mirror of
https://github.com/Leonmmcoset/cleonos.git
synced 2026-04-21 18:44:01 +00:00
Stage 3
This commit is contained in:
17
Makefile
17
Makefile
@@ -63,22 +63,29 @@ define log_step
|
|||||||
@printf '%b\n' "$(COLOR_STEP)[STEP]$(COLOR_RESET) $(1)"
|
@printf '%b\n' "$(COLOR_STEP)[STEP]$(COLOR_RESET) $(1)"
|
||||||
endef
|
endef
|
||||||
|
|
||||||
SOURCES := \
|
C_SOURCES := \
|
||||||
clks/kernel/kmain.c \
|
clks/kernel/kmain.c \
|
||||||
clks/kernel/log.c \
|
clks/kernel/log.c \
|
||||||
clks/kernel/limine_requests.c \
|
clks/kernel/limine_requests.c \
|
||||||
clks/kernel/tty.c \
|
clks/kernel/tty.c \
|
||||||
clks/kernel/pmm.c \
|
clks/kernel/pmm.c \
|
||||||
clks/kernel/heap.c \
|
clks/kernel/heap.c \
|
||||||
|
clks/kernel/interrupts.c \
|
||||||
clks/lib/string.c \
|
clks/lib/string.c \
|
||||||
clks/drivers/serial/serial.c \
|
clks/drivers/serial/serial.c \
|
||||||
clks/drivers/video/framebuffer.c \
|
clks/drivers/video/framebuffer.c \
|
||||||
clks/drivers/video/font8x8.c \
|
clks/drivers/video/font8x8.c \
|
||||||
clks/arch/x86_64/boot.c
|
clks/arch/x86_64/boot.c
|
||||||
|
|
||||||
OBJECTS := $(patsubst %.c,$(OBJ_ROOT)/%.o,$(SOURCES))
|
ASM_SOURCES := \
|
||||||
|
clks/arch/x86_64/interrupt_stubs.S
|
||||||
|
|
||||||
|
C_OBJECTS := $(patsubst %.c,$(OBJ_ROOT)/%.o,$(C_SOURCES))
|
||||||
|
ASM_OBJECTS := $(patsubst %.S,$(OBJ_ROOT)/%.o,$(ASM_SOURCES))
|
||||||
|
OBJECTS := $(C_OBJECTS) $(ASM_OBJECTS)
|
||||||
|
|
||||||
CFLAGS_COMMON := -std=c11 -ffreestanding -fno-stack-protector -fno-builtin -Wall -Wextra -Werror -Iclks/include
|
CFLAGS_COMMON := -std=c11 -ffreestanding -fno-stack-protector -fno-builtin -Wall -Wextra -Werror -Iclks/include
|
||||||
|
ASFLAGS_COMMON := -ffreestanding -Iclks/include
|
||||||
LDFLAGS_COMMON := -nostdlib -z max-page-size=0x1000
|
LDFLAGS_COMMON := -nostdlib -z max-page-size=0x1000
|
||||||
|
|
||||||
.PHONY: all setup setup-tools setup-limine kernel ramdisk iso run debug clean clean-all help
|
.PHONY: all setup setup-tools setup-limine kernel ramdisk iso run debug clean clean-all help
|
||||||
@@ -165,6 +172,12 @@ $(OBJ_ROOT)/%.o: %.c Makefile
|
|||||||
> @mkdir -p $(dir $@)
|
> @mkdir -p $(dir $@)
|
||||||
> @$(CC) $(CFLAGS_COMMON) $(ARCH_CFLAGS) -c $< -o $@
|
> @$(CC) $(CFLAGS_COMMON) $(ARCH_CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(OBJ_ROOT)/%.o: %.S Makefile
|
||||||
|
> $(call log_step,assembling $<)
|
||||||
|
> @mkdir -p $(dir $@)
|
||||||
|
> @$(CC) $(ASFLAGS_COMMON) $(ARCH_CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
|
||||||
$(RAMDISK_IMAGE):
|
$(RAMDISK_IMAGE):
|
||||||
> $(call log_step,packing ramdisk -> $(RAMDISK_IMAGE))
|
> $(call log_step,packing ramdisk -> $(RAMDISK_IMAGE))
|
||||||
> @mkdir -p $(dir $@)
|
> @mkdir -p $(dir $@)
|
||||||
|
|||||||
117
clks/arch/x86_64/interrupt_stubs.S
Normal file
117
clks/arch/x86_64/interrupt_stubs.S
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
.intel_syntax noprefix
|
||||||
|
|
||||||
|
.global clks_isr_stub_default
|
||||||
|
.extern clks_interrupt_dispatch
|
||||||
|
|
||||||
|
.macro ISR_NOERR num
|
||||||
|
.global clks_isr_stub_\num
|
||||||
|
clks_isr_stub_\num:
|
||||||
|
push 0
|
||||||
|
push \num
|
||||||
|
jmp clks_isr_common
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro ISR_ERR num
|
||||||
|
.global clks_isr_stub_\num
|
||||||
|
clks_isr_stub_\num:
|
||||||
|
push \num
|
||||||
|
jmp clks_isr_common
|
||||||
|
.endm
|
||||||
|
|
||||||
|
clks_isr_stub_default:
|
||||||
|
push 0
|
||||||
|
push 255
|
||||||
|
jmp clks_isr_common
|
||||||
|
|
||||||
|
ISR_NOERR 0
|
||||||
|
ISR_NOERR 1
|
||||||
|
ISR_NOERR 2
|
||||||
|
ISR_NOERR 3
|
||||||
|
ISR_NOERR 4
|
||||||
|
ISR_NOERR 5
|
||||||
|
ISR_NOERR 6
|
||||||
|
ISR_NOERR 7
|
||||||
|
ISR_ERR 8
|
||||||
|
ISR_NOERR 9
|
||||||
|
ISR_ERR 10
|
||||||
|
ISR_ERR 11
|
||||||
|
ISR_ERR 12
|
||||||
|
ISR_ERR 13
|
||||||
|
ISR_ERR 14
|
||||||
|
ISR_NOERR 15
|
||||||
|
ISR_NOERR 16
|
||||||
|
ISR_ERR 17
|
||||||
|
ISR_NOERR 18
|
||||||
|
ISR_NOERR 19
|
||||||
|
ISR_NOERR 20
|
||||||
|
ISR_ERR 21
|
||||||
|
ISR_NOERR 22
|
||||||
|
ISR_NOERR 23
|
||||||
|
ISR_NOERR 24
|
||||||
|
ISR_NOERR 25
|
||||||
|
ISR_NOERR 26
|
||||||
|
ISR_NOERR 27
|
||||||
|
ISR_NOERR 28
|
||||||
|
ISR_ERR 29
|
||||||
|
ISR_ERR 30
|
||||||
|
ISR_NOERR 31
|
||||||
|
|
||||||
|
ISR_NOERR 32
|
||||||
|
ISR_NOERR 33
|
||||||
|
ISR_NOERR 34
|
||||||
|
ISR_NOERR 35
|
||||||
|
ISR_NOERR 36
|
||||||
|
ISR_NOERR 37
|
||||||
|
ISR_NOERR 38
|
||||||
|
ISR_NOERR 39
|
||||||
|
ISR_NOERR 40
|
||||||
|
ISR_NOERR 41
|
||||||
|
ISR_NOERR 42
|
||||||
|
ISR_NOERR 43
|
||||||
|
ISR_NOERR 44
|
||||||
|
ISR_NOERR 45
|
||||||
|
ISR_NOERR 46
|
||||||
|
ISR_NOERR 47
|
||||||
|
|
||||||
|
clks_isr_common:
|
||||||
|
cld
|
||||||
|
|
||||||
|
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
|
||||||
|
sub rsp, 8
|
||||||
|
call clks_interrupt_dispatch
|
||||||
|
add rsp, 8
|
||||||
|
|
||||||
|
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, 16
|
||||||
|
iretq
|
||||||
9
clks/include/clks/interrupts.h
Normal file
9
clks/include/clks/interrupts.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#ifndef CLKS_INTERRUPTS_H
|
||||||
|
#define CLKS_INTERRUPTS_H
|
||||||
|
|
||||||
|
#include <clks/types.h>
|
||||||
|
|
||||||
|
void clks_interrupts_init(void);
|
||||||
|
u64 clks_interrupts_timer_ticks(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
313
clks/kernel/interrupts.c
Normal file
313
clks/kernel/interrupts.c
Normal file
@@ -0,0 +1,313 @@
|
|||||||
|
#include <clks/compiler.h>
|
||||||
|
#include <clks/cpu.h>
|
||||||
|
#include <clks/interrupts.h>
|
||||||
|
#include <clks/log.h>
|
||||||
|
#include <clks/types.h>
|
||||||
|
|
||||||
|
#define CLKS_IDT_ENTRY_COUNT 256U
|
||||||
|
#define CLKS_INTERRUPT_GATE 0x8EU
|
||||||
|
|
||||||
|
#define CLKS_PIC1_CMD 0x20U
|
||||||
|
#define CLKS_PIC1_DATA 0x21U
|
||||||
|
#define CLKS_PIC2_CMD 0xA0U
|
||||||
|
#define CLKS_PIC2_DATA 0xA1U
|
||||||
|
#define CLKS_PIC_EOI 0x20U
|
||||||
|
|
||||||
|
#define CLKS_IRQ_BASE 32U
|
||||||
|
#define CLKS_IRQ_TIMER 32U
|
||||||
|
#define CLKS_IRQ_LAST 47U
|
||||||
|
|
||||||
|
struct clks_idt_entry {
|
||||||
|
u16 offset_low;
|
||||||
|
u16 selector;
|
||||||
|
u8 ist;
|
||||||
|
u8 type_attr;
|
||||||
|
u16 offset_mid;
|
||||||
|
u32 offset_high;
|
||||||
|
u32 zero;
|
||||||
|
} CLKS_PACKED;
|
||||||
|
|
||||||
|
struct clks_idtr {
|
||||||
|
u16 limit;
|
||||||
|
u64 base;
|
||||||
|
} CLKS_PACKED;
|
||||||
|
|
||||||
|
struct clks_interrupt_frame {
|
||||||
|
u64 rax;
|
||||||
|
u64 rbx;
|
||||||
|
u64 rcx;
|
||||||
|
u64 rdx;
|
||||||
|
u64 rsi;
|
||||||
|
u64 rdi;
|
||||||
|
u64 rbp;
|
||||||
|
u64 r8;
|
||||||
|
u64 r9;
|
||||||
|
u64 r10;
|
||||||
|
u64 r11;
|
||||||
|
u64 r12;
|
||||||
|
u64 r13;
|
||||||
|
u64 r14;
|
||||||
|
u64 r15;
|
||||||
|
u64 vector;
|
||||||
|
u64 error_code;
|
||||||
|
u64 rip;
|
||||||
|
u64 cs;
|
||||||
|
u64 rflags;
|
||||||
|
u64 rsp;
|
||||||
|
u64 ss;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void clks_isr_stub_default(void);
|
||||||
|
extern void clks_isr_stub_0(void);
|
||||||
|
extern void clks_isr_stub_1(void);
|
||||||
|
extern void clks_isr_stub_2(void);
|
||||||
|
extern void clks_isr_stub_3(void);
|
||||||
|
extern void clks_isr_stub_4(void);
|
||||||
|
extern void clks_isr_stub_5(void);
|
||||||
|
extern void clks_isr_stub_6(void);
|
||||||
|
extern void clks_isr_stub_7(void);
|
||||||
|
extern void clks_isr_stub_8(void);
|
||||||
|
extern void clks_isr_stub_9(void);
|
||||||
|
extern void clks_isr_stub_10(void);
|
||||||
|
extern void clks_isr_stub_11(void);
|
||||||
|
extern void clks_isr_stub_12(void);
|
||||||
|
extern void clks_isr_stub_13(void);
|
||||||
|
extern void clks_isr_stub_14(void);
|
||||||
|
extern void clks_isr_stub_15(void);
|
||||||
|
extern void clks_isr_stub_16(void);
|
||||||
|
extern void clks_isr_stub_17(void);
|
||||||
|
extern void clks_isr_stub_18(void);
|
||||||
|
extern void clks_isr_stub_19(void);
|
||||||
|
extern void clks_isr_stub_20(void);
|
||||||
|
extern void clks_isr_stub_21(void);
|
||||||
|
extern void clks_isr_stub_22(void);
|
||||||
|
extern void clks_isr_stub_23(void);
|
||||||
|
extern void clks_isr_stub_24(void);
|
||||||
|
extern void clks_isr_stub_25(void);
|
||||||
|
extern void clks_isr_stub_26(void);
|
||||||
|
extern void clks_isr_stub_27(void);
|
||||||
|
extern void clks_isr_stub_28(void);
|
||||||
|
extern void clks_isr_stub_29(void);
|
||||||
|
extern void clks_isr_stub_30(void);
|
||||||
|
extern void clks_isr_stub_31(void);
|
||||||
|
extern void clks_isr_stub_32(void);
|
||||||
|
extern void clks_isr_stub_33(void);
|
||||||
|
extern void clks_isr_stub_34(void);
|
||||||
|
extern void clks_isr_stub_35(void);
|
||||||
|
extern void clks_isr_stub_36(void);
|
||||||
|
extern void clks_isr_stub_37(void);
|
||||||
|
extern void clks_isr_stub_38(void);
|
||||||
|
extern void clks_isr_stub_39(void);
|
||||||
|
extern void clks_isr_stub_40(void);
|
||||||
|
extern void clks_isr_stub_41(void);
|
||||||
|
extern void clks_isr_stub_42(void);
|
||||||
|
extern void clks_isr_stub_43(void);
|
||||||
|
extern void clks_isr_stub_44(void);
|
||||||
|
extern void clks_isr_stub_45(void);
|
||||||
|
extern void clks_isr_stub_46(void);
|
||||||
|
extern void clks_isr_stub_47(void);
|
||||||
|
|
||||||
|
static struct clks_idt_entry clks_idt[CLKS_IDT_ENTRY_COUNT];
|
||||||
|
static u16 clks_idt_code_selector = 0x08U;
|
||||||
|
static u64 clks_timer_ticks = 0;
|
||||||
|
|
||||||
|
static const char *clks_exception_names[32] = {
|
||||||
|
"DE DIVIDE ERROR",
|
||||||
|
"DB DEBUG",
|
||||||
|
"NMI",
|
||||||
|
"BP BREAKPOINT",
|
||||||
|
"OF OVERFLOW",
|
||||||
|
"BR BOUND RANGE",
|
||||||
|
"UD INVALID OPCODE",
|
||||||
|
"NM DEVICE NOT AVAILABLE",
|
||||||
|
"DF DOUBLE FAULT",
|
||||||
|
"COPROCESSOR SEGMENT",
|
||||||
|
"TS INVALID TSS",
|
||||||
|
"NP SEGMENT NOT PRESENT",
|
||||||
|
"SS STACK SEGMENT",
|
||||||
|
"GP GENERAL PROTECTION",
|
||||||
|
"PF PAGE FAULT",
|
||||||
|
"RESERVED",
|
||||||
|
"MF X87 FLOAT",
|
||||||
|
"AC ALIGNMENT CHECK",
|
||||||
|
"MC MACHINE CHECK",
|
||||||
|
"XF SIMD FLOAT",
|
||||||
|
"VE VIRT EXCEPTION",
|
||||||
|
"CP CONTROL PROTECTION",
|
||||||
|
"RESERVED",
|
||||||
|
"RESERVED",
|
||||||
|
"RESERVED",
|
||||||
|
"RESERVED",
|
||||||
|
"RESERVED",
|
||||||
|
"RESERVED",
|
||||||
|
"HV HYPERVISOR",
|
||||||
|
"VC VMM COMM",
|
||||||
|
"SX SECURITY",
|
||||||
|
"RESERVED"
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void clks_outb(u16 port, u8 value) {
|
||||||
|
__asm__ volatile("outb %0, %1" : : "a"(value), "Nd"(port));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u8 clks_inb(u16 port) {
|
||||||
|
u8 value;
|
||||||
|
__asm__ volatile("inb %1, %0" : "=a"(value) : "Nd"(port));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void clks_io_wait(void) {
|
||||||
|
__asm__ volatile("outb %%al, $0x80" : : "a"(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clks_pic_remap_and_mask(void) {
|
||||||
|
u8 master_mask = clks_inb(CLKS_PIC1_DATA);
|
||||||
|
u8 slave_mask = clks_inb(CLKS_PIC2_DATA);
|
||||||
|
|
||||||
|
clks_outb(CLKS_PIC1_CMD, 0x11);
|
||||||
|
clks_io_wait();
|
||||||
|
clks_outb(CLKS_PIC2_CMD, 0x11);
|
||||||
|
clks_io_wait();
|
||||||
|
|
||||||
|
clks_outb(CLKS_PIC1_DATA, CLKS_IRQ_BASE);
|
||||||
|
clks_io_wait();
|
||||||
|
clks_outb(CLKS_PIC2_DATA, CLKS_IRQ_BASE + 8U);
|
||||||
|
clks_io_wait();
|
||||||
|
|
||||||
|
clks_outb(CLKS_PIC1_DATA, 4U);
|
||||||
|
clks_io_wait();
|
||||||
|
clks_outb(CLKS_PIC2_DATA, 2U);
|
||||||
|
clks_io_wait();
|
||||||
|
|
||||||
|
clks_outb(CLKS_PIC1_DATA, 0x01);
|
||||||
|
clks_io_wait();
|
||||||
|
clks_outb(CLKS_PIC2_DATA, 0x01);
|
||||||
|
clks_io_wait();
|
||||||
|
|
||||||
|
(void)master_mask;
|
||||||
|
(void)slave_mask;
|
||||||
|
|
||||||
|
clks_outb(CLKS_PIC1_DATA, 0xFEU);
|
||||||
|
clks_outb(CLKS_PIC2_DATA, 0xFFU);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clks_pic_send_eoi(u64 vector) {
|
||||||
|
if (vector >= 40U) {
|
||||||
|
clks_outb(CLKS_PIC2_CMD, CLKS_PIC_EOI);
|
||||||
|
}
|
||||||
|
|
||||||
|
clks_outb(CLKS_PIC1_CMD, CLKS_PIC_EOI);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clks_idt_set_gate(u8 vector, void (*handler)(void), u8 flags) {
|
||||||
|
u64 addr = (u64)handler;
|
||||||
|
|
||||||
|
clks_idt[vector].offset_low = (u16)(addr & 0xFFFFULL);
|
||||||
|
clks_idt[vector].selector = clks_idt_code_selector;
|
||||||
|
clks_idt[vector].ist = 0;
|
||||||
|
clks_idt[vector].type_attr = flags;
|
||||||
|
clks_idt[vector].offset_mid = (u16)((addr >> 16) & 0xFFFFULL);
|
||||||
|
clks_idt[vector].offset_high = (u32)((addr >> 32) & 0xFFFFFFFFULL);
|
||||||
|
clks_idt[vector].zero = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clks_load_idt(void) {
|
||||||
|
struct clks_idtr idtr;
|
||||||
|
|
||||||
|
idtr.limit = (u16)(sizeof(clks_idt) - 1U);
|
||||||
|
idtr.base = (u64)&clks_idt[0];
|
||||||
|
|
||||||
|
__asm__ volatile("lidt %0" : : "m"(idtr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clks_enable_interrupts(void) {
|
||||||
|
__asm__ volatile("sti");
|
||||||
|
}
|
||||||
|
|
||||||
|
void clks_interrupt_dispatch(struct clks_interrupt_frame *frame) {
|
||||||
|
u64 vector = frame->vector;
|
||||||
|
|
||||||
|
if (vector < 32U) {
|
||||||
|
clks_log(CLKS_LOG_ERROR, "EXC", clks_exception_names[vector]);
|
||||||
|
clks_log_hex(CLKS_LOG_ERROR, "EXC", "VECTOR", vector);
|
||||||
|
clks_log_hex(CLKS_LOG_ERROR, "EXC", "ERROR", frame->error_code);
|
||||||
|
clks_log_hex(CLKS_LOG_ERROR, "EXC", "RIP", frame->rip);
|
||||||
|
clks_cpu_halt_forever();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vector == CLKS_IRQ_TIMER) {
|
||||||
|
clks_timer_ticks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vector >= CLKS_IRQ_BASE && vector <= CLKS_IRQ_LAST) {
|
||||||
|
clks_pic_send_eoi(vector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clks_interrupts_init(void) {
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
__asm__ volatile("mov %%cs, %0" : "=r"(clks_idt_code_selector));
|
||||||
|
|
||||||
|
for (i = 0; i < CLKS_IDT_ENTRY_COUNT; i++) {
|
||||||
|
clks_idt_set_gate((u8)i, clks_isr_stub_default, CLKS_INTERRUPT_GATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
clks_idt_set_gate(0, clks_isr_stub_0, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(1, clks_isr_stub_1, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(2, clks_isr_stub_2, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(3, clks_isr_stub_3, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(4, clks_isr_stub_4, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(5, clks_isr_stub_5, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(6, clks_isr_stub_6, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(7, clks_isr_stub_7, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(8, clks_isr_stub_8, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(9, clks_isr_stub_9, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(10, clks_isr_stub_10, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(11, clks_isr_stub_11, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(12, clks_isr_stub_12, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(13, clks_isr_stub_13, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(14, clks_isr_stub_14, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(15, clks_isr_stub_15, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(16, clks_isr_stub_16, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(17, clks_isr_stub_17, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(18, clks_isr_stub_18, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(19, clks_isr_stub_19, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(20, clks_isr_stub_20, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(21, clks_isr_stub_21, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(22, clks_isr_stub_22, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(23, clks_isr_stub_23, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(24, clks_isr_stub_24, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(25, clks_isr_stub_25, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(26, clks_isr_stub_26, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(27, clks_isr_stub_27, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(28, clks_isr_stub_28, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(29, clks_isr_stub_29, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(30, clks_isr_stub_30, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(31, clks_isr_stub_31, CLKS_INTERRUPT_GATE);
|
||||||
|
|
||||||
|
clks_idt_set_gate(32, clks_isr_stub_32, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(33, clks_isr_stub_33, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(34, clks_isr_stub_34, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(35, clks_isr_stub_35, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(36, clks_isr_stub_36, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(37, clks_isr_stub_37, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(38, clks_isr_stub_38, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(39, clks_isr_stub_39, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(40, clks_isr_stub_40, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(41, clks_isr_stub_41, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(42, clks_isr_stub_42, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(43, clks_isr_stub_43, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(44, clks_isr_stub_44, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(45, clks_isr_stub_45, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(46, clks_isr_stub_46, CLKS_INTERRUPT_GATE);
|
||||||
|
clks_idt_set_gate(47, clks_isr_stub_47, CLKS_INTERRUPT_GATE);
|
||||||
|
|
||||||
|
clks_pic_remap_and_mask();
|
||||||
|
clks_load_idt();
|
||||||
|
clks_enable_interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 clks_interrupts_timer_ticks(void) {
|
||||||
|
return clks_timer_ticks;
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
#include <clks/cpu.h>
|
#include <clks/cpu.h>
|
||||||
#include <clks/framebuffer.h>
|
#include <clks/framebuffer.h>
|
||||||
#include <clks/heap.h>
|
#include <clks/heap.h>
|
||||||
|
#include <clks/interrupts.h>
|
||||||
#include <clks/kernel.h>
|
#include <clks/kernel.h>
|
||||||
#include <clks/log.h>
|
#include <clks/log.h>
|
||||||
#include <clks/pmm.h>
|
#include <clks/pmm.h>
|
||||||
@@ -30,7 +31,7 @@ void clks_kernel_main(void) {
|
|||||||
clks_tty_init();
|
clks_tty_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
clks_log(CLKS_LOG_INFO, "BOOT", "CLEONOS STAGE2 START");
|
clks_log(CLKS_LOG_INFO, "BOOT", "CLEONOS STAGE3 START");
|
||||||
|
|
||||||
if (boot_fb == CLKS_NULL) {
|
if (boot_fb == CLKS_NULL) {
|
||||||
clks_log(CLKS_LOG_WARN, "VIDEO", "NO FRAMEBUFFER FROM LIMINE");
|
clks_log(CLKS_LOG_WARN, "VIDEO", "NO FRAMEBUFFER FROM LIMINE");
|
||||||
@@ -77,6 +78,9 @@ void clks_kernel_main(void) {
|
|||||||
clks_kfree(heap_probe);
|
clks_kfree(heap_probe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clks_interrupts_init();
|
||||||
|
clks_log(CLKS_LOG_INFO, "INT", "IDT + PIC INITIALIZED");
|
||||||
|
|
||||||
clks_log(CLKS_LOG_INFO, "TTY", "VIRTUAL TTY0 READY");
|
clks_log(CLKS_LOG_INFO, "TTY", "VIRTUAL TTY0 READY");
|
||||||
clks_log(CLKS_LOG_DEBUG, "KERNEL", "IDLE LOOP ENTER");
|
clks_log(CLKS_LOG_DEBUG, "KERNEL", "IDLE LOOP ENTER");
|
||||||
|
|
||||||
|
|||||||
34
docs/stage3.md
Normal file
34
docs/stage3.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# CLeonOS Stage3
|
||||||
|
|
||||||
|
## Stage Goal
|
||||||
|
- Add interrupt and exception foundation for x86_64 CLKS.
|
||||||
|
- Build and load IDT with exception vectors (0-31) and PIC IRQ vectors (32-47).
|
||||||
|
- Remap PIC and enable timer IRQ.
|
||||||
|
- Provide unified ISR stub + C dispatcher.
|
||||||
|
|
||||||
|
## Acceptance Criteria
|
||||||
|
- Kernel boots and prints `INT IDT + PIC INITIALIZED`.
|
||||||
|
- CPU exceptions are captured and logged with vector/error/RIP.
|
||||||
|
- Timer IRQ increments internal tick counter without panic.
|
||||||
|
- Kernel reaches idle loop with interrupts enabled.
|
||||||
|
|
||||||
|
## Build Targets
|
||||||
|
- `make setup`
|
||||||
|
- `make iso`
|
||||||
|
- `make run`
|
||||||
|
- `make debug`
|
||||||
|
|
||||||
|
## QEMU Command
|
||||||
|
- `qemu-system-x86_64 -M q35 -m 1024M -cdrom build/CLeonOS-x86_64.iso -serial stdio`
|
||||||
|
|
||||||
|
## Common Bugs and Debugging
|
||||||
|
- Triple fault right after enabling interrupts:
|
||||||
|
- Check IDT entry selector/type and verify `lidt` loaded valid base/limit.
|
||||||
|
- Exception panic with wrong vector/error layout:
|
||||||
|
- Verify assembly stub push order matches `struct clks_interrupt_frame`.
|
||||||
|
- IRQ storm or hang:
|
||||||
|
- Ensure PIC EOI is sent for IRQ vectors and IRQ masks are correct.
|
||||||
|
- Link failure for ISR symbols:
|
||||||
|
- Confirm `interrupt_stubs.S` is included in Makefile and assembled to object file.
|
||||||
|
- Limine ELF panic on segment permissions:
|
||||||
|
- Keep linker sections page-aligned to avoid mixed permission pages.
|
||||||
Reference in New Issue
Block a user