commit 0e9bb980e2cbcc7642f51430edb9ac863961c3e4
parent aab5207bbd3c17a735529e96624e47eedfee596f
Author: Stefan <misc@stefan-koch.name>
Date: Fri, 23 Oct 2015 23:22:20 +0200
added IDT with halting interrupt handler
Diffstat:
5 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
@@ -8,9 +8,11 @@ all: image kernel kernel-install
kernel:
$(ASM) arch/x86/boot.asm -o arch/x86/boot.o -f elf
$(ASM) arch/x86/gdt.asm -o arch/x86/gdt_asm.o -f elf
+ $(ASM) arch/x86/idt.asm -o arch/x86/idt_asm.o -f elf
$(GCC) -c kernel.c -o kernel.o $(GCCFLAGS)
$(GCC) -c arch/x86/gdt.c -o arch/x86/gdt.o $(GCCFLAGS)
- $(GCC) -T kernel.ld -o sos-kernel.img -ffreestanding -O2 -nostdlib arch/x86/boot.o kernel.o arch/x86/gdt_asm.o arch/x86/gdt.o -lgcc
+ $(GCC) -c arch/x86/idt.c -o arch/x86/idt.o $(GCCFLAGS)
+ $(GCC) -T kernel.ld -o sos-kernel.img -ffreestanding -O2 -nostdlib arch/x86/boot.o kernel.o arch/x86/gdt_asm.o arch/x86/gdt.o arch/x86/idt.o arch/x86/idt_asm.o -lgcc
kernel-install:
sudo losetup /dev/loop1 sos.img -o 1048576
diff --git a/arch/x86/idt.asm b/arch/x86/idt.asm
@@ -0,0 +1,7 @@
+section .text
+global int_handler
+int_handler:
+ mov ax, 0x10
+ mov gs, ax
+ mov dword [gs:0xB8000],') : '
+ hlt
diff --git a/arch/x86/idt.c b/arch/x86/idt.c
@@ -0,0 +1,28 @@
+#include <stdint.h>
+#include "idt.h"
+
+void idt_set_entry(unsigned int pos, uint32_t base,
+ uint16_t selector, uint8_t type_attributes)
+{
+ idt[pos].base_lower = base & 0xffff;
+ idt[pos].selector = selector;
+ idt[pos].unused = 0x0;
+ idt[pos].type_attributes = type_attributes;
+ idt[pos].base_higher = (base >> 16) & 0xffff;
+}
+
+extern void int_handler();
+void idt_setup()
+{
+ idt_desc.limit = IDT_ENTRIES * sizeof(struct idt_entry) - 1;
+ idt_desc.base = (uint32_t) (uintptr_t) idt;
+
+ // TODO: set some entries
+ for (int i = 0; i < IDT_ENTRIES; i++) {
+ idt_set_entry(i, (uint32_t)(uintptr_t)&int_handler,
+ 0x8, 0x8e);
+ }
+
+
+ asm volatile("lidt (%0)" :: "m"(idt_desc));
+}
diff --git a/arch/x86/idt.h b/arch/x86/idt.h
@@ -0,0 +1,26 @@
+#ifndef IDT_H
+#define IDT_H
+
+#include <stdint.h>
+
+#define IDT_ENTRIES 256
+
+struct idt_entry {
+ uint16_t base_lower;
+ uint16_t selector;
+ uint8_t unused;
+ uint8_t type_attributes;
+ uint16_t base_higher;
+} __attribute__((packed));
+
+struct idt_description {
+ uint16_t limit;
+ uint32_t base;
+} __attribute__((packed));
+
+struct idt_description idt_desc;
+struct idt_entry idt[IDT_ENTRIES];
+
+void idt_setup();
+
+#endif
diff --git a/kernel.c b/kernel.c
@@ -1,8 +1,10 @@
+#include "arch/x86/idt.h"
#include "arch/x86/gdt.h"
void kernel_main()
{
gdt_setup();
+ idt_setup();
char *vidmem = (char*) 0xb8000;
vidmem[0] = 'H';