feat: idt, gdt. I fucking hate that. I understand like nothing. fuck intel.

This commit is contained in:
Karina
2025-12-21 21:14:29 +04:00
parent e5ce668a8a
commit dd4155584a
13 changed files with 394 additions and 28 deletions
+97
View File
@@ -0,0 +1,97 @@
bits 64
extern isr_handler_c
section .text
%macro ISR_NOERRCODE 1
global isr%1
isr%1:
push 0
push %1
jmp isr_common_stub
%endmacro
%macro ISR_ERRCODE 1
global isr%1
isr%1:
push %1
jmp isr_common_stub
%endmacro
ISR_NOERRCODE 0 ; Divide by zero
ISR_NOERRCODE 1 ; Debug
ISR_NOERRCODE 2 ; NMI
ISR_NOERRCODE 3 ; Breakpoint
ISR_NOERRCODE 4 ; Overflow
ISR_NOERRCODE 5 ; Bound Range Exceeded
ISR_NOERRCODE 6 ; Invalid Opcode
ISR_NOERRCODE 7 ; Device Not Available
ISR_ERRCODE 8 ; Double Fault
ISR_NOERRCODE 9 ; Coprocessor Segment Overrun
ISR_ERRCODE 10 ; Invalid TSS
ISR_ERRCODE 11 ; Segment Not Present
ISR_ERRCODE 12 ; Stack-Segment Fault
ISR_ERRCODE 13 ; General Protection Fault
ISR_ERRCODE 14 ; Page Fault
ISR_NOERRCODE 15 ; Reserved
ISR_NOERRCODE 16 ; x87 Floating-Point Exception
ISR_ERRCODE 17 ; Alignment Check
ISR_NOERRCODE 18 ; Machine Check
ISR_NOERRCODE 19 ; SIMD Floating-Point Exception
ISR_NOERRCODE 20 ; Virtualization Exception
ISR_NOERRCODE 21 ; Reserved
ISR_NOERRCODE 22 ; Reserved
ISR_NOERRCODE 23 ; Reserved
ISR_NOERRCODE 24 ; Reserved
ISR_NOERRCODE 25 ; Reserved
ISR_NOERRCODE 26 ; Reserved
ISR_NOERRCODE 27 ; Reserved
ISR_NOERRCODE 28 ; Reserved
ISR_NOERRCODE 29 ; Reserved
ISR_ERRCODE 30 ; Security Exception
ISR_NOERRCODE 31 ; Reserved
isr_common_stub:
push r15
push r14
push r13
push r12
push r11
push r10
push r9
push r8
push rdi
push rsi
push rbp
push rdx
push rcx
push rbx
push rax
mov rdi, rsp
call isr_handler_c
pop rax
pop rbx
pop rcx
pop rdx
pop rbp
pop rsi
pop rdi
pop r8
pop r9
pop r10
pop r11
pop r12
pop r13
pop r14
pop r15
add rsp, 16
iretq
global idt_load
idt_load:
lidt [rdi]
ret
+40
View File
@@ -0,0 +1,40 @@
bits 64
section .bss
align 16
stack_bottom:
resb 16384
stack_top:
section .text
global _start
global gdt_flush
extern kmain
_start:
cli
mov rsp, stack_top
xor rbp, rbp
call kmain
.hang:
hlt
jmp .hang
gdt_flush:
lgdt [rdi]
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
pop rdi
push 0x08
push rdi
retfq
+11 -1
View File
@@ -7,6 +7,9 @@
#include "panic.h" // IWYU pragma: keep
#include "../data/logo.h"
#include "gdt.h"
#include "idt.h"
void kmain(Bootinfo* info) {
u32 *fb = (u32*)info->framebuffer.base;
if (!fb) return;
@@ -21,12 +24,19 @@ void kmain(Bootinfo* info) {
console_init(&sg_ctx);
console_clear(0xFFFFFF);
console_set_color(0x000000);
gdt_init();
idt_init();
SG_Point logo_point = {sg_ctx.width-100, 100};
sg_put_img(&sg_ctx, &logo_point, &logo_img);
kprint("Welcome to termOS!!!\n");
kprintf("MemoryMap located at %x; \nMemory map size is %d\n", (u64)info->mem.map, (u64)info->mem.map_size);
for (i32 i = 0; i < 1000; i++) kprintf("Test %d\n", i);
int a = 1;
int b = 0;
kprintf("%d", a/b);
while (1) { __asm__("hlt"); }
}
+44
View File
@@ -0,0 +1,44 @@
// just fucking kill me already
#include "gdt.h"
GDTDescriptor gdt[3];
GDTPtr gdt_ptr;
void gdt_set_gate(int num, u64 base, u64 limit, u8 access, u8 gran) {
gdt[num].base_low = (base & 0xFFFF); // left only low 16bit
gdt[num].base_middle = (base >> 16) & 0xFF; // 3rd address byte
gdt[num].base_high = (base >> 24) & 0xFF; // 4th address byte
gdt[num].limit_low = (limit & 0xFFFF);
gdt[num].granularity = (limit >> 16) & 0x0F; // leave only first 4 bits (limit's left 16-19)
gdt[num].granularity |= gran & 0xF0; // get flags and concate two pieces so FFFFLLLL (L -- Limit; F -- flags)
gdt[num].access = access;
// intel,
// please
// FUCK YOU
// cancer of industry
// AMD FOREVER
}
extern void gdt_flush(u64 gdt_ptr_addr); // entry.asm
void gdt_init() {
gdt_ptr.limit = (sizeof(GDTDescriptor) * 3) - 1;
gdt_ptr.base = (u64)&gdt;
// 0: Null
gdt_set_gate(0, 0, 0, 0, 0);
// 1: Kernel Code (Ring 0)
// Access: 0x9A (Present, Ring0, Exec/Read)
// Granularity: 0x20 (Long Mode bit) access ring 0 code exec code readable
gdt_set_gate(1, 0, 0, 0x9A, 0x20); // 0x9A = 1 00 1 1 0 1
// 0x20 = 0010 0000 bit 5 is "Long mode"
// 2: Kernel Data (Ring 0)
// Access: 0x92 (Present, Ring0, Read/Write)
gdt_set_gate(2, 0, 0, 0x92, 0); // 0x92 can't exec
gdt_flush((u64)&gdt_ptr);
}
+70
View File
@@ -0,0 +1,70 @@
#include "idt.h"
#include "types.h"
IDTEntry idt[256];
IDTPtr idt_ptr;
extern void isr0(); extern void isr1(); extern void isr2(); extern void isr3();
extern void isr4(); extern void isr5(); extern void isr6(); extern void isr7();
extern void isr8(); extern void isr9(); extern void isr10(); extern void isr11();
extern void isr12(); extern void isr13(); extern void isr14(); extern void isr15();
extern void isr16(); extern void isr17(); extern void isr18(); extern void isr19();
extern void isr20(); extern void isr21(); extern void isr22(); extern void isr23();
extern void isr24(); extern void isr25(); extern void isr26(); extern void isr27();
extern void isr28(); extern void isr29(); extern void isr30(); extern void isr31();
extern void idt_load(u64); // asm: lidt [rdi] / ret
void idt_set_gate(int num, u64 handler, u16 sel, u8 flags) {
idt[num].offset_low = handler & 0xFFFF;
idt[num].offset_mid = (handler >> 16) & 0xFFFF;
idt[num].offset_high = (handler >> 32) & 0xFFFFFFFF;
idt[num].selector = sel; // 0x08 (Kernel Code)
idt[num].ist = 0;
idt[num].attributes = flags;
idt[num].reserved = 0;
}
void idt_init() {
idt_ptr.limit = (sizeof(IDTEntry) * 256) - 1;
idt_ptr.base = (u64)&idt;
const u8 flags = 0x8E;
const u8 selector = 0x08;
idt_set_gate(0, (u64)isr0, selector, flags);
idt_set_gate(1, (u64)isr1, selector, flags);
idt_set_gate(2, (u64)isr2, selector, flags);
idt_set_gate(3, (u64)isr3, selector, flags);
idt_set_gate(4, (u64)isr4, selector, flags);
idt_set_gate(5, (u64)isr5, selector, flags);
idt_set_gate(6, (u64)isr6, selector, flags);
idt_set_gate(7, (u64)isr7, selector, flags);
idt_set_gate(8, (u64)isr8, selector, flags);
idt_set_gate(9, (u64)isr9, selector, flags);
idt_set_gate(10, (u64)isr10, selector, flags);
idt_set_gate(11, (u64)isr11, selector, flags);
idt_set_gate(12, (u64)isr12, selector, flags);
idt_set_gate(13, (u64)isr13, selector, flags); // General Protection Fault
idt_set_gate(14, (u64)isr14, selector, flags); // Page Fault
idt_set_gate(15, (u64)isr15, selector, flags);
idt_set_gate(16, (u64)isr16, selector, flags);
idt_set_gate(17, (u64)isr17, selector, flags);
idt_set_gate(18, (u64)isr18, selector, flags);
idt_set_gate(19, (u64)isr19, selector, flags);
idt_set_gate(20, (u64)isr20, selector, flags);
idt_set_gate(21, (u64)isr21, selector, flags);
idt_set_gate(22, (u64)isr22, selector, flags);
idt_set_gate(23, (u64)isr23, selector, flags);
idt_set_gate(24, (u64)isr24, selector, flags);
idt_set_gate(25, (u64)isr25, selector, flags);
idt_set_gate(26, (u64)isr26, selector, flags);
idt_set_gate(27, (u64)isr27, selector, flags);
idt_set_gate(28, (u64)isr28, selector, flags);
idt_set_gate(29, (u64)isr29, selector, flags);
idt_set_gate(30, (u64)isr30, selector, flags);
idt_set_gate(31, (u64)isr31, selector, flags);
__asm__ volatile ("lidt %0" : : "m"(idt_ptr));
}
+6
View File
@@ -0,0 +1,6 @@
#include "panic.h"
#include "types.h"
void isr_handler_c(Registers *regs) {
panic(regs);
}
+50 -14
View File
@@ -1,24 +1,60 @@
#include "panic.h"
#include "console.h"
#include "shitgui.h"
static void hlt_loop() {
while (1) {
__asm__ volatile ("cli; hlt");
}
}
#include "types.h"
__attribute__((noreturn)) void panic(const char *msg) {
const char* exception_messages[] = {
"Division By Zero",
"Debug",
"Non Maskable Interrupt",
"Breakpoint",
"Into Detected Overflow",
"Out of Bounds",
"Invalid Opcode",
"No Coprocessor",
"Double Fault",
"Coprocessor Segment Overrun",
"Bad TSS",
"Segment Not Present",
"Stack Fault",
"General Protection Fault",
"Page Fault",
"Unknown Interrupt",
"Coprocessor Fault",
"Alignment Check",
"Machine Check",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved"
};
__attribute__((noreturn)) void panic(Registers *regs) {
console_clear(0xFF0000);
console_set_color(0xFFFFFF);
kprintf("\n\n");
kprintf(" KERNEL PANIC \n");
kprintf("-------------------\n");
kprintf(" Reason: %s\n", msg);
kprintf("-------------------\n");
kprintf(" System halted.\n");
kprintf("\t\t KERNEL PANIC :( \n");
kprintf("\t\t-------------------\n");
kprintf("\t\tCPU EXCEPTION: %d (%s)\n", regs->int_no, exception_messages[regs->int_no]);
kprintf("\t\tError Code: 0x%x\n", regs->err_code);
kprintf("\t\tInstruction Pointer (RIP): 0x%x\n", regs->rip);
kprintf("\t\tCode Segment (CS): 0x%x\n", regs->cs);
kprintf("\t\tFlags (RFLAGS): 0x%x\n", regs->rflags);
kprintf("\t\tStack Pointer (RSP): 0x%x\n", regs->rsp);
kprintf("\t\t-------------------\n");
kprintf(" \tSystem halted.\n");
hlt_loop();
while (1) {
__asm__ volatile ("cli; hlt");
}
}