Cleanup in elf.c with .bss section clean; adm command mounts cdrom instead of floppy...
[ZeXOS.git] / kernel / arch / i386 / gdt.c
blobaf58f7cccac8927b29ad4dea935d5c101854fb87
1 /*
2 * ZeX/OS
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/>.
21 #include <system.h>
22 #include <arch/io.h>
23 #include <string.h>
25 /* Defines a GDT entry */
26 struct gdt_entry
28 unsigned short limit_low;
29 unsigned short base_low;
30 unsigned char base_middle;
31 unsigned char access;
32 unsigned char granularity;
33 unsigned char base_high;
34 } __attribute__((packed));
36 struct gdt_ptr
38 unsigned short limit;
39 unsigned int base;
40 } __attribute__((packed));
42 /* Our GDT, with 3 entries, and finally our special GDT pointer */
43 struct gdt_entry gdt[3];
44 struct gdt_ptr gp;
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! */
94 gdt_flush();
96 return 1;