diff --git a/kernel/Makefile b/kernel/Makefile index 2c5e773..42c80c2 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -30,6 +30,7 @@ LIBS:=$(LIBS) $(KERNEL_ARCH_LIBS) KERNEL_OBJS=\ $(KERNEL_ARCH_OBJS) \ kernel/kernel.o \ +gdt/gdt.o OBJS=\ $(ARCHDIR)/crti.o \ diff --git a/kernel/arch/i386/boot.S b/kernel/arch/i386/boot.S index e8eeee1..1cb4354 100644 --- a/kernel/arch/i386/boot.S +++ b/kernel/arch/i386/boot.S @@ -26,6 +26,7 @@ stack_top: _start: movl $stack_top, %esp call _init + call gdt_init call kernel_main cli 1: hlt diff --git a/kernel/gdt/gdt.c b/kernel/gdt/gdt.c new file mode 100644 index 0000000..bf74f6f --- /dev/null +++ b/kernel/gdt/gdt.c @@ -0,0 +1,42 @@ +#include +#include "gdt.h" +#include +struct gdtdesc kgdt[GDTSIZE]; +struct gdtr kgdtr; + + +void read_gdtr(uint32_t* tgdtr) { + asm("sgdt %0" : "=m" (*tgdtr)); +} +void gdt_init(void) { + + create_gdt_descriptor(0x0, 0x0, 0x0, 0x0, &kgdt[0]); + create_gdt_descriptor(0x0, 0xFFFFF, 0x9A, 0x0C, &kgdt[1]); + create_gdt_descriptor(0x0, 0xFFFFF, 0x92, 0x0C, &kgdt[2]); + create_gdt_descriptor(0x0, 0xFFFFF, 0xFA, 0x0C, &kgdt[3]); + create_gdt_descriptor(0x0, 0xFFFFF, 0xF2, 0x0C, &kgdt[4]); +// create_gdt_descriptor(0x0, 0xFFFFF, 0xF2, 0x0D, &kgdt[5]); + //create_gdt_descriptor(0x0, 0x0, 0xF7, 0x0D, &kgdt[6]); + kgdtr.limit = GDTSIZE*8; + kgdtr.base = GDT_BASE; + memcpy((char*) kgdtr.base, (char *) kgdt, kgdtr.limit); + asm("lgdtl (kgdtr)"); + asm("movw $0x10, %ax \n \ + movw %ax, %ds \n \ + movw %ax, %es \n \ + movw %ax, %fs \n \ + movw %ax, %gs \n \ + ljmp $0x08, $next \n \ + next: \n "); +} + +void create_gdt_descriptor(uint32_t base, uint32_t limit, uint8_t access, uint8_t flags, struct gdtdesc *desc) { + desc->limit0_15 = (limit & 0xffff); + desc->base0_15 = (base & 0xffff); + desc->base16_23 = (base & 0xff0000) >> 16; + desc->access_bytes = access; + desc->limit16_19 = (limit & 0xf0000) >> 16; + desc->flags = (flags & 0xf); + desc->base24_31 = (base & 0xff000000) >> 24; + return; +} diff --git a/kernel/gdt/gdt.h b/kernel/gdt/gdt.h new file mode 100644 index 0000000..868c31c --- /dev/null +++ b/kernel/gdt/gdt.h @@ -0,0 +1,37 @@ +#ifndef _GDT_H +#define _GDT_H + +#include +#include + +struct gdtr { + uint16_t limit; + uint32_t base; +} __attribute__ ((packed)); + +struct gdtdesc { + uint16_t limit0_15; + uint16_t base0_15; + uint8_t base16_23; + uint8_t access_bytes; + uint8_t flags:4; + uint8_t limit16_19; + uint8_t base24_31; +} __attribute__ ((packed)); + + +#define GDTSIZE 0xFF +#define GDT_BASE 0x00000 +#define DESC_NULL 0x0000 +#define DESC_KERNEL_CODE 0x0008 +#define DESC_KERNEL_DATA 0x0010 +#define DESC_USER_CODE 0x0018 +#define DESC_USER_DATA 0x0020 + + +void create_gdt_descriptor(uint32_t base, uint32_t limit, uint8_t access, uint8_t flags, struct gdtdesc *); + +void init_gdt(void); + + +#endif