From ed2d276717c4a650bbd0588ef066be93d6fb82aa Mon Sep 17 00:00:00 2001 From: antifallobst Date: Fri, 10 Feb 2023 20:13:33 +0100 Subject: [PATCH] feature (kernel): implemented function to resolve physical address from virtual address --- kernel/inc/mm/page_map.h | 1 + kernel/src/kmain.c | 4 ++++ kernel/src/mm/page_map.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/kernel/inc/mm/page_map.h b/kernel/inc/mm/page_map.h index 0c6fd08..bb0308b 100644 --- a/kernel/inc/mm/page_map.h +++ b/kernel/inc/mm/page_map.h @@ -44,6 +44,7 @@ extern page_map_T* page_map_fetch_current (); extern void page_map_load (page_map_T* page_map); void page_map_map_memory (page_map_T* page_map, void* virtual_address, void* physical_address, uint64_t flags); void page_map_unmap_memory (page_map_T* page_map, void* virtual_address); +void* page_map_get_physical_address (page_map_T* page_map, void* virtual_address); void page_map_destruct (page_map_T* page_map); void page_map_entry_set_flags (uint64_t* entry, uint64_t flags); diff --git a/kernel/src/kmain.c b/kernel/src/kmain.c index 59f95b8..8949072 100644 --- a/kernel/src/kmain.c +++ b/kernel/src/kmain.c @@ -44,7 +44,11 @@ void kmain(boot_info_T boot_info) { // this should cause a kernel panic // int x = 1312 / 0; + void* debug; + debug = page_map_get_physical_address(g_kernel_page_map, (void*)0x100000000000); page_map_map_memory(g_kernel_page_map, (void*)0x100000000000, pframe_request(), PM_FLAG_READ_WRITE); + debug = page_map_get_physical_address(g_kernel_page_map, (void*)0x100000000000); + memory_copy("test string", (void*)0x100000000000, 13); log(LOG_DEBUG, (string_t)0x100000000000); diff --git a/kernel/src/mm/page_map.c b/kernel/src/mm/page_map.c index 1a65db6..d6b2608 100644 --- a/kernel/src/mm/page_map.c +++ b/kernel/src/mm/page_map.c @@ -90,6 +90,36 @@ void page_map_unmap_memory(page_map_T* page_map, void* virtual_address) { page_table->entries[page_index] = 0; } +void* page_map_get_physical_address(page_map_T* page_map, void* virtual_address) { + virtual_address = (void*)FLOOR_TO((uint64_t)virtual_address, PFRAME_SIZE); + + // Intel's Developer Manual has a nice graph, that explains how these indexes are calculated + uint16_t page_index = ((uint64_t)virtual_address >> 12) & 0x1FF; + uint16_t page_table_index = ((uint64_t)virtual_address >> 21) & 0x1FF; + uint16_t page_directory_index = ((uint64_t)virtual_address >> 30) & 0x1FF; + uint16_t page_directory_page_index = ((uint64_t)virtual_address >> 39) & 0x1FF; + + if (!page_map_entry_get_flag(&page_map->entries[page_directory_page_index], PM_FLAG_PRESENT)) { + return NULL; + } + page_map_T* page_directory_page = page_map_entry_get_address(&page_map->entries[page_directory_page_index]); + + if (!page_map_entry_get_flag(&page_directory_page->entries[page_directory_index], PM_FLAG_PRESENT)) { + return NULL; + } + page_map_T* page_directory = page_map_entry_get_address(&page_directory_page->entries[page_directory_index]); + + if (!page_map_entry_get_flag(&page_directory->entries[page_table_index], PM_FLAG_PRESENT)) { + return NULL; + } + page_map_T* page_table = page_map_entry_get_address(&page_directory->entries[page_table_index]); + + if (!page_map_entry_get_flag(&page_table->entries[page_index], PM_FLAG_PRESENT)) { + return NULL; + } + return page_map_entry_get_address(&page_table->entries[page_index]); +} + void page_map_destruct(page_map_T* page_map) { for (uint16_t page_directory_page_index = 0; page_directory_page_index < 512; page_directory_page_index++) { if (!page_map_entry_get_flag(&page_map->entries[page_directory_page_index], PM_FLAG_PRESENT)) {