From 7e53464d7bb2187fe0754fbdc04becbdccae11fe Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sat, 23 May 2020 18:43:22 +0200 Subject: Dynamic paging approach I think this is it. I really do. I guess. --- src/kernel/memory/paging.c | 50 +++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 29 deletions(-) (limited to 'src/kernel/memory/paging.c') diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 917a186..db9fc2d 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -4,35 +4,38 @@ #include #include -u32 *current_page_directory; -u32 (*current_page_tables)[1024]; -u32 kernel_page_directory[1024] __attribute__((aligned(4096))); +u32 **current_page_directory; +u32 *kernel_page_directory[1024] __attribute__((aligned(4096))); u32 kernel_page_tables[1024][1024] __attribute__((aligned(4096))); -void paging_init(u32 *dir, u32 tables[1024][1024], int user) +void paging_init(u32 **dir, int user) { for (u32 i = 0; i < 1024; i++) { for (u32 j = 0; j < 1024; j++) { - tables[i][j] = - ((j * 0x1000) + (i * 0x400000)) | PT_RW | (user ? PT_USER : 0); + dir[i][j] = ((j * 0x1000) + (i * 0x400000)) | PT_RW | (user ? PT_USER : 0); } } for (u32 i = 0; i < 1024; i++) { - dir[i] = ((u32)tables[i]) | PD_RW | PD_PRESENT | (user ? PD_USER : 0); + dir[i] = ((u32)dir[i]) | PD_RW | PD_PRESENT | (user ? PD_USER : 0); } } extern void KERNEL_END(); void paging_install() { - paging_init(kernel_page_directory, kernel_page_tables, 0); - paging_switch_directory(kernel_page_directory); + for (u32 i = 0; i < 1024; i++) { + kernel_page_directory[i] = kernel_page_tables[i]; + } + + paging_init((u32 **)kernel_page_directory, 0); + paging_switch_directory((u32 **)kernel_page_directory); if (!memory_init()) paging_set_present(0, memory_get_all() >> 3); paging_set_used(0, ((u32)KERNEL_END >> 12) + 1); + log("Installing paging"); paging_enable(); log("Installed paging"); @@ -79,9 +82,8 @@ void paging_enable() paging_enabled = 1; } -void paging_switch_directory(u32 *dir) +void paging_switch_directory(u32 **dir) { - current_page_tables = dir; current_page_directory = dir; asm("mov %0, %%cr3" ::"r"(current_page_directory)); } @@ -95,7 +97,7 @@ void paging_map(u32 phy, u32 virt, u16 flags) { u32 pdi = virt >> 22; u32 pti = virt >> 12 & 0x03FF; - current_page_tables[pdi][pti] = phy | flags; + current_page_directory[pdi][pti] = phy | flags; invlpg(virt); } @@ -103,21 +105,21 @@ u32 paging_get_phys(u32 virt) { u32 pdi = virt >> 22; u32 pti = (virt >> 12) & 0x03FF; - return current_page_tables[pdi][pti] & 0xFFFFF000; + return current_page_directory[pdi][pti] & 0xFFFFF000; } u16 paging_get_flags(u32 virt) { u32 pdi = virt >> 22; u32 pti = (virt >> 12) & 0x03FF; - return current_page_tables[pdi][pti] & 0xFFF; + return current_page_directory[pdi][pti] & 0xFFF; } void paging_set_flag_up(u32 virt, u32 count, u32 flag) { u32 page_n = virt / 0x1000; for (u32 i = page_n; i < page_n + count; i++) { - current_page_tables[i / 1024][i % 1024] |= flag; + current_page_directory[i / 1024][i % 1024] |= flag; invlpg(i * 0x1000); } } @@ -126,7 +128,7 @@ void paging_set_flag_down(u32 virt, u32 count, u32 flag) { u32 page_n = virt / 0x1000; for (u32 i = page_n; i < page_n + count; i++) { - current_page_tables[i / 1024][i % 1024] &= ~flag; + current_page_directory[i / 1024][i % 1024] &= ~flag; invlpg(i * 0x1000); } } @@ -151,15 +153,6 @@ void paging_set_free(u32 virt, u32 count) paging_set_flag_down(virt, count, PT_USED); } -void paging_set_user(u32 virt, u32 count) -{ - u32 page_n = virt / 0x1000; - for (u32 i = page_n; i < page_n + count; i += 1024) { - current_page_directory[i / 1024] |= PD_USER; - } - paging_set_flag_up(virt, count, PT_USER); -} - u32 paging_find_pages(u32 count) { u32 continuous = 0; @@ -167,8 +160,8 @@ u32 paging_find_pages(u32 count) u32 start_page = 0; for (u32 i = 0; i < 1024; i++) { for (u32 j = 0; j < 1024; j++) { - if (!(current_page_tables[i][j] & PT_PRESENT) || - (current_page_tables[i][j] & PT_USED)) { + if (!(current_page_directory[i][j] & PT_PRESENT) || + (current_page_directory[i][j] & PT_USED)) { continuous = 0; start_dir = i; start_page = j + 1; @@ -187,7 +180,6 @@ u32 paging_alloc_pages(u32 count) { u32 ptr = paging_find_pages(count); paging_set_used(ptr, count); - paging_set_user(ptr, count); return ptr; } @@ -196,7 +188,7 @@ u32 paging_get_used_pages() u32 n = 0; for (u32 i = 0; i < 1024; i++) { for (u32 j = 0; j < 1024; j++) { - u8 flags = current_page_tables[i][j] & PT_USED; + u8 flags = current_page_directory[i][j] & PT_USED; if (flags == 1) n++; } -- cgit v1.2.3