aboutsummaryrefslogtreecommitdiff
path: root/arch/i686/lgdt.c
blob: 2d35e8d3acaf751800fd3dc5b0139d8f5ef5e111 (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
#include <gdt.h>

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

  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));
}