Nothing
[ZeXOS.git] / kernel / gdt.c
blob07ae4d578a728740adaa5a9e5f2a1bb354aef262
1 /*
2 * ZeX/OS
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/>.
20 #include <system.h>
21 #include <x86.h>
22 #include <string.h>
24 /* Defines a GDT entry */
25 struct gdt_entry
27 unsigned short limit_low;
28 unsigned short base_low;
29 unsigned char base_middle;
30 unsigned char access;
31 unsigned char granularity;
32 unsigned char base_high;
33 } __attribute__((packed));
35 struct gdt_ptr
37 unsigned short limit;
38 unsigned int base;
39 } __attribute__((packed));
41 /* Our GDT, with 3 entries, and finally our special GDT pointer */
42 struct gdt_entry gdt[3];
43 struct gdt_ptr gp;
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;
76 gp.base = &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 //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! */
97 gdt_flush();
99 return 1;