From eaadde5453e33af6826bb03488991aab0297d3dd Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sun, 31 May 2020 20:26:40 +0200 Subject: OMG --- src/kernel/boot.asm | 49 ++++++--------------------------- src/kernel/events/event.c | 5 +--- src/kernel/fs/elf.c | 5 ++-- src/kernel/io/io.c | 2 +- src/kernel/io/io.h | 2 +- src/kernel/kernel.c | 7 +++-- src/kernel/lib/memory.c | 1 - src/kernel/lib/stdio/vprintf.c | 2 +- src/kernel/linker.ld | 20 ++++++-------- src/kernel/memory/alloc.c | 3 +- src/kernel/memory/paging.c | 62 ++++++++++++++---------------------------- src/kernel/memory/paging.h | 4 +-- src/kernel/multiboot.c | 2 +- src/kernel/system.h | 5 ++++ src/kernel/tasks/process.c | 8 +----- 15 files changed, 56 insertions(+), 121 deletions(-) diff --git a/src/kernel/boot.asm b/src/kernel/boot.asm index 6aa5c1a..1e8d3ee 100644 --- a/src/kernel/boot.asm +++ b/src/kernel/boot.asm @@ -1,28 +1,17 @@ bits 32 -; Some variables -kernel_virt_base equ 0xC0000000 -kernel_page_number equ (kernel_virt_base >> 22) kernel_stack equ 0x4000 - -section .data - align 0x1000 - - boot_page_dir: - dd 0x00000083 - times (kernel_page_number - 1) dd 0 - dd 0x00000083 - times (1024 - kernel_page_number - 1) dd 0 +multiboot_magic equ 0xe85250d6 section .text align 4 multiboot: header_start: - dd 0xe85250d6 + dd multiboot_magic dd 0 dd header_end - header_start - dd 0x100000000 - (0xe85250d6 + 0 + (header_end - header_start)) + dd 0x100000000 - (multiboot_magic + 0 + (header_end - header_start)) ; Information tag align 8 @@ -34,12 +23,6 @@ section .text dd 6 ; mmap dd 13 ; smbios - ; Page-align tag - align 8 - dw 6 - dw 0 - dd 8 - ; Empty tag align 8 dw 0 @@ -50,33 +33,17 @@ section .text global boot extern kernel_main boot: - mov ecx, (boot_page_dir - kernel_virt_base) - mov cr3, ecx - - mov ecx, cr4 - or ecx, 0x00000010 - mov cr4, ecx - - mov ecx, cr0 - or ecx, 0x80000000 - mov cr0, ecx - - lea ecx, [higher_half] - jmp ecx - - higher_half: - mov dword [boot_page_dir], 0 - invlpg [0] - - mov esp, stack + kernel_stack + mov esp, stack_top push esp push ebx push eax cli call kernel_main hlt + jmp $ section .bss align 32 - stack: - resb kernel_stack \ No newline at end of file + stack_bottom: + resb kernel_stack + stack_top: \ No newline at end of file diff --git a/src/kernel/events/event.c b/src/kernel/events/event.c index d479ab7..a50e0c7 100644 --- a/src/kernel/events/event.c +++ b/src/kernel/events/event.c @@ -18,10 +18,7 @@ u32 event_map(u32 id, u8 *function) u32 event_trigger(u32 id, u8 *data) { - if (id >= sizeof(event_map) / sizeof(*event_map)) { - panic("Unknown event id!"); - return -1; - } + assert(id < sizeof(event_map) / sizeof(*event_map)); event_func location = (event_func)event_table[id]; if (!location) { diff --git a/src/kernel/fs/elf.c b/src/kernel/fs/elf.c index 2dddc0e..46a4876 100644 --- a/src/kernel/fs/elf.c +++ b/src/kernel/fs/elf.c @@ -30,7 +30,7 @@ struct process *elf_load(char *path) if (current_proc) prev_dir = current_proc->cr3; else - prev_dir = current_page_directory; + prev_dir = page_directory; u8 *file = read_file(path); if (!file) { @@ -73,8 +73,7 @@ struct process *elf_load(char *path) ((void *)((u32)file) + program_header->offset), program_header->filesz); warn("3"); - if (program_header->filesz > PAGE_SIZE) - panic("ELF binary section too large"); + assert(program_header->filesz <= PAGE_SIZE); break; } default: diff --git a/src/kernel/io/io.c b/src/kernel/io/io.c index fd7cd46..801a2fe 100644 --- a/src/kernel/io/io.c +++ b/src/kernel/io/io.c @@ -74,7 +74,7 @@ void outl(u16 port, u32 data) asm volatile("outl %0, %1" ::"a"(data), "Nd"(port)); } -void init_serial() +void serial_install() { outb(0x3f8 + 1, 0x00); outb(0x3f8 + 3, 0x80); diff --git a/src/kernel/io/io.h b/src/kernel/io/io.h index 2d078f1..b5573cc 100644 --- a/src/kernel/io/io.h +++ b/src/kernel/io/io.h @@ -54,7 +54,7 @@ void outl(u16 port, u32 data); /** * Initialize the serial conenction */ -void init_serial(); +void serial_install(); /** * Write a single char to the serial port (QEMU logging) diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index bd22dfc..48525d9 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -40,14 +40,15 @@ void kernel_main(u32 magic, u32 addr, u32 esp) info("Installing basic features of Melvix..."); // Install features + bss_clean(); gdt_install(); - init_serial(); + serial_install(); idt_install(); isrs_install(); irq_install(); - paging_install(multiboot_address); - multiboot_parse(multiboot_address); + paging_install(); + multiboot_parse(); // Install drivers timer_install(); diff --git a/src/kernel/lib/memory.c b/src/kernel/lib/memory.c index 40f6a1f..75f7870 100644 --- a/src/kernel/lib/memory.c +++ b/src/kernel/lib/memory.c @@ -122,7 +122,6 @@ int memory_init() void bss_clean() { - extern u8 bss_start, kernel_end; u32 start = &bss_start; u32 end = &kernel_end; log("0x%x: 0x%x", start, end - start); diff --git a/src/kernel/lib/stdio/vprintf.c b/src/kernel/lib/stdio/vprintf.c index 3c4ecac..5405309 100644 --- a/src/kernel/lib/stdio/vprintf.c +++ b/src/kernel/lib/stdio/vprintf.c @@ -1,6 +1,6 @@ +#include #include #include -#include #include // TODO: Use global formatting function diff --git a/src/kernel/linker.ld b/src/kernel/linker.ld index b7bde1d..a55b13f 100644 --- a/src/kernel/linker.ld +++ b/src/kernel/linker.ld @@ -1,32 +1,28 @@ ENTRY(boot) -phys = 0x100000; -offset = 0xC0000000; -virt = offset + phys; - SECTIONS { - . = virt; + . = 1M; - .text : AT (ADDR (.text) - offset) + .text BLOCK(4K) : ALIGN(4K) { + text_start = .; *(.text) *(.rodata) - . = ALIGN(0x1000); } - .data : AT (ADDR (.data) - offset) + .data BLOCK(4K) : ALIGN(4K) { + data_start = .; *(.data) - . = ALIGN(0x1000); } - .bss : AT (ADDR (.bss) - offset) + .bss BLOCK(4K) : ALIGN(4K) { + bss_start = .; *(.COMMON) *(.bss) - . = ALIGN(0x1000); } - KERNEL_END = .; + kernel_end = .; } \ No newline at end of file diff --git a/src/kernel/memory/alloc.c b/src/kernel/memory/alloc.c index 904be3a..d1d8b47 100644 --- a/src/kernel/memory/alloc.c +++ b/src/kernel/memory/alloc.c @@ -162,8 +162,7 @@ static struct liballoc_major *allocate_new_page(u32 size) void *malloc(u32 req_size) { - if (!paging_enabled) - warn("Mallocing while paging is disabled!"); + assert(paging_enabled); int started_bet = 0; u64 best_size = 0; diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index fd5ae3b..432b51c 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -4,55 +4,34 @@ #include #include -u32 **current_page_directory; -u32 kernel_page_directory[PAGE_COUNT] __attribute__((aligned(PAGE_ALIGN))); -u32 kernel_page_tables[PAGE_COUNT][PAGE_COUNT] __attribute__((aligned(PAGE_ALIGN))); -u32 *temp_dir[PAGE_COUNT] __attribute__((aligned(PAGE_ALIGN))); +u32 page_directory[1024] __attribute__((aligned(4096))); +u32 page_tables[1024][1024] __attribute__((aligned(4096))); -void paging_init(u32 **dir) +void paging_init() { for (u32 i = 0; i < PAGE_COUNT; i++) { for (u32 j = 0; j < PAGE_COUNT; j++) { - dir[i][j] = ((j * PAGE_ALIGN) + (i * PAGE_SIZE)) | PT_RW | PT_USER; + page_tables[i][j] = ((j * PAGE_ALIGN) + (i * PAGE_SIZE)) | PT_RW | PT_USER; } } for (u32 i = 0; i < PAGE_COUNT; i++) { - dir[i] = ((u32)dir[i]) | PD_RW | PD_PRESENT | PD_USER; + page_directory[i] = (u32)page_tables[i] | PD_RW | PD_PRESENT | PD_USER; } } -void paging_kernel_init(u32 *dir) -{ - for (u32 i = 0; i < PAGE_COUNT; i++) { - for (u32 j = 0; j < PAGE_COUNT; j++) { - kernel_page_tables[i][j] = ((j * PAGE_ALIGN) + (i * PAGE_SIZE)) | PT_RW; - } - } - - for (u32 i = 0; i < PAGE_COUNT; i++) { - kernel_page_directory[i] = ((u32)kernel_page_tables[i]) | PD_RW | PD_PRESENT; - } - - current_page_directory = temp_dir; - for (int i = 0; i < PAGE_COUNT; i++) { - current_page_directory[i] = kernel_page_tables[i]; - for (int j = 0; j < PAGE_COUNT; j++) { - current_page_directory[i][j] = kernel_page_tables[i][j]; - } - } -} - -extern void KERNEL_END(); void paging_install() { - paging_switch_directory((u32 **)kernel_page_directory); - paging_kernel_init(kernel_page_directory); + paging_init(); if (!memory_init()) paging_set_present(0, memory_get_all() >> 3); - paging_set_used(0, ((u32)KERNEL_END >> 12) + 1); + paging_set_used(0, ((u32)&kernel_end >> 12) + 1); + u32 cr4; + asm volatile("mov %%cr4, %0" : "=r"(cr4)); + cr4 &= 0xffffffef; + asm volatile("mov %0, %%cr4" ::"r"(cr4)); paging_enable(); log("Installed paging"); @@ -99,6 +78,7 @@ void paging_disable() void paging_enable() { + asm("mov %0, %%cr3" ::"r"(page_directory)); u32 cr0; asm("mov %%cr0, %0" : "=r"(cr0)); cr0 |= 0x80000000; @@ -108,8 +88,7 @@ void paging_enable() void paging_switch_directory(u32 **dir) { - current_page_directory = dir; - asm("mov %0, %%cr3" ::"r"(current_page_directory)); + asm("mov %0, %%cr3" ::"r"(dir)); } void invlpg(u32 addr) @@ -121,7 +100,7 @@ void paging_map(u32 phy, u32 virt, u16 flags) { u32 pdi = virt >> 22; u32 pti = virt >> 12 & 0x03FF; - current_page_directory[pdi][pti] = phy | flags; + page_tables[pdi][pti] = phy | flags; invlpg(virt); } @@ -129,21 +108,21 @@ u32 paging_get_phys(u32 virt) { u32 pdi = virt >> 22; u32 pti = (virt >> 12) & 0x03FF; - return current_page_directory[pdi][pti] & 0xFFFFF000; + return page_tables[pdi][pti] & 0xFFFFF000; } u16 paging_get_flags(u32 virt) { u32 pdi = virt >> 22; u32 pti = (virt >> 12) & 0x03FF; - return current_page_directory[pdi][pti] & 0xFFF; + return page_tables[pdi][pti] & 0xFFF; } void paging_set_flag_up(u32 virt, u32 count, u32 flag) { u32 page_n = virt / PAGE_ALIGN; for (u32 i = page_n; i < page_n + count; i++) { - current_page_directory[i / PAGE_COUNT][i % PAGE_COUNT] |= flag; + page_tables[i / PAGE_COUNT][i % PAGE_COUNT] |= flag; invlpg(i * PAGE_ALIGN); } } @@ -152,7 +131,7 @@ void paging_set_flag_down(u32 virt, u32 count, u32 flag) { u32 page_n = virt / PAGE_ALIGN; for (u32 i = page_n; i < page_n + count; i++) { - current_page_directory[i / PAGE_COUNT][i % PAGE_COUNT] &= ~flag; + page_tables[i / PAGE_COUNT][i % PAGE_COUNT] &= ~flag; invlpg(i * PAGE_ALIGN); } } @@ -184,8 +163,7 @@ u32 paging_find_pages(u32 count) u32 start_page = 0; for (u32 i = 0; i < PAGE_COUNT; i++) { for (u32 j = 0; j < PAGE_COUNT; j++) { - if (!(current_page_directory[i][j] & PT_PRESENT) || - (current_page_directory[i][j] & PT_USED)) { + if (!(page_tables[i][j] & PT_PRESENT) || (page_tables[i][j] & PT_USED)) { continuous = 0; start_dir = i; start_page = j + 1; @@ -212,7 +190,7 @@ u32 paging_get_used_pages() u32 n = 0; for (u32 i = 0; i < PAGE_COUNT; i++) { for (u32 j = 0; j < PAGE_COUNT; j++) { - u8 flags = current_page_directory[i][j] & PT_USED; + u8 flags = page_tables[i][j] & PT_USED; if (flags == 1) n++; } diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index 3d3b176..b7ea07a 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -25,8 +25,7 @@ #define PT_GLOBAL 1 << 8 #define PT_USED 1 << 9 -u32 **current_page_directory; -u32 kernel_page_directory[1024] __attribute__((aligned(4096))); +u32 page_directory[1024] __attribute__((aligned(4096))); int paging_enabled; void paging_install(); @@ -34,6 +33,7 @@ void paging_enable(); void paging_disable(); u32 **paging_make_directory(); +void paging_remove_directory(u32 **dir); void paging_switch_directory(u32 **dir); void paging_map(u32 phy, u32 virt, u16 flags); diff --git a/src/kernel/multiboot.c b/src/kernel/multiboot.c index f7ac876..8bc5242 100644 --- a/src/kernel/multiboot.c +++ b/src/kernel/multiboot.c @@ -7,7 +7,7 @@ #include #include -void multiboot_parse(u32 multiboot_address) +void multiboot_parse() { struct multiboot_tag *tag; diff --git a/src/kernel/system.h b/src/kernel/system.h index 785aa9b..3972151 100644 --- a/src/kernel/system.h +++ b/src/kernel/system.h @@ -5,7 +5,12 @@ #include #include +// Passed by low level things u32 multiboot_address; +extern u32 text_start; +extern u32 data_start; +extern u32 bss_start; +extern u32 kernel_end; /** * The ASM registers as packed structure diff --git a/src/kernel/tasks/process.c b/src/kernel/tasks/process.c index e11cfee..5f70bc7 100644 --- a/src/kernel/tasks/process.c +++ b/src/kernel/tasks/process.c @@ -136,8 +136,7 @@ void process_suspend(u32 pid) { debug("Suspending process %d", pid); process_print_tree(); - if (pid == 1) - panic("Root process died"); + assert(pid != 1); struct process *proc = process_from_pid(pid); @@ -184,12 +183,7 @@ struct process *process_make_new() proc->registers.ds = 0x23; proc->registers.ss = 0x23; proc->cr3 = paging_make_directory(); - proc->brk = 0x50000000; - - for (int i = 0; i < 1024; i++) - proc->cr3[i] = kernel_page_directory[i]; - proc->pid = pid++; return proc; } -- cgit v1.2.3