feat: idt, gdt. I fucking hate that. I understand like nothing. fuck intel.
This commit is contained in:
+18
-11
@@ -1,24 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(termOS_krn LANGUAGES C ASM)
|
||||
project(termOS_krn LANGUAGES C ASM_NASM)
|
||||
|
||||
set(CMAKE_C_STANDARD 23)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
|
||||
add_compile_options(
|
||||
-ffreestanding
|
||||
-mno-red-zone
|
||||
-fno-stack-protector
|
||||
-fno-builtin
|
||||
-Wall -Wextra
|
||||
-g
|
||||
)
|
||||
|
||||
add_library(shitgui STATIC src/modules/shitgui.c)
|
||||
target_include_directories(shitgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
|
||||
add_executable(kernel
|
||||
add_executable(kernel
|
||||
src/entry.asm
|
||||
src/asm/interrupts.asm
|
||||
src/kmain.c
|
||||
src/modules/gdt.c
|
||||
src/modules/idt.c
|
||||
src/modules/interrupts.c
|
||||
src/modules/memory.c
|
||||
src/modules/serial.c
|
||||
src/modules/console.c
|
||||
@@ -40,6 +36,17 @@ target_link_options(kernel PRIVATE
|
||||
-T "${CMAKE_CURRENT_SOURCE_DIR}/linker.ld"
|
||||
)
|
||||
|
||||
target_compile_options(kernel PRIVATE
|
||||
$<$<COMPILE_LANGUAGE:C>:
|
||||
-ffreestanding
|
||||
-mno-red-zone
|
||||
-fno-stack-protector
|
||||
-fno-builtin
|
||||
-Wall -Wextra
|
||||
-g
|
||||
>
|
||||
)
|
||||
|
||||
set_target_properties(kernel PROPERTIES
|
||||
OUTPUT_NAME "kernel.elf"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#ifndef GDT_H
|
||||
#define GDT_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef struct {
|
||||
u16 limit_low;
|
||||
u16 base_low;
|
||||
u8 base_middle;
|
||||
u8 access;
|
||||
u8 granularity;
|
||||
u8 base_high;
|
||||
} __attribute__((packed)) GDTDescriptor;
|
||||
|
||||
|
||||
typedef struct {
|
||||
u16 limit;
|
||||
u64 base;
|
||||
} __attribute__((packed)) GDTPtr;
|
||||
|
||||
void gdt_init();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include "types.h"
|
||||
|
||||
typedef struct {
|
||||
u16 offset_low;
|
||||
u16 selector;
|
||||
u8 ist;
|
||||
u8 attributes;
|
||||
u16 offset_mid;
|
||||
u32 offset_high;
|
||||
u32 reserved;
|
||||
} __attribute__((packed)) IDTEntry;
|
||||
|
||||
typedef struct {
|
||||
u16 limit;
|
||||
u64 base;
|
||||
} __attribute__((packed)) IDTPtr;
|
||||
|
||||
void idt_init();
|
||||
@@ -1,3 +1,10 @@
|
||||
#pragma once
|
||||
#ifndef PANIC_H
|
||||
#define PANIC_H
|
||||
#include "types.h"
|
||||
|
||||
__attribute__((noreturn)) void panic(const char *msg);
|
||||
__attribute__((noreturn)) void panic(Registers *regs);
|
||||
|
||||
extern const char* exception_messages[];
|
||||
|
||||
#endif
|
||||
@@ -14,4 +14,10 @@ typedef signed _BitInt(64) i64;
|
||||
typedef u64 usize;
|
||||
typedef u64 uintptr_t;
|
||||
|
||||
typedef struct {
|
||||
u64 rax, rbx, rcx, rdx, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15; // Pushed by us
|
||||
u64 int_no, err_code; // Pushed by macro
|
||||
u64 rip, cs, rflags, rsp, ss; // Pushed by CPU
|
||||
} Registers;
|
||||
|
||||
#endif
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
ENTRY(kmain)
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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"); }
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "panic.h"
|
||||
#include "types.h"
|
||||
|
||||
void isr_handler_c(Registers *regs) {
|
||||
panic(regs);
|
||||
}
|
||||
+50
-14
@@ -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");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user