stdlibc: ~several fixes
[meinos.git] / kernel2 / gdt.c
blob823d3c651d2e3511cbb49646e3ac0a5ad6895465
1 /*
2 meinOS - A unix-like x86 microkernel operating system
3 Copyright (C) 2008 Janosch Gräf <janosch.graef@gmx.net>
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/>.
19 #include <gdt.h>
20 #include <malloc.h>
21 #include <string.h>
22 #include <debug.h>
24 void gdt_reloadsregs() {
25 /*const selector_t csel = {
26 .index = 1,
27 .ti = 0,
28 .priv = PRIV_KERNEL
29 };*/
30 const selector_t dsel = {
31 .index = 2,
32 .ti = 0,
33 .priv = PRIV_KERNEL
35 /*asm("mov %0,%%ds;"
36 "ljmp %1,$gdt_reloadregs_fi;"
37 "gdt_reloadregs_fi:"
38 ::"r"((uint16_t)16),"i"((uint16_t)8));*/
40 asm("ljmpl $0x08, $1f;"
41 "1:"
42 "mov %0, %%ds;"
43 "mov %0, %%es;"
44 "mov %0, %%fs;"
45 "mov %0, %%gs;"
46 "mov %0, %%ss;"
47 ::"r"(dsel):"eax");
48 return;
51 /**
52 * Initializes GDT
53 * @return 0=Success; -1=Failure
55 int gdt_init() {
56 //gdt = calloc(GDT_MAXDESC,sizeof(gdtdesc_t));
57 memset(gdt,0,GDT_MAXDESC*sizeof(gdtdesc_t));
59 // Ring 0
60 gdt_set_descriptor(1,0x000FFFFF,0x00000000,GDT_SEGMENT|GDT_PRESENT|GDT_CODESEG,PRIV_KERNEL);
61 gdt_set_descriptor(2,0x000FFFFF,0x00000000,GDT_SEGMENT|GDT_PRESENT|GDT_DATASEG,PRIV_KERNEL);
63 // Ring 3
64 gdt_set_descriptor(3,0x000FFFFF,0x00000000,GDT_SEGMENT|GDT_PRESENT|GDT_CODESEG,PRIV_USER);
65 gdt_set_descriptor(4,0x000FFFFF,0x00000000,GDT_SEGMENT|GDT_PRESENT|GDT_DATASEG,PRIV_USER);
67 gdtsel_t selector = {
68 .size = GDT_MAXDESC*sizeof(gdtdesc_t)-1,
69 .offset = (uint32_t)&gdt
71 asm("lgdt (%0)"::"r"(&selector));
72 gdt_reloadsregs();
74 return 0;
77 void gdt_set_descriptor(int segment,size_t size,void *vdbase,int access,priv_t priv) {
78 uint32_t base = (uint32_t)vdbase;
79 gdt[segment].size0_15 = size&0xFFFF;
80 gdt[segment].flags = ((size>>16)&0x0F)|0xC0;
81 gdt[segment].base0_15 = base&0xFFFF;
82 gdt[segment].base16_23 = (base>>16)&0xFF;
83 gdt[segment].base24_31 = ((base>>24)&0xFF);
84 gdt[segment].access = access|((priv&3)<<5);