Set the IDT more like the GDT

This makes its initialization easier.
This commit is contained in:
Pierre Pronchery 2018-07-15 05:46:34 +02:00
parent 655e39736c
commit b5e6e07701
8 changed files with 102 additions and 15 deletions

View File

@ -62,7 +62,9 @@ _start:
call _init call _init
/* set the interrupt descriptor */ /* set the interrupt descriptor */
#if 0 /* FIXME rework */
call __arch_setidt call __arch_setidt
#endif
/* FIXME setup paging */ /* FIXME setup paging */

View File

@ -11,7 +11,7 @@
.global __arch_setgdt .global __arch_setgdt
.type __arch_setgdt, @function .type __arch_setgdt, @function
__arch_setgdt: __arch_setgdt:
#if 0 #if 1
lea gdt_descriptor, %ecx lea gdt_descriptor, %ecx
#else #else
mov (gdt_descriptor), %ecx mov (gdt_descriptor), %ecx

View File

@ -11,8 +11,16 @@
.global __arch_setidt .global __arch_setidt
.type __arch_setidt, @function .type __arch_setidt, @function
__arch_setidt: __arch_setidt:
lea idt, %eax lea idt, %ecx
lidt (%eax) /* 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 ret
@ -20,5 +28,5 @@ __arch_setidt:
.section .bss .section .bss
.align 16 .align 16
idt: idt:
.short 0x0 /* size */ .skip 2 /* size */
.long 0x0 /* offset */ .skip 4 /* offset */

View File

@ -7,9 +7,20 @@
#ifndef UKERNEL_ARCH_I386_IDT_H #ifndef UKERNEL_ARCH_I386_IDT_H
# define UKERNEL_ARCH_I386_IDT_H # define UKERNEL_ARCH_I386_IDT_H
# include <stdint.h>
/* public */ /* public */
/* types */
typedef struct _IDT
{
uint32_t base;
uint16_t selector;
uint8_t flags;
} IDT;
/* prototypes */ /* prototypes */
int _arch_setidt(void); int _arch_setidt(IDT const * idt, size_t count);
#endif /* !UKERNEL_ARCH_I386_IDT_H */ #endif /* !UKERNEL_ARCH_I386_IDT_H */

View File

@ -77,9 +77,6 @@ _start:
cmp $0x0, %eax cmp $0x0, %eax
jne 2f jne 2f
/* set the interrupt descriptor */
call __arch_setidt
/* start the kernel */ /* start the kernel */
push $0x0 push $0x0
push $0x0 push $0x0
@ -90,11 +87,8 @@ _start:
call main call main
add $0x10, %esp add $0x10, %esp
jmp 2f jmp 2f
1: 1:
/* set the interrupt descriptor */
call __arch_setidt
/* FIXME setup paging */ /* FIXME setup paging */
/* start the kernel */ /* start the kernel */

58
src/kernel/idt.c Normal file
View File

@ -0,0 +1,58 @@
/* $Id$ */
/* Copyright (c) 2018 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS uKernel */
#if defined(__amd64__) || defined(__i386__)
# include <stdint.h>
# include <string.h>
# include <errno.h>
# 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

View File

@ -8,6 +8,7 @@
# include <stdio.h> # include <stdio.h>
# include "arch/amd64/gdt.h" # include "arch/amd64/gdt.h"
# include "arch/i386/gdt.h" # include "arch/i386/gdt.h"
# include "arch/i386/idt.h"
# include "drivers/boot/multiboot.h" # include "drivers/boot/multiboot.h"
# include "drivers/bus.h" # include "drivers/bus.h"
# include "drivers/clock.h" # include "drivers/clock.h"
@ -30,6 +31,10 @@ static const GDT _gdt_4gb[4] =
{ 0x00000000, 0x00000000, 0x89 } { 0x00000000, 0x00000000, 0x89 }
}; };
static const IDT _idt[] =
{
};
/* public */ /* public */
/* functions */ /* functions */
@ -71,7 +76,7 @@ int multiboot(ukMultibootInfo * mi)
(mi->mem_upper - mi->mem_lower) / 1024); (mi->mem_upper - mi->mem_lower) / 1024);
printf("Booted from %#x\n", mi->boot_device_drive); printf("Booted from %#x\n", mi->boot_device_drive);
/* load the modules */ /* setup the GDT */
#if defined(__amd64__) #if defined(__amd64__)
if(_arch_setgdt64(_gdt_4gb, sizeof(_gdt_4gb) / sizeof(*_gdt_4gb)) != 0) if(_arch_setgdt64(_gdt_4gb, sizeof(_gdt_4gb) / sizeof(*_gdt_4gb)) != 0)
#else #else
@ -82,6 +87,7 @@ int multiboot(ukMultibootInfo * mi)
return 2; return 2;
} }
/* load the modules */
if(!(mi->flags & BOOT_MULTIBOOT_INFO_HAS_MODS)) if(!(mi->flags & BOOT_MULTIBOOT_INFO_HAS_MODS))
puts("No modules provided"); puts("No modules provided");
else else
@ -93,6 +99,14 @@ int multiboot(ukMultibootInfo * mi)
multiboot_load_module(mod, NULL, NULL); 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; return 0;
} }
#endif #endif

View File

@ -26,7 +26,7 @@ sources=../common/crtn.S
[uKernel.bin] [uKernel.bin]
type=binary 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` 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 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