3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 /* Defines a GDT entry */
28 unsigned short limit_low
;
29 unsigned short base_low
;
30 unsigned char base_middle
;
32 unsigned char granularity
;
33 unsigned char base_high
;
34 } __attribute__((packed
));
40 } __attribute__((packed
));
42 /* Our GDT, with 3 entries, and finally our special GDT pointer */
43 struct gdt_entry gdt
[3];
46 /* This is in start.asm. We use this to properly reload
47 * the new segment registers */
48 extern void gdt_flush ();
50 /* Setup a descriptor in the Global Descriptor Table */
51 void gdt_set_gate (int num
, unsigned long base
, unsigned long limit
, unsigned char access
, unsigned char gran
)
53 /* Setup the descriptor base address */
54 gdt
[num
].base_low
= (base
& 0xFFFF);
55 gdt
[num
].base_middle
= (base
>> 16) & 0xFF;
56 gdt
[num
].base_high
= (base
>> 24) & 0xFF;
58 /* Setup the descriptor limits */
59 gdt
[num
].limit_low
= (limit
& 0xFFFF);
60 gdt
[num
].granularity
= ((limit
>> 16) & 0x0F);
62 /* Finally, set up the granularity and access flags */
63 gdt
[num
].granularity
|= (gran
& 0xF0);
64 gdt
[num
].access
= access
;
67 /* Should be called by main. This will setup the special GDT
68 * pointer, set up the first 3 entries in our GDT, and then
69 * finally call gdt_flush() in our assembler file in order
70 * to tell the processor where the new GDT is and update the
71 * new segment registers */
72 unsigned int gdt_install ()
74 /* Setup the GDT pointer and limit */
75 gp
.limit
= (sizeof(struct gdt_entry
) * 3) - 1;
76 gp
.base
= (unsigned int) &gdt
;
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 /* Flush out the old GDT and install the new changes! */