diff --git a/src/arch/amd64/kernel.S b/src/arch/amd64/kernel.S index 7c83b32..5affc9b 100644 --- a/src/arch/amd64/kernel.S +++ b/src/arch/amd64/kernel.S @@ -62,7 +62,9 @@ _start: call _init /* set the interrupt descriptor */ +#if 0 /* FIXME rework */ call __arch_setidt +#endif /* FIXME setup paging */ diff --git a/src/arch/i386/gdt.S b/src/arch/i386/gdt.S index a346b9e..f4fd9d8 100644 --- a/src/arch/i386/gdt.S +++ b/src/arch/i386/gdt.S @@ -11,7 +11,7 @@ .global __arch_setgdt .type __arch_setgdt, @function __arch_setgdt: -#if 0 +#if 1 lea gdt_descriptor, %ecx #else mov (gdt_descriptor), %ecx diff --git a/src/arch/i386/idt.S b/src/arch/i386/idt.S index b0028f5..0163216 100644 --- a/src/arch/i386/idt.S +++ b/src/arch/i386/idt.S @@ -11,8 +11,16 @@ .global __arch_setidt .type __arch_setidt, @function __arch_setidt: - lea idt, %eax - lidt (%eax) + lea idt, %ecx + /* set the offset of the IDT */ + mov 0x4(%esp), %eax + mov %eax, 0x2(%ecx) + /* set the size of the IDT */ + mov 0x8(%esp), %eax + dec %eax + mov %ax, (%ecx) + /* load the IDT */ + lidt (%ecx) ret @@ -20,5 +28,5 @@ __arch_setidt: .section .bss .align 16 idt: -.short 0x0 /* size */ -.long 0x0 /* offset */ +.skip 2 /* size */ +.skip 4 /* offset */ diff --git a/src/arch/i386/idt.h b/src/arch/i386/idt.h index 3cd658c..56a2ba5 100644 --- a/src/arch/i386/idt.h +++ b/src/arch/i386/idt.h @@ -7,9 +7,20 @@ #ifndef UKERNEL_ARCH_I386_IDT_H # define UKERNEL_ARCH_I386_IDT_H +# include + /* public */ +/* types */ +typedef struct _IDT +{ + uint32_t base; + uint16_t selector; + uint8_t flags; +} IDT; + + /* prototypes */ -int _arch_setidt(void); +int _arch_setidt(IDT const * idt, size_t count); #endif /* !UKERNEL_ARCH_I386_IDT_H */ diff --git a/src/arch/i386/kernel.S b/src/arch/i386/kernel.S index b062826..36f4460 100644 --- a/src/arch/i386/kernel.S +++ b/src/arch/i386/kernel.S @@ -77,9 +77,6 @@ _start: cmp $0x0, %eax jne 2f - /* set the interrupt descriptor */ - call __arch_setidt - /* start the kernel */ push $0x0 push $0x0 @@ -90,11 +87,8 @@ _start: call main add $0x10, %esp jmp 2f + 1: - - /* set the interrupt descriptor */ - call __arch_setidt - /* FIXME setup paging */ /* start the kernel */ diff --git a/src/kernel/idt.c b/src/kernel/idt.c new file mode 100644 index 0000000..6e697ae --- /dev/null +++ b/src/kernel/idt.c @@ -0,0 +1,58 @@ +/* $Id$ */ +/* Copyright (c) 2018 Pierre Pronchery */ +/* This file is part of DeforaOS uKernel */ + + + +#if defined(__amd64__) || defined(__i386__) +# include +# include +# include +# include "arch/i386/idt.h" + + +/* prototypes */ +extern void __arch_setidt(uint8_t * buf, size_t count); + + +/* variables */ +/* FIXME correct the size */ +static uint8_t _buf[65536]; + + +/* functions */ +/* arch_setidt */ +int _arch_setidt(IDT const * idt, size_t count) +{ + uint8_t * buf = _buf; + size_t i; + IDT const * t; + + memset(&_buf, 0, sizeof(_buf)); + /* check for errors */ + if(/* count == 0 ||*/ count > sizeof(_buf) / sizeof(*idt)) + { + errno = ERANGE; + return -1; + } + for(i = 0; i < count; i++) + { + t = &idt[i]; + buf = &_buf[sizeof(t) * i]; + /* encode the address */ + buf[0] = (t->base >> 8) & 0xff; + buf[1] = t->base & 0xff; + buf[6] = (t->base >> 24) & 0xff; + buf[7] = (t->base >> 16) & 0xff; + /* selector */ + buf[2] = (t->selector >> 8) & 0xff; + buf[3] = t->selector & 0xff; + /* padding */ + buf[4] = 0x0; + /* flags */ + buf[5] = t->flags; + } + __arch_setidt(_buf, count); + return 0; +} +#endif diff --git a/src/kernel/multiboot.c b/src/kernel/multiboot.c index 29c61ed..9243024 100644 --- a/src/kernel/multiboot.c +++ b/src/kernel/multiboot.c @@ -8,6 +8,7 @@ # include # include "arch/amd64/gdt.h" # include "arch/i386/gdt.h" +# include "arch/i386/idt.h" # include "drivers/boot/multiboot.h" # include "drivers/bus.h" # include "drivers/clock.h" @@ -30,6 +31,10 @@ static const GDT _gdt_4gb[4] = { 0x00000000, 0x00000000, 0x89 } }; +static const IDT _idt[] = +{ +}; + /* public */ /* functions */ @@ -71,7 +76,7 @@ int multiboot(ukMultibootInfo * mi) (mi->mem_upper - mi->mem_lower) / 1024); printf("Booted from %#x\n", mi->boot_device_drive); - /* load the modules */ + /* setup the GDT */ #if defined(__amd64__) if(_arch_setgdt64(_gdt_4gb, sizeof(_gdt_4gb) / sizeof(*_gdt_4gb)) != 0) #else @@ -82,6 +87,7 @@ int multiboot(ukMultibootInfo * mi) return 2; } + /* load the modules */ if(!(mi->flags & BOOT_MULTIBOOT_INFO_HAS_MODS)) puts("No modules provided"); else @@ -93,6 +99,14 @@ int multiboot(ukMultibootInfo * mi) multiboot_load_module(mod, NULL, NULL); } } + + /* setup the IDT */ + if(_arch_setidt(_idt, sizeof(_idt) / sizeof(*_idt)) != 0) + { + puts("Could not setup the IDT"); + return 2; + } + return 0; } #endif diff --git a/src/kernel/project.conf b/src/kernel/project.conf index 5a9c115..1bc25e4 100644 --- a/src/kernel/project.conf +++ b/src/kernel/project.conf @@ -26,7 +26,7 @@ sources=../common/crtn.S [uKernel.bin] type=binary -sources=arch.S,gdt.c,main.c,multiboot.c,start.S +sources=arch.S,gdt.c,idt.c,main.c,multiboot.c,start.S ldflags=$(OBJDIR)crti.o $(OBJDIR)crtbegin.o $(OBJDIR)../drivers/boot/multiboot.o $(OBJDIR)../drivers/bus.o $(OBJDIR)../drivers/bus/cmos.o $(OBJDIR)../drivers/bus/ioport.o $(OBJDIR)../drivers/clock.o $(OBJDIR)../drivers/clock/cmos.o $(OBJDIR)../drivers/console.o $(OBJDIR)../drivers/console/uart.o $(OBJDIR)../drivers/console/vesa.o $(OBJDIR)../drivers/console/vga.o $(OBJDIR)../drivers/pic.o $(OBJDIR)../drivers/pic/i8259a.o $(OBJDIR)../lib/libuKernel.a $(OBJDIR)crtend.o $(OBJDIR)crtn.o `$(CC) -print-libgcc-file-name` depends=$(OBJDIR)crtbegin.o,$(OBJDIR)crtend.o,$(OBJDIR)crti.o,$(OBJDIR)crtn.o,$(OBJDIR)../drivers/boot/multiboot.o,$(OBJDIR)../drivers/bus.o,$(OBJDIR)../drivers/bus/cmos.o,$(OBJDIR)../drivers/bus/ioport.o,$(OBJDIR)../drivers/clock.o,$(OBJDIR)../drivers/clock/cmos.o,$(OBJDIR)../drivers/console.o,$(OBJDIR)../drivers/console/uart.o,$(OBJDIR)../drivers/console/vesa.o,$(OBJDIR)../drivers/console/vga.o,$(OBJDIR)../drivers/pic.o,$(OBJDIR)../drivers/pic/i8259a.o,$(OBJDIR)../lib/libuKernel.a,../arch/amd64/uKernel.ld,../arch/i386/uKernel.ld