Interrupts
This commit is contained in:
parent
ca42990b55
commit
f89fafe1fa
@ -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
|
||||
|
@ -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!");
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
54
src/kernel/cpu/interrupts.c
Normal file
54
src/kernel/cpu/interrupts.c
Normal 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
27
src/kernel/cpu/isr.S.py
Normal 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}""")
|
45
src/kernel/cpu/isr_common.S
Normal file
45
src/kernel/cpu/isr_common.S
Normal 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
|
6
src/kernel/cpu/registers.S
Normal file
6
src/kernel/cpu/registers.S
Normal file
@ -0,0 +1,6 @@
|
||||
.intel_syntax noprefix
|
||||
|
||||
.global load_idt
|
||||
load_idt:
|
||||
lidt [rdi]
|
||||
ret
|
3
src/kernel/include/cpu.h
Normal file
3
src/kernel/include/cpu.h
Normal file
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void load_idt(void *);
|
32
src/kernel/include/interrupts.h
Normal file
32
src/kernel/include/interrupts.h
Normal 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 *);
|
@ -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
|
@ -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/*
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user