From f5147e78f91b4a48fafc953ea9774f1ba840d901 Mon Sep 17 00:00:00 2001 From: 0x35c Date: Mon, 21 Oct 2024 16:29:50 +0200 Subject: [PATCH] wip: page_tables allocation --- headers/memory.h | 10 ++++++++- src/kernel.c | 30 +++++++++++++------------ src/memory/frame.c | 2 +- src/memory/memory.c | 20 ++++++++++++----- src/memory/page.c | 44 +++++++++++++++++++++---------------- src/memory/virt/allocator.c | 3 +-- 6 files changed, 67 insertions(+), 42 deletions(-) diff --git a/headers/memory.h b/headers/memory.h index 1344129..9003366 100644 --- a/headers/memory.h +++ b/headers/memory.h @@ -1,6 +1,7 @@ #pragma once #include +#include #define PRESENT (1 << 0) #define RW (1 << 1) @@ -8,11 +9,18 @@ #define ACCESSED (1 << 4) #define INIT_FLAGS (PRESENT | RW | SUPERVISOR) #define PAGE_SIZE 4096 +#define PT_SIZE 1024 +#define PD_SIZE 1024 #define PAGE_MASK 0xFFFFF000 #define HEAP_END 0xC0000000 +extern uint32_t boot_page_directory; +extern uint32_t *page_directory; +extern uint32_t page_table_default[1024]; + +uint32_t *virt_to_phys(uint32_t *virt_addr); void init_memory(void); void *alloc_frames(size_t size); int free_frames(void *frame_ptr, size_t size); -void *alloc_pages(size_t size); +void *alloc_pages(size_t size, uint32_t **frame_ptr); int free_pages(void *page_ptr, size_t size); diff --git a/src/kernel.c b/src/kernel.c index 29d6766..624c74a 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -40,19 +40,21 @@ void kernel_main(void) /* strcpy(str, "hello"); */ /* int i = 0; */ /* while (vmalloc(10)) */ - /* if (i++ > 11000) */ - /* kprintf("str: %s at %d\n", str, i); */ - void *tab[1024]; - for (int i = 0; i < 1024; i++) { - tab[i] = alloc_pages(1); - /* PRINT_INT(i); */ - /* PRINT_PTR(tab[i]); */ - if (tab[i]) - memset(tab[i], i, 4096); - } + /* ; */ + /* if (i++ > 70000) */ + /* kprintf("%d\n", i); */ + /* void *tab[1024]; */ + /* for (int i = 0; i < 1023; i++) { */ + /* tab[i] = alloc_pages(1); */ + /* PRINT_INT(i); */ + /* PRINT_PTR(tab[i]); */ + /* if (!tab[i]) */ + /* break; */ + /* memset(tab[i], i, 4096); */ + /* } */ /* PRINT_UINT(((uint8_t *)tab[0])[0]); */ - for (int i = 0; i < 10; i++) - PRINT_PTR(tab[i]); - /* PRINT_UINT(((uint8_t *)tab[i])[0]); */ - shell_init(); + /* for (int i = 0; i < 10; i++) */ + /* PRINT_UINT(((uint8_t *)tab[i])[0]); */ + /* PRINT_PTR(tab[i]); */ + /* shell_init(); */ } diff --git a/src/memory/frame.c b/src/memory/frame.c index ad256c2..184bae1 100644 --- a/src/memory/frame.c +++ b/src/memory/frame.c @@ -14,7 +14,7 @@ static uint32_t remaining_frames = MAX_FRAMES; static int32_t find_next_block(size_t nb_frames) { - for (uint32_t i = 1; i + nb_frames < MAX_FRAMES - 1; i++) { + for (uint32_t i = 1024; i + nb_frames < MAX_FRAMES - 1; i++) { uint32_t j; for (j = 0; frame_table[i + j] == 0 && j < nb_frames; j++) ; diff --git a/src/memory/memory.c b/src/memory/memory.c index c035774..8ecbe9b 100644 --- a/src/memory/memory.c +++ b/src/memory/memory.c @@ -1,13 +1,22 @@ #include "memory.h" #include "debug.h" #include "kprintf.h" -#include "string.h" #include -extern uint32_t boot_page_directory; uint32_t *page_directory = &boot_page_directory; -uint32_t page_table1[1024] __attribute__((aligned(4096))); +uint32_t page_table_default[1024] __attribute__((aligned(4096))); + +static void alloc_page_tables(void) +{ + uint32_t *frame_ptr = NULL; + for (int16_t i = 1; i < 768; i++) { + uint32_t *page_table = alloc_pages(PAGE_SIZE, &frame_ptr); + for (int16_t j = 0; j < 1024; j++) + page_table[j] = j << 12 | 0x03; + page_directory[i] = ((uint32_t)frame_ptr & PAGE_MASK) | 0x03; + } +} void init_memory(void) { @@ -15,6 +24,7 @@ void init_memory(void) for (int16_t i = 0; i < 0x300; i++) page_directory[i] = 0x02; for (int16_t i = 0; i < 1024; i++) - page_table1[i] = (i << 12) | 0x03; - page_directory[342] = ((uint32_t)page_table1 - HEAP_END) | 0x03; + page_table_default[i] = (i << 12) | 0x03; + page_directory[0] = ((uint32_t)page_table_default - HEAP_END) | 0x03; + alloc_page_tables(); } diff --git a/src/memory/page.c b/src/memory/page.c index c2138ad..421b4fe 100644 --- a/src/memory/page.c +++ b/src/memory/page.c @@ -7,26 +7,30 @@ #include "memory.h" #include "utils.h" -#define PT_SIZE 1024 #define MAX_TLB_ENTRIES 32 -extern uint32_t page_table1[PT_SIZE]; +static uint32_t *current_page_table; static int16_t find_next_block(size_t nb_pages) { - for (uint16_t i = 1; i + nb_pages < PT_SIZE - 1; i++) { - uint16_t j; - for (j = 0; page_table1[i + j] >> 12 == i + j && j < nb_pages; - j++) - ; - if (j == nb_pages) - return i; - i += j; + for (uint16_t pd_index = 0; pd_index < 768; pd_index++) { + current_page_table = + (uint32_t *)(page_directory[pd_index] >> 12); + for (uint16_t i = 0; i + nb_pages < PT_SIZE; i++) { + uint16_t j; + for (j = 0; current_page_table[i + j] >> 12 == i + j && + j < nb_pages; + j++) + ; + if (j == nb_pages) + return i; + i += j; + } } return -1; } -void *alloc_pages(size_t size) +void *alloc_pages(size_t size, uint32_t **frame_ptr) { const uint32_t nb_pages = CEIL(size, PAGE_SIZE); const int16_t index = find_next_block(nb_pages); @@ -39,15 +43,17 @@ void *alloc_pages(size_t size) void *frame = alloc_frames(PAGE_SIZE); if (!frame) { for (size_t j = index; j < i; j++) - free_frames((void *)(page_table1[j] >> 12), - PAGE_SIZE); + free_frames( + (void *)(current_page_table[j] >> 12), + PAGE_SIZE); return NULL; } - /* assert(page_table1[i] >> 12 == i); */ - page_table1[i] = ((uint32_t)frame & PAGE_MASK) | INIT_FLAGS; + if (frame_ptr) + *frame_ptr = frame; + current_page_table[i] = + ((uint32_t)frame & PAGE_MASK) | INIT_FLAGS; } - /* PRINT_PTR(page_table1[index]); */ - return (void *)(index * PAGE_SIZE); + return (void *)((0 * 1024 + index) * PAGE_SIZE); } int free_pages(void *page_ptr, size_t size) @@ -66,8 +72,8 @@ int free_pages(void *page_ptr, size_t size) return -1; } for (size_t i = page_index; i < page_index + nb_pages; i++) { - free_frames((void *)(page_table1[i] >> 12), PAGE_SIZE); - page_table1[i] = i << 12 | INIT_FLAGS; + free_frames((void *)(current_page_table[i] >> 12), PAGE_SIZE); + current_page_table[i] = i << 12 | INIT_FLAGS; } return 0; } diff --git a/src/memory/virt/allocator.c b/src/memory/virt/allocator.c index b4c6751..bd5e085 100644 --- a/src/memory/virt/allocator.c +++ b/src/memory/virt/allocator.c @@ -49,12 +49,11 @@ static void new_block(Zone *zone, uint32_t zone_size) int new_vzone(block_type_t type, uint32_t size) { - void *heap = alloc_pages(size); + void *heap = alloc_pages(size, NULL); if (heap == NULL) { kprintf(KERN_ERR "error: alloc_pages failed\n"); return (-1); } - PRINT_PTR(heap); Zone *zone = (Zone *)heap; zone->type = type;