diff --git a/src/kernel/Makefile b/src/kernel/Makefile index 048dc59..1e6a04e 100644 --- a/src/kernel/Makefile +++ b/src/kernel/Makefile @@ -4,8 +4,8 @@ endif CC := ${TARGET}-gcc -SRC := $(wildcard **/*.[cS]) -OBJ := $(patsubst %, %.o, $(basename $(SRC))) +SRC := $(wildcard **/*.[cS]*) +OBJ := $(patsubst %, %.o, $(basename $(basename $(SRC)))) CFLAGS := -Wall -Wextra -pedantic -ffreestanding -mcmodel=large CFLAGS += -ggdb -O0 @@ -16,6 +16,9 @@ LDFLAGS := -n -nostdlib -lgcc -T Link.ld kernel: $(OBJ) $(LINK.c) $^ -o $@ +%.o: %.S.py + python3 $^ | $(COMPILE.S) $(DEPFLAGS) -x assembler-with-cpp - -o $@ + # Automatic dependency tracking DEP := $(OBJ:.o=.d) DEPFLAGS = -MT $@ -MMD -MP -MF $*.d diff --git a/src/kernel/boot/kmain.c b/src/kernel/boot/kmain.c index 22140dd..da4d9f2 100644 --- a/src/kernel/boot/kmain.c +++ b/src/kernel/boot/kmain.c @@ -3,9 +3,15 @@ #include #include #include +#include struct kernel_boot_data_st kernel_boot_data; +int divide(int a, int b) +{ + return a/b; +} + void kmain(uint64_t multiboot_magic, void *multiboot_data) { vga_init(); @@ -22,15 +28,17 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data) size_t index = 0; uintptr_t start, end; uint32_t type; - while(!multiboot_get_memory_ara(index, &start, &end, &type)) + while(!multiboot_get_memory_area(index++, &start, &end, &type)) { debug_info("%d %x-%x\n", type, start, end); - index++; } + interrupt_init(); + debug("Hello, world!"); - int value = 123; - debug_info("dec: %d hex: %x, binary: %b", value, value, value); + + // Force a divide by zero error + divide(5, 0); PANIC("End of kernel function!"); diff --git a/src/kernel/boot/multiboot.c b/src/kernel/boot/multiboot.c index 41a5e2e..348ae0b 100644 --- a/src/kernel/boot/multiboot.c +++ b/src/kernel/boot/multiboot.c @@ -83,7 +83,7 @@ int multiboot_init(uint64_t magic, void *mboot_info) return 0; } -int multiboot_get_memory_ara(size_t index, uintptr_t *start, uintptr_t *end, uint32_t *type) +int multiboot_get_memory_area(size_t index, uintptr_t *start, uintptr_t *end, uint32_t *type) { if(index >= kernel_boot_data.mmap_len) return 1; diff --git a/src/kernel/cpu/interrupts.c b/src/kernel/cpu/interrupts.c new file mode 100644 index 0000000..a006bf5 --- /dev/null +++ b/src/kernel/cpu/interrupts.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include + +#define IDT_INTERRUPT 0xE +#define IDT_DPL0 0x0 +#define IDT_PRESENT 0x80 + +#define NUM_INTERRUPTS 256 + +struct idt { + uint16_t base_l; + uint16_t cs; + uint8_t ist; + uint8_t flags; + uint16_t base_m; + uint32_t base_h; + uint32_t _; +}__attribute__((packed)) idt[NUM_INTERRUPTS]; + +struct { + uint16_t len; + struct idt *addr; +}__attribute__((packed)) idtr; + +extern uintptr_t isr_table[]; + +void interrupt_init() +{ + memset(idt, 0, sizeof(idt)); + for(int i=0; i < NUM_INTERRUPTS; i++) + { + idt[i].base_l = isr_table[i] & 0xFFFF; + idt[i].base_m = (isr_table[i] >> 16) & 0xFFFF; + idt[i].base_h = (isr_table[i] >> 32) & 0xFFFFFFFF; + idt[i].cs = 0x8; + idt[i].ist = 0; + idt[i].flags = IDT_PRESENT | IDT_DPL0 | IDT_INTERRUPT; + } + + idtr.addr = idt; + idtr.len = sizeof(idt)-1; + load_idt(&idtr); +} + +registers *int_handler(registers *r) +{ + debug_error("Unhandled interrupt occurred\n"); + debug_error("Interrupt number: %d, Error code: %d\n", r->int_no, r->err_code); + PANIC("Unhandled interrupt"); + for(;;); +} \ No newline at end of file diff --git a/src/kernel/cpu/isr.S.py b/src/kernel/cpu/isr.S.py new file mode 100644 index 0000000..0d772c0 --- /dev/null +++ b/src/kernel/cpu/isr.S.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python + +num_isr = 256 +pushes_error = [8, 10, 11, 12, 13, 14, 17] + +print(""" +.intel_syntax noprefix +.extern isr_common +""") + +print("// Interrupt Service Routines") +for i in range(num_isr): + print(f"""isr{i}: + cli + {"push 0" if i in pushes_error else "nop"} + push {i} + jmp isr_common""") + +print("") +print("// Vector table") + +print(""" +.section .data +.global isr_table +isr_table:""") +for i in range(num_isr): + print(f""".quad isr{i}""") \ No newline at end of file diff --git a/src/kernel/cpu/isr_common.S b/src/kernel/cpu/isr_common.S new file mode 100644 index 0000000..598de89 --- /dev/null +++ b/src/kernel/cpu/isr_common.S @@ -0,0 +1,45 @@ +.intel_syntax noprefix + +.extern int_handler +.global isr_common +.global isr_return + +isr_common: + push r15 + push r14 + push r13 + push r12 + push r11 + push r10 + push r9 + push r8 + push rbp + push rdi + push rsi + push rdx + push rcx + push rbx + push rax + mov rdi, rsp + call int_handler + + mov rdi, rax +isr_return: + mov rsp, rdi + pop rax + pop rbx + pop rcx + pop rdx + pop rsi + pop rdi + pop rbp + pop r8 + pop r9 + pop r10 + pop r11 + pop r12 + pop r13 + pop r14 + pop r15 + add rsp, 0x10 + iretq \ No newline at end of file diff --git a/src/kernel/cpu/registers.S b/src/kernel/cpu/registers.S new file mode 100644 index 0000000..e97c8b4 --- /dev/null +++ b/src/kernel/cpu/registers.S @@ -0,0 +1,6 @@ +.intel_syntax noprefix + +.global load_idt +load_idt: + lidt [rdi] + ret \ No newline at end of file diff --git a/src/kernel/include/cpu.h b/src/kernel/include/cpu.h new file mode 100644 index 0000000..aa4f679 --- /dev/null +++ b/src/kernel/include/cpu.h @@ -0,0 +1,3 @@ +#pragma once + +void load_idt(void *); \ No newline at end of file diff --git a/src/kernel/include/interrupts.h b/src/kernel/include/interrupts.h new file mode 100644 index 0000000..0e8230c --- /dev/null +++ b/src/kernel/include/interrupts.h @@ -0,0 +1,32 @@ +#pragma once +#include + +typedef struct { + uint64_t rax; + uint64_t rbx; + uint64_t rcx; + uint64_t rdx; + uint64_t rsi; + uint64_t rdi; + uint64_t rbp; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + + uint64_t int_no; + uint64_t err_code; + + uint64_t rip; + uint64_t cs; + uint64_t rflags; + uint64_t rsp; + uint64_t ss; +} registers; + +void interrupt_init(); +void isr_return(registers *); \ No newline at end of file diff --git a/src/kernel/include/multiboot.h b/src/kernel/include/multiboot.h index 00f2a96..76c425b 100644 --- a/src/kernel/include/multiboot.h +++ b/src/kernel/include/multiboot.h @@ -25,5 +25,5 @@ struct kernel_boot_data_st{ extern struct kernel_boot_data_st kernel_boot_data; int multiboot_init(uint64_t magic, void *mboot_info); -int multiboot_get_memory_ara(size_t index, uintptr_t *start, uintptr_t *end, uint32_t *type); +int multiboot_get_memory_area(size_t index, uintptr_t *start, uintptr_t *end, uint32_t *type); #endif \ No newline at end of file diff --git a/toolchain/build-toolchain.sh b/toolchain/build-toolchain.sh index 78d10c2..2481f9e 100755 --- a/toolchain/build-toolchain.sh +++ b/toolchain/build-toolchain.sh @@ -5,6 +5,7 @@ apk add gmp-dev mpfr-dev mpc1-dev apk add make apk add grub-bios xorriso +apk add python3 rm -rf /var/cache/apk/*