diff options
-rw-r--r-- | src/kernel/fs/elf.c | 10 | ||||
-rw-r--r-- | src/kernel/memory/paging.c | 78 | ||||
-rw-r--r-- | src/kernel/memory/paging.h | 17 | ||||
-rw-r--r-- | src/kernel/tasks/process.c | 4 | ||||
-rw-r--r-- | src/kernel/tasks/process.h | 4 |
5 files changed, 52 insertions, 61 deletions
diff --git a/src/kernel/fs/elf.c b/src/kernel/fs/elf.c index a67ab6a..ba9251a 100644 --- a/src/kernel/fs/elf.c +++ b/src/kernel/fs/elf.c @@ -25,6 +25,12 @@ int is_elf(struct elf_header *header) struct process *elf_load(char *path) { + u32 *prev_dir; + if (current_proc) + prev_dir = current_proc->cr3; + else + prev_dir = current_page_directory; + u8 *file = read_file(path); if (!file) { warn("File or directory not found: %s", path); @@ -71,6 +77,6 @@ struct process *elf_load(char *path) } } - paging_switch_directory(paging_kernel_directory); + paging_switch_directory(prev_dir); return proc; -}
\ No newline at end of file +} diff --git a/src/kernel/memory/paging.c b/src/kernel/memory/paging.c index 516f0f1..de93ffb 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -4,57 +4,47 @@ #include <stdint.h> #include <system.h> -int paging_enabled = 0; +u32 *current_page_directory; +u32 (*current_page_tables)[1024]; +u32 kernel_page_directory[1024] __attribute__((aligned(4096))); +u32 kernel_page_tables[1024][1024] __attribute__((aligned(4096))); -u32 tmp[1024][1024] __attribute__((aligned(4096))); -struct page_directory *paging_kernel_directory __attribute__((aligned(4096))) = - (struct page_directory *)tmp; -struct page_directory *paging_directory __attribute__((aligned(4096))); // Current - -void paging_init(struct page_directory *dir, int user) +void paging_init(u32 *dir, int user) { for (u32 i = 0; i < 1024; i++) { for (u32 j = 0; j < 1024; j++) { - dir->tables[i]->pages[j] = - ((j * 0x1000) + (i * PAGE_SIZE)) | PT_RW | (user ? PT_USER : 0); + current_page_tables[i][j] = ((j * 0x1000) + (i * 0x400000)) | PT_RW; } } for (u32 i = 0; i < 1024; i++) { - dir->tables[i] = ((u32)dir->tables[i]) | PD_RW | PD_PRESENT | (user ? PD_USER : 0); + current_page_directory[i] = ((u32)current_page_tables[i]) | PD_RW | PD_PRESENT; } } -struct page_directory *paging_make_directory(int user) -{ - struct page_directory *dir = (struct page_directory *)malloc(sizeof(struct page_directory)); - - paging_init(dir, user); - - return dir; -} - extern void KERNEL_END(); void paging_install(u32 multiboot_address) { - paging_switch_directory(paging_kernel_directory); - paging_init(paging_directory, 0); + paging_switch_directory(kernel_page_directory); + 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); + 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 - log("Enabling"); paging_enable(); log("Installed paging"); +} + +u32 *paging_make_directory(int user) +{ + u32 *dir = malloc(1024 * 1024 * 32); - u32 a = (u32)malloc(4096); - u32 b = (u32)malloc(4096); - free((void *)b); - free((void *)a); - u32 c = (u32)malloc(2048); - assert(a == c); - info("kmalloc test succeeded!"); + paging_init(dir, user); + + return dir; } void paging_disable() @@ -68,6 +58,7 @@ void paging_disable() void paging_enable() { + asm("mov %0, %%cr3" ::"r"(current_page_directory)); u32 cr0; asm("mov %%cr0, %0" : "=r"(cr0)); cr0 |= 0x80000000; @@ -75,10 +66,11 @@ void paging_enable() paging_enabled = 1; } -void paging_switch_directory(struct page_directory *dir) +void paging_switch_directory(u32 *dir) { - paging_directory = dir; - asm("mov %0, %%cr3" ::"r"(dir)); + current_page_tables = kernel_page_tables; + current_page_directory = dir; + asm("mov %0, %%cr3" ::"r"(current_page_directory)); } void invlpg(u32 addr) @@ -90,7 +82,7 @@ void paging_map(u32 phy, u32 virt, u16 flags) { u32 pdi = virt >> 22; u32 pti = virt >> 12 & 0x03FF; - paging_directory->tables[pdi]->pages[pti] = phy | flags; + current_page_tables[pdi][pti] = phy | flags; invlpg(virt); } @@ -98,21 +90,21 @@ u32 paging_get_phys(u32 virt) { u32 pdi = virt >> 22; u32 pti = (virt >> 12) & 0x03FF; - return paging_directory->tables[pdi]->pages[pti] & 0xFFFFF000; + return current_page_tables[pdi][pti] & 0xFFFFF000; } u16 paging_get_flags(u32 virt) { u32 pdi = virt >> 22; u32 pti = (virt >> 12) & 0x03FF; - return paging_directory->tables[pdi]->pages[pti] & 0xFFF; + return current_page_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++) { - paging_directory->tables[i / 1024]->pages[i % 1024] |= flag; + current_page_tables[i / 1024][i % 1024] |= flag; invlpg(i * 0x1000); } } @@ -121,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++) { - paging_directory->tables[i / 1024]->pages[i % 1024] &= ~flag; + current_page_tables[i / 1024][i % 1024] &= ~flag; invlpg(i * 0x1000); } } @@ -150,7 +142,7 @@ void paging_set_user(u32 virt, u32 count) { u32 page_n = virt / 0x1000; for (u32 i = page_n; i < page_n + count; i += 1024) { - paging_directory->tables[i] = ((u32)paging_directory->tables[i]) | PD_USER; + current_page_directory[i / 1024] |= PD_USER; } paging_set_flag_up(virt, count, PT_USER); } @@ -162,8 +154,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 (!(paging_directory->tables[i]->pages[j] & PT_PRESENT) || - (paging_directory->tables[i]->pages[j] & PT_USED)) { + if (!(current_page_tables[i][j] & PT_PRESENT) || + (current_page_tables[i][j] & PT_USED)) { continuous = 0; start_dir = i; start_page = j + 1; @@ -191,10 +183,10 @@ u32 paging_get_used_pages() u32 n = 0; for (u32 i = 0; i < 1024; i++) { for (u32 j = 0; j < 1024; j++) { - u8 flags = paging_directory->tables[i]->pages[j] & PT_USED; + u8 flags = current_page_tables[i][j] & PT_USED; if (flags == 1) n++; } } return n; -}
\ No newline at end of file +} diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index bf82cf5..8857381 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -23,23 +23,16 @@ #define PT_GLOBAL 1 << 8 #define PT_USED 1 << 9 -struct page_table { - u32 pages[1024] __attribute__((aligned(4096))); -}; - -struct page_directory { - struct page_table *tables[1024] __attribute__((aligned(4096))); -}; - -struct page_directory *paging_kernel_directory __attribute__((aligned(4096))); +u32 *current_page_directory; +u32 kernel_page_directory[1024] __attribute__((aligned(4096))); int paging_enabled; void paging_install(u32 multiboot_address); void paging_enable(); void paging_disable(); -struct page_directory *paging_make_directory(int user); -void paging_switch_directory(struct page_directory *dir); +u32 *paging_make_directory(int user); +void paging_switch_directory(u32 *dir); void paging_map(u32 phy, u32 virt, u16 flags); u32 paging_get_phys(u32 virt); @@ -58,4 +51,4 @@ void paging_set_user(u32 virt, u32 count); u32 paging_find_pages(u32 count); u32 paging_alloc_pages(u32 count); -#endif
\ No newline at end of file +#endif diff --git a/src/kernel/tasks/process.c b/src/kernel/tasks/process.c index c4ab74a..75419ba 100644 --- a/src/kernel/tasks/process.c +++ b/src/kernel/tasks/process.c @@ -188,7 +188,7 @@ struct process *process_make_new() proc->brk = 0x50000000; for (int i = 0; i < 1024; i++) - proc->cr3->tables[i] = paging_kernel_directory->tables[i]; + proc->cr3[i] = kernel_page_directory[i]; proc->pid = pid++; return proc; @@ -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 08b30ed..00f0f07 100644 --- a/src/kernel/tasks/process.h +++ b/src/kernel/tasks/process.h @@ -13,7 +13,7 @@ struct mmap { }; struct process { - struct page_directory *cr3; + u32 *cr3; struct regs registers; u32 pid; @@ -65,4 +65,4 @@ extern u32 stack_hold; #define WAIT_ERROR (-1) #define WAIT_OKAY 0 -#endif
\ No newline at end of file +#endif |