1 | #include "gdt.h"
|
2 |
|
3 | typedef unsigned long uint64_t;
|
4 | typedef unsigned short uint16_t;
|
5 |
|
6 | #define GDT_ENTRIES 5
|
7 |
|
8 | #define GDT_FLAG_DATASEG 0x02
|
9 | #define GDT_FLAG_CODESEG 0x0a
|
10 | #define GDT_FLAG_TSS 0x09
|
11 |
|
12 | #define GDT_FLAG_SEGMENT 0x10
|
13 | #define GDT_FLAG_RING0 0x00
|
14 | #define GDT_FLAG_RING3 0x60
|
15 | #define GDT_FLAG_PRESENT 0x80
|
16 |
|
17 | #define GDT_FLAG_4K_GRAN 0x800
|
18 | #define GDT_FLAG_32_BIT 0x400
|
19 |
|
20 | uint64_t gdt[GDT_ENTRIES];
|
21 |
|
22 | void set_gdt_entry(int i, unsigned int base, unsigned int limit, int flags)
|
23 | {
|
24 | gdt[i] = limit & 0xffffLL;
|
25 | gdt[i] |= (base & 0xffffffLL) << 16;
|
26 | gdt[i] |= (flags & 0xffLL) << 40;
|
27 | gdt[i] |= ((limit >> 16) & 0xfLL) << 48;
|
28 | gdt[i] |= ((flags >> 8 )& 0xffLL) << 52;
|
29 | gdt[i] |= ((base >> 24) & 0xffLL) << 56;
|
30 | }
|
31 |
|
32 | void init_gdt()
|
33 | {
|
34 | set_gdt_entry(0, 0, 0, 0);
|
35 | set_gdt_entry(1, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT |
|
36 | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
|
37 | set_gdt_entry(2, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT |
|
38 | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT);
|
39 | set_gdt_entry(3, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT |
|
40 | GDT_FLAG_CODESEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
|
41 | set_gdt_entry(4, 0, 0xfffff, GDT_FLAG_SEGMENT | GDT_FLAG_32_BIT |
|
42 | GDT_FLAG_DATASEG | GDT_FLAG_4K_GRAN | GDT_FLAG_PRESENT | GDT_FLAG_RING3);
|
43 | }
|
44 |
|
45 | struct
|
46 | {
|
47 | uint16_t limit;
|
48 | unsigned int pointer;
|
49 | } __attribute__((packed)) gdtp =
|
50 | {
|
51 | .limit = GDT_ENTRIES * 12 - 1, //vorher *8
|
52 | .pointer = &gdt,
|
53 | };
|
54 |
|
55 | void install_gdt()
|
56 | {
|
57 | init_gdt();
|
58 |
|
59 | asm volatile("lgdt %0" : : "m" (gdtp));
|
60 | loadseg();
|
61 | }
|