From 1bbc9fa0eea6e5daa559535142cb4e62e4bc657e Mon Sep 17 00:00:00 2001 From: Lizzy Fleckenstein Date: Thu, 11 Apr 2024 18:46:48 +0200 Subject: use huge pages --- Makefile | 1 - stage2/paging.asm | 2 +- stage3/heap.c | 28 ----- stage3/heap.h | 3 - stage3/main.c | 68 +++++------ stage3/paging.asm | 343 ------------------------------------------------------ stage3/paging.h | 19 --- 7 files changed, 36 insertions(+), 428 deletions(-) delete mode 100644 stage3/paging.asm delete mode 100644 stage3/paging.h diff --git a/Makefile b/Makefile index eea6f87..646f781 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,6 @@ STAGE3_C = \ STAGE3 = $(STAGE3_C) \ stage3/isr.o \ stage3/yield.o \ - stage3/paging.o \ stage3/watchdog.o PAD_BOUNDARY = pad() { truncate -s $$(echo "($$(du -b $$1 | cut -f1)+$$2-1)/$$2*$$2" | bc) $$1; }; pad diff --git a/stage2/paging.asm b/stage2/paging.asm index cd6ea1c..4e5e2f1 100644 --- a/stage2/paging.asm +++ b/stage2/paging.asm @@ -24,7 +24,7 @@ paging: mov [di], eax add di, 8 add eax, 0x1000 - cmp eax, 0x200000 + cmp eax, 0x400000 jb .build_pt ; enable paging and long mode diff --git a/stage3/heap.c b/stage3/heap.c index 85bb8e9..2c54d8c 100644 --- a/stage3/heap.c +++ b/stage3/heap.c @@ -129,34 +129,6 @@ void heap_add(void *ptr, usize size) kfree(h + 1); } -void heap_add_region(MemRegion *region) -{ - switch (region->used) { - // region is reserved - case -1: - break; - - // region is entirely free - case 0: - heap_add(region->start, region->size); - break; - - // region is partly used - default: { - void *region_end = region->start + region->size; - - // rounds up region->start to pagesize align - void *use_begin = (void *) ((u64) (region->start + PAGESIZE - 1) & ~(PAGESIZE - 1)); - void *use_end = use_begin + region->used; - - heap_add(region->start, use_begin - region->start); - heap_add(use_end, region_end - use_end); - } - } - - region->used = -1; // just to be safe -} - heap_header *heap_get_free_ptr() { return free_ptr; diff --git a/stage3/heap.h b/stage3/heap.h index 10fe261..0b7057b 100644 --- a/stage3/heap.h +++ b/stage3/heap.h @@ -2,12 +2,9 @@ #define HEAP_H #include "def.h" -#include "paging.h" void heap_init(); - void heap_add(void *ptr, usize size); -void heap_add_region(MemRegion *region); void *try_kmalloc(usize size); void *kmalloc(usize siz); diff --git a/stage3/main.c b/stage3/main.c index 5f6756f..e9b5717 100644 --- a/stage3/main.c +++ b/stage3/main.c @@ -1,5 +1,4 @@ #include "def.h" -#include "paging.h" #include "gfx.h" #include "halt.h" #include "heap.h" @@ -18,6 +17,17 @@ #include "rng.h" #include "debug.h" +typedef enum { + MEM_USABLE = 1, + MEM_RESERVED = 2, +} mem_region_type; + +typedef struct __attribute__((packed)) { + void *start; + usize size; + usize type; +} mem_region; + char keymap[256] = { '\0' }; void keyboard_handler() @@ -60,43 +70,35 @@ void keyboard_handler() void kmain() { - heap_init(); + // PML3 + for (u64 page = 0; page < 512*512; page++) + ((u64 *) 0x200000)[page] = (page << 30) | 0b10000011; // bit 7 is for huge pages + + // PML4 + for (u64 tbl = 0; tbl < 512; tbl++) + ((u64 *) 0x1000)[tbl] = (0x200000 + tbl * 0x1000) | 0b11; -#define MMAP for (MemRegion *mreg = (void *) 0x500; mreg->start != nil; mreg++) +#define MMAP for (mem_region *mreg = (void *) 0x500; mreg->start != nil; mreg++) + + // heap init + heap_init(); MMAP { - // remove anything between 0x100000 and 0x200000. it has already been mapped + // remove anything between 0x100000 and 0x400000. it is used for kernel and page tables usize start = (usize) mreg->start; - if (start >= 0x100000 && start < 0x200000) { - if (start + mreg->size <= 0x200000) { + if (start >= 0x100000 && start < 0x400000) { + if (start + mreg->size <= 0x400000) { mreg->size = 0; // kill it } else { - mreg->size = start + mreg->size - 0x200000; - mreg->start = (void *) 0x200000; + mreg->size = start + mreg->size - 0x400000; + mreg->start = (void *) 0x400000; } } - } - // backup memory map - usize n_mreg = 0; - MMAP n_mreg++; - MemRegion mregs[n_mreg]; - { - usize i = 0; - MMAP mregs[i++] = *mreg; + // add to heap + if (mreg->type == MEM_USABLE) // usable + heap_add(mreg->start, mreg->size); } - // setup paging - MMAP page_region(mreg); - - page_region(&(MemRegion) { - .start = (void *) (u64) gfx_info->framebuffer, - .size = gfx_info->pitch * gfx_info->height, - .used = MEM_RESERVED, - }); - - // heap init - MMAP heap_add_region(mreg); - // font init font_init(); font_set_size(1); @@ -106,13 +108,13 @@ void kmain() print(S("welcome to cuddles\n")); // memory map - print(S("memory map:\n")); - for (usize i = 0; i < n_mreg; i++) { - print_num_pad((u64) mregs[i].start, 16, 16, ' '); + print(S("heap memory:\n")); + MMAP { + print_num_pad((u64) mreg->start, 16, 16, ' '); print(S(" | ")); - print_num_pad((u64) mregs[i].start + mregs[i].size, 16, 16, ' '); + print_num_pad((u64) mreg->start + mreg->size, 16, 16, ' '); print(S(" | ")); - print_dec(mregs[i].used); + print_dec(mreg->type); print(S("\n")); } diff --git a/stage3/paging.asm b/stage3/paging.asm deleted file mode 100644 index f58bb98..0000000 --- a/stage3/paging.asm +++ /dev/null @@ -1,343 +0,0 @@ -global page_region -%define PAGEBUFSIZE 0x10 * 0x1000 - -section .bss - -ALIGN(4096) -pagebuf_data: resb PAGEBUFSIZE - -section .data - -pagebuf_init: - .start: dq pagebuf_data - .size: dq PAGEBUFSIZE - .used: dq 0 - -pagebuf: dq pagebuf_init - -next_page: dq 0 - -section .text - -; allocate new page table buffer -alloc: - ; rsi = buffer (result) - ; rdi = next_page - ; r8 = pagebuf - ; rbx = upper - ; rax = tmp; used_next - - mov r8, [pagebuf] ; *pagebuf - mov rsi, [r8] ; start = pagebuf->start - - mov rbx, [r8+8] ; size = pagebuf->size - add rbx, rsi ; upper_have = start + size - - ; round *up* to 0x1000 align - mov rax, 0xfff - add rsi, rax - not rax - and rsi, rax ; aligned_start = (start + 0xfff) & (~0xfff) - - mov rax, [r8+16] ; used = pagebuf->used - add rax, 0x1000 - add rsi, rax ; upper_need = aligned_start + used + 0x1000 - - cmp rsi, rbx ; if upper_need > upper_have - ja .newbuf ; current region is full, get new - - cmp rsi, r10 ; if upper_need >= next_page - jae .oom ; out of memory (target buffer isn't paged yet) - - mov [r8+16], rax ; pagebuf->used = used + 0x1000 - - ; clear out buffer - - mov rbx, rsi - sub rsi, 0x1000 - -.clear: - sub rbx, 8 - mov qword[rbx], 0 - cmp rbx, rsi - jne .clear - - ret - -; select next page buffer -.newbuf: - cmp r8, pagebuf_init - jne .nextbuf - - mov r8, 0x500 - jmp .trybuf - -.nextbuf: - add r8, 24 - -.trybuf: - cmp qword[r8], 0 - je .oom ; last region reached - - mov rax, [r8+16] - - cmp rax, -1 - je .nextbuf ; region is reserved - - cmp rax, 0 - jne .oom ; region has not been paged yet - - mov [pagebuf], r8 - jmp alloc - -.oom: - push rdi - - mov rdi, .oom_msg - ; call print_str - - pop rdi - - ; call print_hex - ; call newline - - jmp $ - -.oom_msg: db "out of memory for page table", 10, "next_page = ", 0 - -; get/create page tables -get_tables: -; level 4 - - ; rdi = address (arg, persist) - ; rax = tmp - ; rbx = mask - ; rcx = bits (persist) - ; rdx = level (persist) - ; r8 = table address - ; rsi = next offset (persist) - - mov cl, 12+9*4 - mov dl, 4 - - mov rsi, 0x1000 - -; level 4 -.level: - dec dl - mov r8, rdi - mov rbx, -1 ; reset remainder mask - shl rbx, cl ; update remainder mask - not rbx ; negate remainder mask - and r8, rbx ; apply remainder mask - - mov al, 9 - mul dl - add al, 12 - mov cl, al - - shr r8, cl ; divide - shl r8, 3 ; multiply by 8 - - mov rbx, 0xfff ; 0x1000 alignment - not rbx ; offset mask - - and rsi, rbx ; apply offset mask - add r8, rsi ; add offset - push r8 ; store - - cmp dl, 0 - je .done - - mov rsi, [r8] ; next offset - cmp rsi, 0 - jne .level - - call alloc - or rsi, 3 - mov r8, [rsp] - mov [r8], rsi - - jmp .level - -.done: - pop r11 - pop r12 - pop r13 - pop r14 - - ret - -space: - mov dil, ' ' - ; jmp print_chr - -page_region: - push rbx - push r12 - push r13 - push r14 - push r15 - - mov r9, rdi - - mov rdi, [r9] ; ptr = mmap_entry->ptr - mov r10, [next_page] - - push rdi - - mov rax, 1 << 63 - - or rdi, rax - ; call print_hex - ; call space - - mov rdi, [r9+8] - add rdi, [rsp] - or rdi, rax - - ; call print_hex - ; call newline - - pop rdi - - ; for usable region (type = 1), set mmap_entry->used = 0 - ; for reserved region (type = 2), set mmap_entry->used = -1 - xor rax, rax - xor rbx, rbx - mov eax, dword[r9+16] - cmp rax, 1 - je .set_used - dec rbx -.set_used: - mov [r9+16], rbx - - mov r10, rdi - mov r15, rdi ; r15 = end of region - add r15, [r9+8] - - mov rax, 0xfff - not rax - and rdi, rax ; round down to 0x1000 aligned - - cmp rdi, r10 - jb .get_tables - - mov r10, rdi - -.get_tables: - call get_tables ; page tables into r11-r14 - - ; start filling L1 map -.l1: - mov rax, rdi - or rax, 3 - mov [r11], rax - - add rdi, 0x1000 - - cmp rdi, r10 - jb .next - - mov r10, rdi - -.next: - cmp rdi, r15 ; if next >= end - jae .done - - ; prepare rcx mask for later - mov rcx, -1 - shl rcx, 3 - - ; bump L1 - - add r11, 8 - mov rax, r11 - and rax, 0xfff - jnz .l1 - - ; bump L2 - - add r12, 8 - mov rax, r12 - and rax, 0xfff - jnz .l2 - - ; bump L3 - - add r13, 8 - mov rax, r13 - and rax, 0xfff - jnz .l3 - - ; bump L4 - - add r14, 8 - mov rax, r14 - and rax, 0xfff - jnz .l4 - - ; machine has more than 256TB of RAM, tell user to fuck off - jmp .bruh - -.l4: - mov r13, [r14] - and r13, rcx - jnz .l3 - - call alloc - mov r13, rsi - or rsi, 3 - mov [r14], rsi - -.l3: - mov r12, [r13] - and r12, rcx - jnz .l2 - - call alloc - mov r12, rsi - or rsi, 3 - mov [r13], rsi - -.l2: - mov r11, [r12] - and r11, rcx - jnz .l2 - - call alloc - mov r11, rsi - or rsi, 3 - mov [r12], rsi - - jmp .l1 - -.done: - mov [next_page], r10 - - pop r15 - pop r14 - pop r13 - pop r12 - pop rbx - - ret - -.bruh: - mov rdi, .bruh_msg - ; call print_str - jmp $ - -.bruh_msg: db "bruh why do you have more than 256TB of RAM (you fucking glow)", 10, 0 - -; identity map available memory -old_page_map: - mov r9, 0x0500 ; mmap_entry -.entry: - cmp qword[r9], 0 - je .done - call page_region - add r9, 24 - jmp .entry -.done: - ret diff --git a/stage3/paging.h b/stage3/paging.h deleted file mode 100644 index 319b297..0000000 --- a/stage3/paging.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef PAGING_H -#define PAGING_H - -#include "def.h" - -typedef enum { - MEM_USABLE = 1, - MEM_RESERVED = 2, -} MemRegionType; - -typedef struct __attribute__((packed)) { - void *start; - usize size; - usize used; -} MemRegion; - -void page_region(MemRegion *region); - -#endif -- cgit v1.2.3