From f0ceac4c2e11a8cfd62ccb0a693178cae7c44d82 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sat, 16 May 2020 16:21:42 +0200 Subject: Added page-aligned allocation for page-fix Not completely finished! --- src/kernel/fs/elf.c | 5 ++++- src/kernel/memory/alloc.c | 8 ++++++++ src/kernel/memory/alloc.h | 1 + src/kernel/memory/paging.c | 17 +++++++++++------ src/kernel/memory/paging.h | 2 +- src/kernel/tasks/process.c | 2 +- src/kernel/tasks/process.h | 2 +- 7 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/kernel/fs/elf.c b/src/kernel/fs/elf.c index ba9251a..3279784 100644 --- a/src/kernel/fs/elf.c +++ b/src/kernel/fs/elf.c @@ -51,8 +51,11 @@ struct process *elf_load(char *path) strcpy(proc->name, path); proc->registers.eip = header->entry; + log("1"); paging_switch_directory(proc->cr3); + log("2"); u32 stk = (u32)malloc(PAGE_SIZE); + log("3"); proc->registers.useresp = 0x40000000 - (PAGE_SIZE / 2); proc->registers.ebp = proc->registers.useresp; proc->registers.esp = proc->registers.useresp; @@ -79,4 +82,4 @@ struct process *elf_load(char *path) paging_switch_directory(prev_dir); return proc; -} +} \ No newline at end of file diff --git a/src/kernel/memory/alloc.c b/src/kernel/memory/alloc.c index a4fb60a..904be3a 100644 --- a/src/kernel/memory/alloc.c +++ b/src/kernel/memory/alloc.c @@ -361,6 +361,14 @@ void *malloc(u32 req_size) return NULL; } +// Definitely improveable +void *valloc(u32 req_size) +{ + u32 mask = l_page_size - 1; + u32 mem = malloc(req_size + l_page_size); + return (void *)((mem + mask) & ~mask); +} + void free(void *ptr) { struct liballoc_minor *min; diff --git a/src/kernel/memory/alloc.h b/src/kernel/memory/alloc.h index 6c4290e..2e8697f 100644 --- a/src/kernel/memory/alloc.h +++ b/src/kernel/memory/alloc.h @@ -4,6 +4,7 @@ #include void *malloc(u32); +void *valloc(u32 req_size); // Page-aligned void *realloc(void *, u32); void *calloc(u32, u32); void free(void *); diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index de93ffb..380b7e0 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -13,12 +13,13 @@ void paging_init(u32 *dir, int user) { for (u32 i = 0; i < 1024; i++) { for (u32 j = 0; j < 1024; j++) { - current_page_tables[i][j] = ((j * 0x1000) + (i * 0x400000)) | PT_RW; + current_page_tables[i][j] = + ((j * 0x1000) + (i * 0x400000)) | PT_RW | (user ? PT_USER : 0); } } for (u32 i = 0; i < 1024; i++) { - current_page_directory[i] = ((u32)current_page_tables[i]) | PD_RW | PD_PRESENT; + dir[i] = ((u32)current_page_tables[i]) | PD_RW | PD_PRESENT | (user ? PD_USER : 0); } } @@ -26,6 +27,7 @@ extern void KERNEL_END(); void paging_install(u32 multiboot_address) { paging_switch_directory(kernel_page_directory); + current_page_tables = kernel_page_tables; paging_init(current_page_directory, 0); // if mmap approach didn't work @@ -40,7 +42,8 @@ void paging_install(u32 multiboot_address) u32 *paging_make_directory(int user) { - u32 *dir = malloc(1024 * 1024 * 32); + u32 *dir = valloc(1024 * 1024 * 32); + current_page_tables = valloc(1024 * 1024 * 32); paging_init(dir, user); @@ -68,9 +71,11 @@ void paging_enable() void paging_switch_directory(u32 *dir) { - current_page_tables = kernel_page_tables; + current_page_tables = (u32(*)[1024])dir; current_page_directory = dir; - asm("mov %0, %%cr3" ::"r"(current_page_directory)); + log("huh"); + asm("mov %0, %%cr3" ::"r"(dir)); + log("huh"); } void invlpg(u32 addr) @@ -189,4 +194,4 @@ u32 paging_get_used_pages() } } return n; -} +} \ No newline at end of file diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index 8857381..9f37ed6 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -51,4 +51,4 @@ void paging_set_user(u32 virt, u32 count); u32 paging_find_pages(u32 count); u32 paging_alloc_pages(u32 count); -#endif +#endif \ No newline at end of file diff --git a/src/kernel/tasks/process.c b/src/kernel/tasks/process.c index 75419ba..f90df89 100644 --- a/src/kernel/tasks/process.c +++ b/src/kernel/tasks/process.c @@ -232,4 +232,4 @@ u32 uspawn(char *path) log("Spawned"); process_force_switch(); return 0; -} +} \ No newline at end of file diff --git a/src/kernel/tasks/process.h b/src/kernel/tasks/process.h index 00f0f07..96ef44b 100644 --- a/src/kernel/tasks/process.h +++ b/src/kernel/tasks/process.h @@ -65,4 +65,4 @@ extern u32 stack_hold; #define WAIT_ERROR (-1) #define WAIT_OKAY 0 -#endif +#endif \ No newline at end of file -- cgit v1.2.3 From e3e294e60333cb603a3ac35412c8279d45081737 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Sun, 17 May 2020 23:35:14 +0200 Subject: Some testing in paging This approach will probably work. I've done some *very* dumb mistakes before (e.g. assuming **dir == dir[1024][1024])... I KNOW BETTER NOW THOUGH! --- src/kernel/fs/elf.c | 2 +- src/kernel/memory/paging.c | 53 +++++++++++++++++----------------------------- src/kernel/memory/paging.h | 15 ++++++++----- src/kernel/tasks/process.h | 2 +- 4 files changed, 31 insertions(+), 41 deletions(-) diff --git a/src/kernel/fs/elf.c b/src/kernel/fs/elf.c index 3279784..22cdb74 100644 --- a/src/kernel/fs/elf.c +++ b/src/kernel/fs/elf.c @@ -25,7 +25,7 @@ int is_elf(struct elf_header *header) struct process *elf_load(char *path) { - u32 *prev_dir; + struct page_dir *prev_dir; if (current_proc) prev_dir = current_proc->cr3; else diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 380b7e0..c0c1a6a 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -4,46 +4,45 @@ #include #include -u32 *current_page_directory; -u32 (*current_page_tables)[1024]; -u32 kernel_page_directory[1024] __attribute__((aligned(4096))); +struct page_dir *current_page_directory; +struct page_dir kernel_page_directory[1024] __attribute__((aligned(4096))); u32 kernel_page_tables[1024][1024] __attribute__((aligned(4096))); -void paging_init(u32 *dir, int user) +void paging_init(struct page_dir *dir, int user) { for (u32 i = 0; i < 1024; i++) { for (u32 j = 0; j < 1024; j++) { - current_page_tables[i][j] = + dir->tables[i][j] = ((j * 0x1000) + (i * 0x400000)) | PT_RW | (user ? PT_USER : 0); } } for (u32 i = 0; i < 1024; i++) { - dir[i] = ((u32)current_page_tables[i]) | PD_RW | PD_PRESENT | (user ? PD_USER : 0); + dir[i] = *(struct page_dir *)(((u32)dir->tables[i]) | PD_RW | PD_PRESENT | + (user ? PD_USER : 0)); } } extern void KERNEL_END(); void paging_install(u32 multiboot_address) { + kernel_page_directory->tables = kernel_page_tables; paging_switch_directory(kernel_page_directory); - current_page_tables = kernel_page_tables; paging_init(current_page_directory, 0); // if mmap approach didn't work if (!memory_init(multiboot_address)) paging_set_present(0, memory_get_all() >> 3); // /4 paging_set_used(0, ((u32)KERNEL_END >> 12) + 1); // /4096 - // paging_set_user(0, memory_get_all() >> 3); // HMM paging_enable(); log("Installed paging"); } -u32 *paging_make_directory(int user) +struct page_dir *paging_make_directory(int user) { - u32 *dir = valloc(1024 * 1024 * 32); - current_page_tables = valloc(1024 * 1024 * 32); + struct page_dir *dir = valloc(1024 * 1024 * 32); + dir->tables = valloc(1024 * 1024 * 32); paging_init(dir, user); @@ -61,7 +60,6 @@ void paging_disable() void paging_enable() { - asm("mov %0, %%cr3" ::"r"(current_page_directory)); u32 cr0; asm("mov %%cr0, %0" : "=r"(cr0)); cr0 |= 0x80000000; @@ -69,13 +67,10 @@ void paging_enable() paging_enabled = 1; } -void paging_switch_directory(u32 *dir) +void paging_switch_directory(struct page_dir *dir) { - current_page_tables = (u32(*)[1024])dir; current_page_directory = dir; - log("huh"); asm("mov %0, %%cr3" ::"r"(dir)); - log("huh"); } void invlpg(u32 addr) @@ -87,7 +82,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->tables[pdi][pti] = phy | flags; invlpg(virt); } @@ -95,21 +90,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->tables[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->tables[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->tables[i / 1024][i % 1024] |= flag; invlpg(i * 0x1000); } } @@ -118,7 +113,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->tables[i / 1024][i % 1024] &= ~flag; invlpg(i * 0x1000); } } @@ -143,15 +138,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; @@ -159,8 +145,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->tables[i][j] & PT_PRESENT) || + (current_page_directory->tables[i][j] & PT_USED)) { continuous = 0; start_dir = i; start_page = j + 1; @@ -179,7 +165,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; } @@ -188,7 +173,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->tables[i][j] & PT_USED; if (flags == 1) n++; } diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index 9f37ed6..17dde1d 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -23,16 +23,22 @@ #define PT_GLOBAL 1 << 8 #define PT_USED 1 << 9 -u32 *current_page_directory; -u32 kernel_page_directory[1024] __attribute__((aligned(4096))); +typedef u32 (*page_tables)[1024] __attribute__((aligned(4096))); + +struct page_dir { + page_tables tables; +}; + +struct page_dir *current_page_directory; +struct page_dir kernel_page_directory[1024] __attribute__((aligned(4096))); int paging_enabled; void paging_install(u32 multiboot_address); void paging_enable(); void paging_disable(); -u32 *paging_make_directory(int user); -void paging_switch_directory(u32 *dir); +struct page_dir *paging_make_directory(int user); +void paging_switch_directory(struct page_dir *dir); void paging_map(u32 phy, u32 virt, u16 flags); u32 paging_get_phys(u32 virt); @@ -46,7 +52,6 @@ void paging_set_present(u32 virt, u32 count); void paging_set_absent(u32 virt, u32 count); void paging_set_used(u32 virt, u32 count); void paging_set_free(u32 virt, u32 count); -void paging_set_user(u32 virt, u32 count); u32 paging_find_pages(u32 count); u32 paging_alloc_pages(u32 count); diff --git a/src/kernel/tasks/process.h b/src/kernel/tasks/process.h index 96ef44b..92d5ec2 100644 --- a/src/kernel/tasks/process.h +++ b/src/kernel/tasks/process.h @@ -13,7 +13,7 @@ struct mmap { }; struct process { - u32 *cr3; + struct page_dir *cr3; struct regs registers; u32 pid; -- cgit v1.2.3