From 98b4afb451e480d2256d6b24c88eb0777a6bdcc0 Mon Sep 17 00:00:00 2001 From: vanten-s Date: Tue, 25 Feb 2025 18:48:58 +0100 Subject: [PATCH] Testing paging and entering userland --- arch/i686/bootstrap.s | 13 +++++++ arch/i686/interrupts/idt.c | 3 ++ arch/i686/interrupts/interrupt.c | 11 ++++++ arch/i686/interrupts/interrupt.h | 1 + arch/i686/paging.c | 66 +++++++++++++++++++++++++++----- kernel/elf.c | 4 +- kernel/heap.c | 2 +- kernel/kernel.c | 13 +++---- kernel/syscall.c | 3 ++ kernel/task.c | 2 +- 10 files changed, 96 insertions(+), 22 deletions(-) diff --git a/arch/i686/bootstrap.s b/arch/i686/bootstrap.s index a2d0c61..80283e3 100644 --- a/arch/i686/bootstrap.s +++ b/arch/i686/bootstrap.s @@ -124,6 +124,19 @@ _start: # Set up the stack. mov $stack_top, %esp + # Setup the GDT + call gdt_init + + jmp $0x08,$reload_CS + +reload_CS: + mov $0x10, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + # Enter the high-level kernel. call kernel_main diff --git a/arch/i686/interrupts/idt.c b/arch/i686/interrupts/idt.c index 6017f44..d1401a0 100644 --- a/arch/i686/interrupts/idt.c +++ b/arch/i686/interrupts/idt.c @@ -132,6 +132,9 @@ static void add_exceptions() entry = generate_entry(true, divide_by_zero, 0xF, 0, 0x8); add_entry(entry, DivisionByZero); + entry = generate_entry(true, page_fault, 0xF, 0, 0x8); + add_entry(entry, PageFault); + entry = generate_entry(true, general_protection_fault, 0xF, 0, 0x8); add_entry(entry, GenerProtFault); diff --git a/arch/i686/interrupts/interrupt.c b/arch/i686/interrupts/interrupt.c index 6e26577..6c2eac4 100644 --- a/arch/i686/interrupts/interrupt.c +++ b/arch/i686/interrupts/interrupt.c @@ -23,12 +23,14 @@ static void stack_trace() __attribute__((interrupt)) void divide_by_zero(struct interrupt_frame*) { + asm("cli"); terminal_writestring("Yo dude u cant divide by zero yao\n"); while (1) { } } __attribute__((interrupt)) void general_protection_fault(struct interrupt_frame*) { + asm("cli"); terminal_writestring("GPF handler called\n"); while (1) { asm("cli"); @@ -38,6 +40,7 @@ __attribute__((interrupt)) void general_protection_fault(struct interrupt_frame* __attribute__((interrupt)) void double_fault(struct interrupt_frame*) { + asm("cli"); stack_trace(); terminal_writestring("2 Errors in a row, u better behave naughty naughty\n"); while (1) { @@ -48,10 +51,18 @@ __attribute__((interrupt)) void double_fault(struct interrupt_frame*) __attribute__((interrupt)) void exception(struct interrupt_frame*) { + asm("cli"); terminal_writestring("Some weird error code stuff\n"); while (1) { } } +__attribute__((interrupt)) void page_fault(struct interrupt_frame*) +{ + asm("cli"); + terminal_writestring("Page Fault\n"); + while (1) { } +} + __attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame*) { terminal_writestring("Keyboard Interrupt\n"); diff --git a/arch/i686/interrupts/interrupt.h b/arch/i686/interrupts/interrupt.h index d4b6c59..3d29951 100644 --- a/arch/i686/interrupts/interrupt.h +++ b/arch/i686/interrupts/interrupt.h @@ -11,6 +11,7 @@ struct interrupt_frame { __attribute__((interrupt)) void divide_by_zero(struct interrupt_frame* frame); __attribute__((interrupt)) void general_protection_fault(struct interrupt_frame* frame); __attribute__((interrupt)) void double_fault(struct interrupt_frame* frame); +__attribute__((interrupt)) void page_fault(struct interrupt_frame* frame); __attribute__((interrupt)) void exception(struct interrupt_frame* frame); diff --git a/arch/i686/paging.c b/arch/i686/paging.c index c9ce1dd..e52ee0f 100644 --- a/arch/i686/paging.c +++ b/arch/i686/paging.c @@ -4,6 +4,8 @@ #include #include +#include +#include struct x86_Page_Directory { bool present: 1; @@ -15,7 +17,7 @@ struct x86_Page_Directory { bool available_2: 1; bool page_size: 1; uint8_t available_1 : 4; - uint32_t address : 20; // Multiply by 0x1000 + uintptr_t address : 20; // Multiply by 0x1000 } __attribute__((packed)); struct x86_Page_Table { @@ -29,22 +31,66 @@ struct x86_Page_Table { bool page_attribute_table: 1; bool global: 1; uint8_t available_1 : 3; - uint32_t address : 20; // Multiply by 0x1000 + uintptr_t address : 20; // Multiply by 0x1000 } __attribute__((packed)); extern struct x86_Page_Directory boot_page_directory[1024] __attribute__((aligned(4096))); +static struct x86_Page_Table user_code_table __attribute__((aligned(4096))); +static uint8_t user_code[4096] __attribute__((aligned(4096))); + +static struct x86_Page_Table user_data_table __attribute__((aligned(4096))); +static uint8_t user_data[4096] __attribute__((aligned(4096))); + static struct x86_Page_Table* get_table(uint16_t index) { - struct x86_Page_Table* table = (struct x86_Page_Table*)(boot_page_directory[index].address * 0x1000 + 0xC0000000); + struct x86_Page_Table* table = (struct x86_Page_Table*)((boot_page_directory[index].address << 12) + 0xC0000000); return table; } -void setup_paging() { - struct x86_Page_Table* kernel = get_table(768); - for (int i = 0; i < 1024; i++) { - if (kernel[i].address != 0) { - struct x86_Page_Table test = kernel[i]; - } - } +static void reload_pages () { + asm("\ +movl %cr3, %ecx; \ +movl %ecx, %cr3; \ + "); } +static void set_page_directory_entry(uintptr_t address, struct x86_Page_Table* table) { + boot_page_directory[address >> 22].address = ((uintptr_t)(table) - 0xC0000000) >> 12; + boot_page_directory[address >> 22].present = true; + boot_page_directory[address >> 22].read_write = true; +} + + +void setup_paging() { + struct x86_Page_Table* kernel = get_table(768); + uint16_t i = 0; + while (kernel[i].present == 0) { + i++; + } + + terminal_writestring("Kernel Start Page: "); + print_hex_bytes(&i, 2); + while (kernel[i].present != 0) { + i++; + } + + terminal_writestring("\nKernel End Page: "); + print_hex_bytes(&i, 2); + terminal_putchar('\n'); + + set_page_directory_entry(0, &user_code_table); + + user_code_table.address = ((uintptr_t)user_code - 0xC0000000) >> 12; + user_code_table.present = true; + user_code_table.read_write = true; + user_code_table.user_supervisor = true; + + set_page_directory_entry(0x00400000, &user_data_table); + + user_data_table.address = ((uintptr_t)user_data - 0xC0000000) >> 12; + user_data_table.present = true; + user_data_table.read_write = true; + user_data_table.user_supervisor = true; + + reload_pages(); +} diff --git a/kernel/elf.c b/kernel/elf.c index 3829266..9438826 100644 --- a/kernel/elf.c +++ b/kernel/elf.c @@ -19,14 +19,14 @@ extern void jump_to_userspace(); void run_program(uint8_t* code, size_t code_length, uint8_t* data, size_t data_length) { uint8_t* userland_code = (uint8_t*) 0x00000000; - uint8_t* userland_data = (uint8_t*) 0x00800000; + uint8_t* userland_data = (uint8_t*) 0x00400000; memcpy(userland_code, code, code_length); memcpy(userland_data, data, data_length); struct CPUState target = { .eip = (size_t) userland_code, - .esp = 0x00000000, + .esp = 0x00400000, .eax = 0, .ebx = 0, .ecx = 0, diff --git a/kernel/heap.c b/kernel/heap.c index f56eb26..9b52f27 100644 --- a/kernel/heap.c +++ b/kernel/heap.c @@ -3,7 +3,7 @@ #include #include -#define HEAP_SIZE (4096) +#define HEAP_SIZE (1 << 12) uint8_t* global_heap_data[HEAP_SIZE + sizeof(struct Heap_Block)]; struct Heap_Metadata global_heap; diff --git a/kernel/kernel.c b/kernel/kernel.c index c4b0dda..09bbcbe 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -14,13 +14,7 @@ #endif uint8_t program[] = { - // 0xba, 0x01, 0x00, 0x00, 0x00, // mov 1, %edx - 0xb8, 0x00, 0x00, 0xC0, 0x00, // mov $buffer, %eax - // 0xcd, 0x80, // int 0x80 - 0xb9, 0x00, 0x00, 0x00, 0x00, // mov 0, %ecx 0xcd, 0x80, // int 0x80 - 0xb9, 0x00, 0x00, 0x80, 0x00, // mov $start, %ecx - 0xff, 0xe1, // jmp *%ecx }; uint8_t data[] = "Hello From Userspace\n"; @@ -39,11 +33,14 @@ void kernel_main(void) setup_tasks(); setup_paging(); - asm("sti"); + asm("cli"); run_program(program, sizeof(program), data, sizeof(data)); + asm("sti"); + while (true) { - terminal_writestring("Hello from Kernelspace\n"); + terminal_writestring("Hello from Kernelspace 1\n"); + terminal_writestring("Hello from Kernelspace 2\n"); } } diff --git a/kernel/syscall.c b/kernel/syscall.c index 4a48173..84b4c5a 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -25,6 +25,7 @@ static void input(char* buffer) void _syscall(uint32_t a, uint32_t b, uint32_t c) { + /* switch (c) { case 0x00: print((char*) a); @@ -33,4 +34,6 @@ void _syscall(uint32_t a, uint32_t b, uint32_t c) input((char*) a); break; } + */ + terminal_writestring("waow :3"); } diff --git a/kernel/task.c b/kernel/task.c index 64d5e1b..74a8086 100644 --- a/kernel/task.c +++ b/kernel/task.c @@ -159,7 +159,7 @@ void _switch_task( size_t ds_passed ) { - terminal_writestring("Switching task\n"); + // terminal_writestring("Switching task\n"); if (num_tasks == 0) { return; };