Interrupts

This commit is contained in:
Thomas Lovén 2022-01-04 11:24:55 +01:00
parent ca42990b55
commit f89fafe1fa
11 changed files with 187 additions and 8 deletions

View File

@ -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

View File

@ -3,9 +3,15 @@
#include <vga.h>
#include <debug.h>
#include <multiboot.h>
#include <interrupts.h>
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!");

View File

@ -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;

View File

@ -0,0 +1,54 @@
#include <interrupts.h>
#include <stdint.h>
#include <memory.h>
#include <cpu.h>
#include <debug.h>
#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(;;);
}

27
src/kernel/cpu/isr.S.py Normal file
View File

@ -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}""")

View File

@ -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

View File

@ -0,0 +1,6 @@
.intel_syntax noprefix
.global load_idt
load_idt:
lidt [rdi]
ret

3
src/kernel/include/cpu.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void load_idt(void *);

View File

@ -0,0 +1,32 @@
#pragma once
#include <stdint.h>
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 *);

View File

@ -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

View File

@ -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/*