3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 /* Defines a GDT entry */
27 unsigned short limit_low
;
28 unsigned short base_low
;
29 unsigned char base_middle
;
31 unsigned char granularity
;
32 unsigned char base_high
;
33 } __attribute__((packed
));
39 } __attribute__((packed
));
41 /* Our GDT, with 3 entries, and finally our special GDT pointer */
42 struct gdt_entry gdt
[3];
45 /* This is in start.asm. We use this to properly reload
46 * the new segment registers */
47 extern void gdt_flush ();
49 /* Setup a descriptor in the Global Descriptor Table */
50 void gdt_set_gate (int num
, unsigned long base
, unsigned long limit
, unsigned char access
, unsigned char gran
)
52 /* Setup the descriptor base address */
53 gdt
[num
].base_low
= (base
& 0xFFFF);
54 gdt
[num
].base_middle
= (base
>> 16) & 0xFF;
55 gdt
[num
].base_high
= (base
>> 24) & 0xFF;
57 /* Setup the descriptor limits */
58 gdt
[num
].limit_low
= (limit
& 0xFFFF);
59 gdt
[num
].granularity
= ((limit
>> 16) & 0x0F);
61 /* Finally, set up the granularity and access flags */
62 gdt
[num
].granularity
|= (gran
& 0xF0);
63 gdt
[num
].access
= access
;
66 /* Should be called by main. This will setup the special GDT
67 * pointer, set up the first 3 entries in our GDT, and then
68 * finally call gdt_flush() in our assembler file in order
69 * to tell the processor where the new GDT is and update the
70 * new segment registers */
71 extern int testf_c (void);
72 unsigned int gdt_install ()
74 /* Setup the GDT pointer and limit */
75 gp
.limit
= (sizeof(struct gdt_entry
) * 3) - 1;
78 /* Our NULL descriptor */
79 gdt_set_gate(0, 0, 0, 0, 0);
81 /* The second entry is our Code Segment. The base address
82 * is 0, the limit is 4GBytes, it uses 4KByte granularity,
83 * uses 32-bit opcodes, and is a Code Segment descriptor.
84 * Please check the table above in the tutorial in order
85 * to see exactly what each value means */
86 gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
88 /* The third entry is our Data Segment. It's EXACTLY the
89 * same as our code segment, but the descriptor type in
90 * this entry's access byte says it's a Data Segment */
91 gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
93 //gdt_set_gate(3, &testf_c, 0xFFFFFFFF, 0x92, 0xCF);
94 //idt_set_gate(0x80, (unsigned) system_call, 15, 3);
96 /* Flush out the old GDT and install the new changes! */