Interrupts
This commit is contained in:
parent
ca42990b55
commit
f89fafe1fa
@ -4,8 +4,8 @@ endif
|
|||||||
|
|
||||||
CC := ${TARGET}-gcc
|
CC := ${TARGET}-gcc
|
||||||
|
|
||||||
SRC := $(wildcard **/*.[cS])
|
SRC := $(wildcard **/*.[cS]*)
|
||||||
OBJ := $(patsubst %, %.o, $(basename $(SRC)))
|
OBJ := $(patsubst %, %.o, $(basename $(basename $(SRC))))
|
||||||
|
|
||||||
CFLAGS := -Wall -Wextra -pedantic -ffreestanding -mcmodel=large
|
CFLAGS := -Wall -Wextra -pedantic -ffreestanding -mcmodel=large
|
||||||
CFLAGS += -ggdb -O0
|
CFLAGS += -ggdb -O0
|
||||||
@ -16,6 +16,9 @@ LDFLAGS := -n -nostdlib -lgcc -T Link.ld
|
|||||||
kernel: $(OBJ)
|
kernel: $(OBJ)
|
||||||
$(LINK.c) $^ -o $@
|
$(LINK.c) $^ -o $@
|
||||||
|
|
||||||
|
%.o: %.S.py
|
||||||
|
python3 $^ | $(COMPILE.S) $(DEPFLAGS) -x assembler-with-cpp - -o $@
|
||||||
|
|
||||||
# Automatic dependency tracking
|
# Automatic dependency tracking
|
||||||
DEP := $(OBJ:.o=.d)
|
DEP := $(OBJ:.o=.d)
|
||||||
DEPFLAGS = -MT $@ -MMD -MP -MF $*.d
|
DEPFLAGS = -MT $@ -MMD -MP -MF $*.d
|
||||||
|
@ -3,9 +3,15 @@
|
|||||||
#include <vga.h>
|
#include <vga.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <multiboot.h>
|
#include <multiboot.h>
|
||||||
|
#include <interrupts.h>
|
||||||
|
|
||||||
struct kernel_boot_data_st kernel_boot_data;
|
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)
|
void kmain(uint64_t multiboot_magic, void *multiboot_data)
|
||||||
{
|
{
|
||||||
vga_init();
|
vga_init();
|
||||||
@ -22,15 +28,17 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data)
|
|||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
uintptr_t start, end;
|
uintptr_t start, end;
|
||||||
uint32_t type;
|
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);
|
debug_info("%d %x-%x\n", type, start, end);
|
||||||
index++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interrupt_init();
|
||||||
|
|
||||||
debug("Hello, world!");
|
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!");
|
PANIC("End of kernel function!");
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ int multiboot_init(uint64_t magic, void *mboot_info)
|
|||||||
return 0;
|
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;
|
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;
|
extern struct kernel_boot_data_st kernel_boot_data;
|
||||||
|
|
||||||
int multiboot_init(uint64_t magic, void *mboot_info);
|
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
|
#endif
|
@ -5,6 +5,7 @@ apk add gmp-dev mpfr-dev mpc1-dev
|
|||||||
|
|
||||||
apk add make
|
apk add make
|
||||||
apk add grub-bios xorriso
|
apk add grub-bios xorriso
|
||||||
|
apk add python3
|
||||||
|
|
||||||
rm -rf /var/cache/apk/*
|
rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user