aboutsummaryrefslogtreecommitdiff
path: root/i686/lgdt.c
blob: 10781db9fa23fe86809a77a398ebd648fb42652c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "gdt.h"

struct __attribute__((packed)) Pointer {
  uint16_t limit;
  uint32_t base;
};

static struct SegmentDescriptor_t segments[8] __attribute__((aligned(32)));

void
gdt_install()
{
  SegmentDescriptor(&segments[0], 0, 0, 0);                     // null segment
  SegmentDescriptor(&segments[2], 0, 0xffffffff, 0x9a);         // ktext
  SegmentDescriptor(&segments[3], 0, 0xffffffff, 0x92);         // kdata

  const struct Pointer ptr = {.limit = sizeof(segments) - 1, .base = (unsigned)&segments};
  asm volatile("lgdt (%0)" : : "a"(&ptr));

  // load the kernel data segment
  asm volatile(R"(mov %0, %%ds
  mov %0, %%es
  mov %0, %%fs
  mov %0, %%gs
  mov %0, %%ss
)"
               :
               : "ax"(kdataDescriptor));

  // load the kernel code segment
  asm volatile(R"(ljmp %0, $1f
  1:)"
               :
               : "i"(ktextDescriptor));
}