From 9f142941c380b5a7a5aa7a92f65b8f9020e67a96 Mon Sep 17 00:00:00 2001 From: 0x35c <> Date: Wed, 12 Nov 2025 16:02:52 +0100 Subject: [PATCH] wip: separate allocators into a kernel one and a user one --- headers/memory.h | 6 +- src/interrupt/handler.c | 2 - src/kpanic.c | 8 +-- src/memory/{phys => kern}/allocator.c | 6 +- src/memory/{phys => kern}/info.c | 0 src/memory/{phys => kern}/kfree.c | 2 +- src/memory/{phys => kern}/kmalloc.c | 0 src/memory/{phys => kern}/krealloc.c | 0 src/memory/{phys => kern}/ksize.c | 0 src/memory/kern/page.c | 92 +++++++++++++++++++++++++++ src/memory/load_pd.s | 19 +++--- src/memory/memory.c | 2 +- src/memory/page_directory.c | 2 +- src/memory/page_table.c | 3 +- src/memory/paging.s | 21 +++--- src/memory/virt/allocator.c | 5 +- src/memory/{ => virt}/page.c | 5 +- src/memory/virt/vfree.c | 2 +- src/multiboot.c | 4 +- src/multitasking/fork.c | 2 +- src/multitasking/process.c | 10 +-- src/multitasking/thread.c | 14 ++-- 22 files changed, 149 insertions(+), 56 deletions(-) rename src/memory/{phys => kern}/allocator.c (94%) rename src/memory/{phys => kern}/info.c (100%) rename src/memory/{phys => kern}/kfree.c (98%) rename src/memory/{phys => kern}/kmalloc.c (100%) rename src/memory/{phys => kern}/krealloc.c (100%) rename src/memory/{phys => kern}/ksize.c (100%) create mode 100644 src/memory/kern/page.c rename src/memory/{ => virt}/page.c (93%) diff --git a/headers/memory.h b/headers/memory.h index a46420a..6316a2e 100644 --- a/headers/memory.h +++ b/headers/memory.h @@ -59,8 +59,10 @@ void init_memory(multiboot_info_t *mbd, uint32_t magic); void *alloc_frame(void); int free_frame(void *frame_ptr); int8_t add_single_page(void *frame); -void *alloc_pages(size_t size, void **phys_addr); -int free_pages(void *page_ptr, size_t size); +void *kalloc_pages(size_t size, void **phys_addr); +void *valloc_pages(size_t size, void **phys_addr); +int kfree_pages(void *page_ptr, size_t size); +int vfree_pages(void *page_ptr, size_t size); void init_page_table(uint32_t page_table[1024], uint16_t start); int16_t add_page_table(uint16_t pd_index); void switch_pd(uint32_t *pd, uint32_t *cr3); diff --git a/src/interrupt/handler.c b/src/interrupt/handler.c index 1ab1436..8b77f9c 100644 --- a/src/interrupt/handler.c +++ b/src/interrupt/handler.c @@ -36,8 +36,6 @@ void isr_handler(struct registers *regs) { uint8_t i = 0; while (i < ARRAY_SIZE(faults)) { - if (i == 6) - reboot(); if (i == regs->int_no) kpanic("interrupt: %s\n", faults[i]); i++; diff --git a/src/kpanic.c b/src/kpanic.c index 9ff1f7a..31637c2 100644 --- a/src/kpanic.c +++ b/src/kpanic.c @@ -23,10 +23,10 @@ __attribute__((noreturn)) void kpanic(const char *format, ...) va_end(va); uint32_t faulting_address; - // __asm__ __volatile__("mov %%cr2, %0" : "=r"(faulting_address)); - // kprintf("fault at address: %p\n", faulting_address); - /* for (int i = 16; i < 32; i++) */ - /* kprintf("%p\n", page_table1[i]); */ + __asm__ __volatile__("mov %%cr2, %0" : "=r"(faulting_address)); + kprintf("fault at address: %p\n", faulting_address); + // for (int i = 16; i < 32; i++) + // kprintf("%p\n", page_table1[i]); // show_valloc_mem(); /* kprintf("\n\n"); */ /* print_stack(); */ diff --git a/src/memory/phys/allocator.c b/src/memory/kern/allocator.c similarity index 94% rename from src/memory/phys/allocator.c rename to src/memory/kern/allocator.c index 560ff75..cfb905e 100644 --- a/src/memory/phys/allocator.c +++ b/src/memory/kern/allocator.c @@ -1,9 +1,8 @@ #include "alloc.h" #include "assert.h" -#include "kpanic.h" #include "kprintf.h" #include "memory.h" -#include "process.h" +#include "string.h" Zone *kzones[3]; @@ -50,11 +49,12 @@ static void new_block(Zone *zone, uint32_t zone_size) int new_kzone(block_type_t type, uint32_t size) { // assert(current_task->pid); - void *heap = alloc_frame(); + void *heap = kalloc_pages(size, NULL); if (heap == NULL) { kprintf(KERN_ERR "error: alloc_frame failed\n"); return (-1); } + memset(heap, 0, size); Zone *zone = (Zone *)heap; zone->type = type; diff --git a/src/memory/phys/info.c b/src/memory/kern/info.c similarity index 100% rename from src/memory/phys/info.c rename to src/memory/kern/info.c diff --git a/src/memory/phys/kfree.c b/src/memory/kern/kfree.c similarity index 98% rename from src/memory/phys/kfree.c rename to src/memory/kern/kfree.c index 6002bc3..7d52c8f 100644 --- a/src/memory/phys/kfree.c +++ b/src/memory/kern/kfree.c @@ -47,7 +47,7 @@ static int unmap_zone(Zone *zone) if (right) right->prev = left; unmap: - err = free_pages((void *)zone, zone->size); + err = kfree_pages((void *)zone, zone->size); if (err) kprintf(KERN_ERR "error: munmap failed\n"); return (err); diff --git a/src/memory/phys/kmalloc.c b/src/memory/kern/kmalloc.c similarity index 100% rename from src/memory/phys/kmalloc.c rename to src/memory/kern/kmalloc.c diff --git a/src/memory/phys/krealloc.c b/src/memory/kern/krealloc.c similarity index 100% rename from src/memory/phys/krealloc.c rename to src/memory/kern/krealloc.c diff --git a/src/memory/phys/ksize.c b/src/memory/kern/ksize.c similarity index 100% rename from src/memory/phys/ksize.c rename to src/memory/kern/ksize.c diff --git a/src/memory/kern/page.c b/src/memory/kern/page.c new file mode 100644 index 0000000..51cb559 --- /dev/null +++ b/src/memory/kern/page.c @@ -0,0 +1,92 @@ +#include +#include +#include + +#include "assert.h" +#include "kprintf.h" +#include "memory.h" +#include "process.h" +#include "string.h" +#include "utils.h" + +static int16_t find_next_block(size_t nb_pages, uint16_t *pd_index_ptr, + uint32_t **page_table_ptr) +{ + + for (*pd_index_ptr = 769; *pd_index_ptr < 1021; (*pd_index_ptr)++) { + if (current_pd[(*pd_index_ptr)] == 0x02) { + if (add_page_table(*pd_index_ptr) < 0) + return -2; + } + *page_table_ptr = (uint32_t *)GET_PAGE_ADDR(769, *pd_index_ptr); + for (uint16_t i = 0; i + nb_pages - 1 < PT_SIZE; i++) { + uint16_t j; + for (j = 0; (*page_table_ptr)[i + j] >> 12 == i + j && + j < nb_pages; + j++) + ; + if (j == nb_pages) + return i; + i += j; + } + } + return -1; +} + +void *kalloc_pages(size_t size, void **phys_addr) +{ + const uint32_t nb_pages = CEIL(size, PAGE_SIZE); + uint16_t pd_index; + uint32_t *page_table; + const int16_t index = find_next_block(nb_pages, &pd_index, &page_table); + + if (index < 0) { + kprintf(KERN_CRIT "%d: Not enough pages (max: %d)\n", index, + PT_SIZE); + return NULL; + } + for (size_t i = index; i - (size_t)index < nb_pages; i++) { + void *frame = alloc_frame(); + if (!frame) { + for (size_t j = index; j < i; j++) + free_frame((void *)(page_table[j] & PAGE_MASK)); + return NULL; + } + if (phys_addr) + *phys_addr = frame; + page_table[i] = ((uint32_t)frame & PAGE_MASK) | INIT_FLAGS; + } + return (void *)GET_PAGE_ADDR(pd_index, index); +} + +int kfree_pages(void *page_ptr, size_t size) +{ + const uint32_t page_addr = (uint32_t)page_ptr; + const uint32_t nb_pages = CEIL(size, PAGE_SIZE); + const uint32_t page_index = page_addr / PAGE_SIZE; + const uint32_t pd_index = page_index / PD_SIZE; + const uint32_t pt_index = page_index % PD_SIZE; + + if ((uint32_t)pd_index > 0x300) { + kprintf(KERN_WARNING "Address out of range\n"); + return -1; + } else if (page_addr % PAGE_SIZE) { + kprintf(KERN_WARNING "Invalid address\n"); + return -1; + } else if (pt_index + nb_pages > PT_SIZE) { + kprintf(KERN_WARNING "Invalid number of frames\n"); + return -1; + } + uint32_t *page_table = + (uint32_t *)GET_PAGE_ADDR(0, PT_START + pd_index); + for (uint16_t i = pt_index; i < pt_index + nb_pages; i++) { + if (page_table[i] >> 12 == i) { + kprintf(KERN_WARNING "Page already free\n"); + return -2; + } + free_frame((void *)(page_table[i] & PAGE_MASK)); + page_table[i] = i << 12; + } + + return 0; +} diff --git a/src/memory/load_pd.s b/src/memory/load_pd.s index bffd31d..ec340f8 100644 --- a/src/memory/load_pd.s +++ b/src/memory/load_pd.s @@ -1,12 +1,13 @@ .intel_syntax noprefix -.text -.global load_page_directory +.section .text + .global load_page_directory + load_page_directory: -push ebp -mov ebp, esp -mov eax, [esp + 8] -mov cr3, eax -mov esp, ebp -pop ebp -ret + push ebp + mov ebp, esp + mov eax, [esp + 8] + mov cr3, eax + mov esp, ebp + pop ebp + ret diff --git a/src/memory/memory.c b/src/memory/memory.c index 1aebc63..6ae92d7 100644 --- a/src/memory/memory.c +++ b/src/memory/memory.c @@ -113,7 +113,7 @@ static void init_frame_zones(void) void init_memory(multiboot_info_t *mbd, uint32_t magic) { - for (uint16_t i = 0; i < 0x300; i++) + for (uint16_t i = 769; i < 1021; i++) kernel_pd[i] = 0x02; init_page_table(page_table_default, 0); kernel_pd[0] = ((uint32_t)page_table_default - HEAP_END) | 0x03; diff --git a/src/memory/page_directory.c b/src/memory/page_directory.c index 1699b9b..3e96b0a 100644 --- a/src/memory/page_directory.c +++ b/src/memory/page_directory.c @@ -4,4 +4,4 @@ void init_page_directory(uint32_t page_directory[1024]) { for (uint16_t i = 0; i < 0x300; i++) page_directory[i] = 0x02; -} \ No newline at end of file +} diff --git a/src/memory/page_table.c b/src/memory/page_table.c index 9085ca3..916830a 100644 --- a/src/memory/page_table.c +++ b/src/memory/page_table.c @@ -1,6 +1,5 @@ -#include "assert.h" -#include "kprintf.h" #include "memory.h" + void init_page_table(uint32_t page_table[1024], uint16_t start) { for (uint16_t i = start; i < 1024; i++) diff --git a/src/memory/paging.s b/src/memory/paging.s index 10d62d3..354fd8c 100644 --- a/src/memory/paging.s +++ b/src/memory/paging.s @@ -1,13 +1,14 @@ .intel_syntax noprefix -.text -.global enable_paging +.section .text + .global enable_paging + enable_paging: -push ebp -mov ebp, esp -mov eax, cr0 -or eax, 0x80000000 -mov cr0, eax -mov esp, ebp -pop ebp -ret + push ebp + mov ebp, esp + mov eax, cr0 + or eax, 0x80000000 + mov cr0, eax + mov esp, ebp + pop ebp + ret diff --git a/src/memory/virt/allocator.c b/src/memory/virt/allocator.c index 853cce0..13f7652 100644 --- a/src/memory/virt/allocator.c +++ b/src/memory/virt/allocator.c @@ -3,7 +3,7 @@ #include "kpanic.h" #include "kprintf.h" #include "memory.h" -#include "process.h" +#include "string.h" Zone *vzones[3]; @@ -50,11 +50,12 @@ static void new_block(Zone *zone, uint32_t zone_size) int new_vzone(block_type_t type, uint32_t size) { // assert(current_task->pid); - void *heap = alloc_pages(size, NULL); + void *heap = valloc_pages(size, NULL); if (heap == NULL) { kprintf(KERN_ERR "error: alloc_pages failed\n"); return (-1); } + memset(heap, 0, size); Zone *zone = (Zone *)heap; zone->type = type; diff --git a/src/memory/page.c b/src/memory/virt/page.c similarity index 93% rename from src/memory/page.c rename to src/memory/virt/page.c index 7a2c412..0c49f05 100644 --- a/src/memory/page.c +++ b/src/memory/virt/page.c @@ -33,7 +33,7 @@ static int16_t find_next_block(size_t nb_pages, uint16_t *pd_index_ptr, return -1; } -void *alloc_pages(size_t size, void **phys_addr) +void *valloc_pages(size_t size, void **phys_addr) { const uint32_t nb_pages = CEIL(size, PAGE_SIZE); uint16_t pd_index; @@ -56,11 +56,10 @@ void *alloc_pages(size_t size, void **phys_addr) *phys_addr = frame; page_table[i] = ((uint32_t)frame & PAGE_MASK) | INIT_FLAGS; } - memset((void *)GET_PAGE_ADDR(pd_index, index), 0, nb_pages * PAGE_SIZE); return (void *)GET_PAGE_ADDR(pd_index, index); } -int free_pages(void *page_ptr, size_t size) +int vfree_pages(void *page_ptr, size_t size) { const uint32_t page_addr = (uint32_t)page_ptr; const uint32_t nb_pages = CEIL(size, PAGE_SIZE); diff --git a/src/memory/virt/vfree.c b/src/memory/virt/vfree.c index 70a3dcf..36bff8c 100644 --- a/src/memory/virt/vfree.c +++ b/src/memory/virt/vfree.c @@ -47,7 +47,7 @@ static int unmap_zone(Zone *zone) if (right) right->prev = left; unmap: - err = free_pages((void *)zone, zone->size); + err = vfree_pages((void *)zone, zone->size); if (err) kprintf(KERN_ERR "error: munmap failed\n"); return (err); diff --git a/src/multiboot.c b/src/multiboot.c index ee9ec16..32fff32 100644 --- a/src/multiboot.c +++ b/src/multiboot.c @@ -38,8 +38,8 @@ static void init_vbe(multiboot_info_t *mbd_virt) ((mbd_virt->framebuffer_addr + i * PAGE_SIZE) & PAGE_MASK) | INIT_FLAGS; } - kernel_pd[800] = ((uint32_t)vbe_page_table - HEAP_END) | 0x03; - display.buff = (uint32_t *)GET_PAGE_ADDR(800, 0) + + kernel_pd[1021] = ((uint32_t)vbe_page_table - HEAP_END) | 0x03; + display.buff = (uint32_t *)GET_PAGE_ADDR(1021, 0) + (mbd_virt->framebuffer_addr % PAGE_SIZE); display.height = mbd_virt->framebuffer_height; display.width = mbd_virt->framebuffer_width; diff --git a/src/multitasking/fork.c b/src/multitasking/fork.c index 6a11c5b..e9d583c 100644 --- a/src/multitasking/fork.c +++ b/src/multitasking/fork.c @@ -10,7 +10,7 @@ static struct tcb *thread_clone(struct tcb *thread) if (!new_tcb) return NULL; new_tcb->tid = thread->tid; - new_tcb->esp0 = alloc_pages(STACK_SIZE, NULL); + new_tcb->esp0 = kalloc_pages(STACK_SIZE, NULL); if (!new_tcb->esp0) { delete_thread(new_tcb); return NULL; diff --git a/src/multitasking/process.c b/src/multitasking/process.c index eac4a0c..775fda0 100644 --- a/src/multitasking/process.c +++ b/src/multitasking/process.c @@ -9,16 +9,16 @@ struct pcb *create_process(uid_t uid) { static pid_t pid = 1; - struct pcb *new_pcb = vmalloc(sizeof(struct pcb)); + struct pcb *new_pcb = kmalloc(sizeof(struct pcb)); if (!new_pcb) return NULL; new_pcb->uid = uid; new_pcb->pid = pid++; new_pcb->tid = 1; - new_pcb->heap = alloc_pages(4096, &new_pcb->cr3); + new_pcb->heap = kalloc_pages(4096, &new_pcb->cr3); if (!new_pcb->heap) { - vfree(new_pcb); + kfree(new_pcb); return NULL; } memcpy(new_pcb->heap, current_pd, 4096); @@ -48,8 +48,8 @@ void remove_process(struct pcb *pcb) struct pcb *left = pcb->prev; struct pcb *right = pcb->next; if (pcb->heap) - free_pages(pcb->heap, 4096); + kfree_pages(pcb->heap, 4096); left->next = right; right->prev = left; - vfree(pcb); + kfree(pcb); } diff --git a/src/multitasking/thread.c b/src/multitasking/thread.c index 1f8d4e7..978da94 100644 --- a/src/multitasking/thread.c +++ b/src/multitasking/thread.c @@ -10,12 +10,12 @@ struct tcb *create_thread(struct pcb *process, void (*entry)(void)) { - struct tcb *new_tcb = vmalloc(sizeof(struct tcb)); + struct tcb *new_tcb = kmalloc(sizeof(struct tcb)); if (!new_tcb) return NULL; new_tcb->tid = process->tid++; - new_tcb->esp0 = alloc_pages(STACK_SIZE, NULL); + new_tcb->esp0 = kalloc_pages(STACK_SIZE, NULL); if (!new_tcb->esp0) { vfree(new_tcb); return NULL; @@ -46,9 +46,9 @@ struct tcb *create_thread(struct pcb *process, void (*entry)(void)) new_tcb->process = process; new_tcb->state = NEW; - struct list *new_node = vmalloc(sizeof(struct list)); + struct list *new_node = kmalloc(sizeof(struct list)); if (!new_node) { - free_pages(new_tcb->esp0, STACK_SIZE); + kfree_pages(new_tcb->esp0, STACK_SIZE); vfree(new_tcb); return NULL; } @@ -68,13 +68,13 @@ struct tcb *create_thread(struct pcb *process, void (*entry)(void)) void delete_thread(struct tcb *thread) { - vfree(thread->esp0); + kfree(thread->esp0); struct list *it = thread->process->thread_list; assert(it); while (it->next && it->next->content != thread) it = it->next; struct list *to_free = it; it->next = it->next->next; - vfree(to_free); - vfree(thread); + kfree(to_free); + kfree(thread); }