From 5e561bfa157b50812fa691e66fd15c75271b6f49 Mon Sep 17 00:00:00 2001 From: 0x35c Date: Mon, 10 Feb 2025 13:25:19 +0100 Subject: [PATCH] wip: multiple pds and switch to kernel pd when needed --- headers/memory.h | 4 +++- src/kernel.c | 2 +- src/memory/memory.c | 16 ++++++++++++---- src/memory/page.c | 7 ++++--- src/memory/page_table.c | 2 +- src/multiboot.c | 5 ++--- src/multitasking/scheduler.c | 3 +-- src/multitasking/switch_to_task.s | 5 +++++ src/multitasking/task.c | 24 ++++++++++++------------ 9 files changed, 41 insertions(+), 27 deletions(-) diff --git a/headers/memory.h b/headers/memory.h index 9466183..a46420a 100644 --- a/headers/memory.h +++ b/headers/memory.h @@ -46,7 +46,8 @@ extern uint32_t _kernel_end; extern uint32_t _kernel_start; extern uint32_t boot_page_directory; extern uint32_t boot_page_table1; -extern uint32_t *page_directory; +extern uint32_t *kernel_pd; +extern uint32_t *current_pd; extern uint32_t page_table_default[1024]; extern uint32_t mem_size; extern multiboot_memory_map_t *mmap_addr; @@ -62,3 +63,4 @@ void *alloc_pages(size_t size, void **phys_addr); int free_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/kernel.c b/src/kernel.c index b80f210..d638609 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -66,7 +66,7 @@ void kernel_main(multiboot_info_t *mbd, uint32_t magic) */ /* "Martin 03:50, 22 March 2009 (UTC)\n"); */ create_kernel_task(); - exec_fn(uwu); + exec_fn(owo); /* exec_fn(owo); */ /* exec_fn(owo); */ /* exec_fn(owo); */ diff --git a/src/memory/memory.c b/src/memory/memory.c index 5bed694..1aebc63 100644 --- a/src/memory/memory.c +++ b/src/memory/memory.c @@ -4,12 +4,19 @@ #include -uint32_t *page_directory = &boot_page_directory; +uint32_t *kernel_pd = &boot_page_directory; +uint32_t *current_pd; uint32_t page_table_default[1024] __attribute__((aligned(PAGE_SIZE))); uint32_t frame_zones_page_table[1024] __attribute__((aligned(PAGE_SIZE))); uint32_t mem_size; struct frame_zone *head; +void switch_pd(uint32_t *pd, uint32_t *cr3) +{ + current_pd = pd; + asm volatile("mov %0, %%cr3" ::"r"(cr3)); +} + static void lst_add_back(struct frame_zone **root, struct frame_zone *element) { if (!*root) { @@ -61,7 +68,7 @@ static void add_frame_node(multiboot_memory_map_t *mmmt) end_addr = ROUND_CEIL(start_addr + len, PAGE_SIZE); init_page_table(frame_zones_page_table, 0); - page_directory[1022] = ((uint32_t)frame_zones_page_table - HEAP_END) | 0x03; + kernel_pd[1022] = ((uint32_t)frame_zones_page_table - HEAP_END) | 0x03; frame_zones_page_table[index] = ((uint32_t)start_addr & PAGE_MASK) | INIT_FLAGS; @@ -107,9 +114,10 @@ static void init_frame_zones(void) void init_memory(multiboot_info_t *mbd, uint32_t magic) { for (uint16_t i = 0; i < 0x300; i++) - page_directory[i] = 0x02; + kernel_pd[i] = 0x02; init_page_table(page_table_default, 0); - page_directory[0] = ((uint32_t)page_table_default - HEAP_END) | 0x03; + kernel_pd[0] = ((uint32_t)page_table_default - HEAP_END) | 0x03; + current_pd = kernel_pd; init_multiboot(mbd, magic); init_frame_zones(); } diff --git a/src/memory/page.c b/src/memory/page.c index 4cffa58..f7462da 100644 --- a/src/memory/page.c +++ b/src/memory/page.c @@ -10,10 +10,10 @@ #include "utils.h" static int16_t find_next_block(size_t nb_pages, uint16_t *pd_index_ptr, - uint32_t **page_table_ptr) + uint32_t **page_table_ptr) { for (*pd_index_ptr = 1; *pd_index_ptr < 768; (*pd_index_ptr)++) { - if (current_task->heap[(*pd_index_ptr)] == 0x02) { + if (current_pd[(*pd_index_ptr)] == 0x02) { if (add_page_table(*pd_index_ptr) < 0) return -2; } @@ -92,7 +92,8 @@ int free_pages(void *page_ptr, size_t 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); + 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"); diff --git a/src/memory/page_table.c b/src/memory/page_table.c index 0e574c0..bf3fc33 100644 --- a/src/memory/page_table.c +++ b/src/memory/page_table.c @@ -17,6 +17,6 @@ int16_t add_page_table(uint16_t pd_index) uint32_t *page_table = (uint32_t *)GET_PAGE_ADDR(0, PT_START + pd_index); init_page_table(page_table, 0); - page_directory[pd_index] = ((uint32_t)frame & PAGE_MASK) | 0x03; + kernel_pd[pd_index] = ((uint32_t)frame & PAGE_MASK) | 0x03; return 0; } diff --git a/src/multiboot.c b/src/multiboot.c index ddcc924..ee9ec16 100644 --- a/src/multiboot.c +++ b/src/multiboot.c @@ -38,7 +38,7 @@ static void init_vbe(multiboot_info_t *mbd_virt) ((mbd_virt->framebuffer_addr + i * PAGE_SIZE) & PAGE_MASK) | INIT_FLAGS; } - page_directory[800] = ((uint32_t)vbe_page_table - HEAP_END) | 0x03; + kernel_pd[800] = ((uint32_t)vbe_page_table - HEAP_END) | 0x03; display.buff = (uint32_t *)GET_PAGE_ADDR(800, 0) + (mbd_virt->framebuffer_addr % PAGE_SIZE); display.height = mbd_virt->framebuffer_height; @@ -53,8 +53,7 @@ void init_multiboot(multiboot_info_t *mbd, uint32_t magic) kpanic("invalid magic number! (git good skill issue)"); init_page_table(multiboot_page_table, 0); - page_directory[1023] = - ((uint32_t)multiboot_page_table - HEAP_END) | 0x03; + kernel_pd[1023] = ((uint32_t)multiboot_page_table - HEAP_END) | 0x03; size_t pt_index = CEIL( (uint32_t)mbd % PAGE_SIZE + sizeof(multiboot_info_t), PAGE_SIZE); diff --git a/src/multitasking/scheduler.c b/src/multitasking/scheduler.c index 14498fa..0d9b917 100644 --- a/src/multitasking/scheduler.c +++ b/src/multitasking/scheduler.c @@ -19,8 +19,7 @@ void scheduler(void) if (!current_task) // || current_task->next == current_task) return; cli(); - uint32_t *old_pd = current_task->heap; - current_task->heap = page_directory; + switch_pd(kernel_pd, (uint32_t *)((uint32_t)kernel_pd - HEAP_END)); struct task *it = current_task->next; while (it && it->status != RUN) { if (it != current_task && func[it->status]) { diff --git a/src/multitasking/switch_to_task.s b/src/multitasking/switch_to_task.s index 73c8d3f..d1ffa5c 100644 --- a/src/multitasking/switch_to_task.s +++ b/src/multitasking/switch_to_task.s @@ -23,6 +23,11 @@ switch_to_task: mov esp, [eax+0] // get esp + mov ecx, [eax+12] // get task's pd + mov [current_pd], ecx + mov ecx, [eax+8] + mov cr3, ecx + pop esi pop edi pop ebp diff --git a/src/multitasking/task.c b/src/multitasking/task.c index 1ea8318..8a68658 100644 --- a/src/multitasking/task.c +++ b/src/multitasking/task.c @@ -15,36 +15,36 @@ uint32_t esp_backup; struct task *create_task(uint8_t uid) { static uint32_t pid = 1; - uint32_t *old_pd = current_task->heap; - current_task->heap = page_directory; // kernel pd + switch_pd(kernel_pd, (uint32_t *)((uint32_t)kernel_pd - HEAP_END)); struct task *new_task = vmalloc(sizeof(struct task)); - current_task->heap = old_pd; - if (!new_task) + if (!new_task) { + switch_pd(current_task->heap, current_task->cr3); return NULL; + } + switch_pd(current_task->heap, current_task->cr3); new_task->status = RUN; new_task->uid = uid; new_task->esp = new_task->esp0 + STACK_SIZE; new_task->pid = pid++; // Allocate new pd - old_pd = current_task->heap; - current_task->heap = alloc_pages(4096, (void **)&new_task->cr3); + new_task->heap = alloc_pages(4096, (void **)&new_task->cr3); if (!new_task->heap) { - current_task->heap = old_pd; vfree(new_task); return NULL; } - new_task->heap = current_task->heap; + new_task->heap[768] = ((uint32_t)boot_page_table1 - HEAP_END) | 0x03; + memcpy(new_task->heap, current_task->heap, 4096); + switch_pd(new_task->heap, new_task->cr3); // Allocate new stack on the newly allocated pd new_task->esp0 = alloc_pages(STACK_SIZE, NULL); - current_task->heap = old_pd; + switch_pd(current_task->heap, current_task->cr3); if (!new_task->esp0) { vfree(new_task); free_pages(new_task->heap, 4096); return NULL; } - new_task->heap[768] = ((uint32_t)boot_page_table1 - HEAP_END) | 0x03; new_task->next = current_task->next; new_task->prev = current_task; @@ -60,8 +60,8 @@ int8_t create_kernel_task(void) new_task->status = RUN; new_task->uid = 0; new_task->pid = 0; - new_task->heap = page_directory; - new_task->cr3 = page_directory - KERNEL_START; + new_task->heap = kernel_pd; + new_task->cr3 = (uint32_t *)((uint32_t)kernel_pd - HEAP_END); new_task->prev = new_task; new_task->next = new_task; current_task = new_task;