gdt.c


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
}