-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgdt.c
250 lines (197 loc) · 6.79 KB
/
gdt.c
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
/* Basically, we are going to use this as a GDT entry to section of memory and permissions/access
Interesting resources about what is going on here:
http://linuxgazette.net/82/raghu.html
http://wiki.osdev.org/GDT_Tutorial
http://www.jamesmolloy.co.uk/tutorial_html/4.-The%20GDT%20and%20IDT.html
*/
static void idt_install();
static void gdt_install();
static void idt_set_gate(unsigned char,unsigned long,unsigned int,unsigned char);
static void gdt_set_gate(int num, unsigned long, unsigned long, unsigned char, unsigned char);
struct gdt_entry
{
unsigned short limit_low;
unsigned short base_low;
unsigned char base_middle;
unsigned char access;
unsigned char granularity;
unsigned char base_high;
} __attribute__((packed));
struct gdt_ptr
{
unsigned short limit;
unsigned int base;
} __attribute__((packed));
void init_tables()
{
gdt_install();
idt_install();
}
/* Mix of code from Bran's tutorial and JamesM's. */
struct gdt_entry gdt_entries[5];
struct gdt_ptr gp;
static void gdt_set_gate(int num, unsigned long base, unsigned long limit, unsigned char access, unsigned char gran)
{
/* Setup the descriptor base address */
gdt_entries[num].base_low = (base & 0xFFFF);
gdt_entries[num].base_middle = (base >> 16) & 0xFF;
gdt_entries[num].base_high = (base >> 24) & 0xFF;
/* Setup the descriptor limits */
gdt_entries[num].limit_low = (limit & 0xFFFF);
gdt_entries[num].granularity = ((limit >> 16) & 0x0F);
/* Finally, set up the granularity and access flags */
gdt_entries[num].granularity |= (gran & 0xF0);
gdt_entries[num].access = access;
}
static void gdt_install()
{
/* Setup the GDT pointer and limit
*/
gp.limit = (sizeof(struct gdt_entry) * 5) - 1;
gp.base = &gdt_entries;
gdt_set_gate(0, 0, 0, 0, 0); // Null segment
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment
gdt_flush();
}
struct idt_entry
{
unsigned short base_lo;
unsigned short sel;
unsigned char always0;
unsigned char flags;
unsigned short base_hi;
} __attribute__((packed));
struct idt_ptr
{
unsigned short limit;
unsigned int base;
} __attribute__((packed));
struct idt_entry idt_entries[256];
struct idt_ptr id;
extern void isr0 ();
extern void isr1 ();
extern void isr2 ();
extern void isr3 ();
extern void isr4 ();
extern void isr5 ();
extern void isr6 ();
extern void isr7 ();
extern void isr8 ();
extern void isr9 ();
extern void isr10();
extern void isr11();
extern void isr12();
extern void isr13();
extern void isr14();
extern void isr15();
extern void isr16();
extern void isr17();
extern void isr18();
extern void isr19();
extern void isr20();
extern void isr21();
extern void isr22();
extern void isr23();
extern void isr24();
extern void isr25();
extern void isr26();
extern void isr27();
extern void isr28();
extern void isr29();
extern void isr30();
extern void isr31();
extern void irq0 ();
extern void irq1 ();
extern void irq2 ();
extern void irq3 ();
extern void irq4 ();
extern void irq5 ();
extern void irq6 ();
extern void irq7 ();
extern void irq8 ();
extern void irq9 ();
extern void irq10();
extern void irq11();
extern void irq12();
extern void irq13();
extern void irq14();
extern void irq15();
static void idt_set_gate(unsigned char num, unsigned long base, unsigned int sel, unsigned char flags)
{
idt_entries[num].base_lo = base & 0xFFFF;
idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
idt_entries[num].sel = sel;
idt_entries[num].always0 = 0;
idt_entries[num].flags = flags;
}
static void idt_install()
{
id.limit = sizeof(struct idt_entry) * 256 -1;
id.base = &idt_entries;
memset(&idt_entries, 0, sizeof(struct idt_entry)*256);
/* Re-map out interrupts */
outportb(0x20, 0x11);
outportb(0xA0, 0x11);
outportb(0x21, 0x20);
outportb(0xA1, 0x28);
outportb(0x21, 0x04);
outportb(0xA1, 0x02);
outportb(0x21, 0x01);
outportb(0xA1, 0x01);
outportb(0x21, 0x0);
outportb(0xA1, 0x0);
idt_set_gate( 0, (unsigned long)isr0 , 0x08, 0x8E);
idt_set_gate( 1, (unsigned long)isr1 , 0x08, 0x8E);
idt_set_gate( 2, (unsigned long)isr2 , 0x08, 0x8E);
idt_set_gate( 3, (unsigned long)isr3 , 0x08, 0x8E);
idt_set_gate( 4, (unsigned long)isr4 , 0x08, 0x8E);
idt_set_gate( 5, (unsigned long)isr5 , 0x08, 0x8E);
idt_set_gate( 6, (unsigned long)isr6 , 0x08, 0x8E);
idt_set_gate( 7, (unsigned long)isr7 , 0x08, 0x8E);
idt_set_gate( 8, (unsigned long)isr8 , 0x08, 0x8E);
idt_set_gate( 9, (unsigned long)isr9 , 0x08, 0x8E);
idt_set_gate( 10, (unsigned long)isr10 , 0x08, 0x8E);
idt_set_gate( 11, (unsigned long)isr11 , 0x08, 0x8E);
idt_set_gate( 12, (unsigned long)isr12 , 0x08, 0x8E);
idt_set_gate( 13, (unsigned long)isr13 , 0x08, 0x8E);
idt_set_gate( 14, (unsigned long)isr14 , 0x08, 0x8E);
idt_set_gate( 15, (unsigned long)isr15 , 0x08, 0x8E);
idt_set_gate( 16, (unsigned long)isr16 , 0x08, 0x8E);
idt_set_gate( 17, (unsigned long)isr17 , 0x08, 0x8E);
idt_set_gate( 18, (unsigned long)isr18 , 0x08, 0x8E);
idt_set_gate( 19, (unsigned long)isr19 , 0x08, 0x8E);
idt_set_gate( 20, (unsigned long)isr20 , 0x08, 0x8E);
idt_set_gate( 21, (unsigned long)isr21 , 0x08, 0x8E);
idt_set_gate( 22, (unsigned long)isr22 , 0x08, 0x8E);
idt_set_gate( 23, (unsigned long)isr23 , 0x08, 0x8E);
idt_set_gate( 24, (unsigned long)isr24 , 0x08, 0x8E);
idt_set_gate( 25, (unsigned long)isr25 , 0x08, 0x8E);
idt_set_gate( 26, (unsigned long)isr26 , 0x08, 0x8E);
idt_set_gate( 27, (unsigned long)isr27 , 0x08, 0x8E);
idt_set_gate( 28, (unsigned long)isr28 , 0x08, 0x8E);
idt_set_gate( 29, (unsigned long)isr29 , 0x08, 0x8E);
idt_set_gate( 30, (unsigned long)isr30 , 0x08, 0x8E);
idt_set_gate( 31, (unsigned long)isr31 , 0x08, 0x8E);
/* Set up software interrupts */
idt_set_gate( 32, (unsigned long)irq0 , 0x08, 0x8E);
idt_set_gate( 33, (unsigned long)irq1 , 0x08, 0x8E);
idt_set_gate( 34, (unsigned long)irq2 , 0x08, 0x8E);
idt_set_gate( 35, (unsigned long)irq3 , 0x08, 0x8E);
idt_set_gate( 36, (unsigned long)irq4 , 0x08, 0x8E);
idt_set_gate( 37, (unsigned long)irq5 , 0x08, 0x8E);
idt_set_gate( 38, (unsigned long)irq6 , 0x08, 0x8E);
idt_set_gate( 39, (unsigned long)irq7 , 0x08, 0x8E);
idt_set_gate( 40, (unsigned long)irq8 , 0x08, 0x8E);
idt_set_gate( 41, (unsigned long)irq9 , 0x08, 0x8E);
idt_set_gate( 42, (unsigned long)irq10 , 0x08, 0x8E);
idt_set_gate( 43, (unsigned long)irq11 , 0x08, 0x8E);
idt_set_gate( 44, (unsigned long)irq12 , 0x08, 0x8E);
idt_set_gate( 45, (unsigned long)irq13 , 0x08, 0x8E);
idt_set_gate( 46, (unsigned long)irq14 , 0x08, 0x8E);
idt_set_gate( 47, (unsigned long)irq15 , 0x08, 0x8E);
idt_flush();
}
extern void idt_flush();