diff options
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/fs/elf.c | 18 | ||||
-rw-r--r-- | src/kernel/kernel.c | 3 | ||||
-rw-r--r-- | src/kernel/lib/lib.h | 2 | ||||
-rw-r--r-- | src/kernel/lib/memory.c | 2 | ||||
-rw-r--r-- | src/kernel/memory/alloc.h | 2 | ||||
-rw-r--r-- | src/kernel/memory/paging.c | 73 | ||||
-rw-r--r-- | src/kernel/memory/paging.h | 17 | ||||
-rw-r--r-- | src/kernel/system.h | 2 | ||||
-rw-r--r-- | src/kernel/tasks/process.c | 2 | ||||
-rw-r--r-- | src/kernel/tasks/process.h | 2 |
10 files changed, 73 insertions, 50 deletions
diff --git a/src/kernel/fs/elf.c b/src/kernel/fs/elf.c index 22cdb74..fe180c4 100644 --- a/src/kernel/fs/elf.c +++ b/src/kernel/fs/elf.c @@ -25,7 +25,8 @@ int is_elf(struct elf_header *header) struct process *elf_load(char *path) { - struct page_dir *prev_dir; + log("ELF START"); + u32 *prev_dir; if (current_proc) prev_dir = current_proc->cr3; else @@ -51,11 +52,12 @@ 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"); + if (!memory_init()) + paging_set_present(0, memory_get_all() >> 3); + + u32 stk = (u32)valloc(PAGE_SIZE); + proc->registers.useresp = 0x40000000 - (PAGE_SIZE / 2); proc->registers.ebp = proc->registers.useresp; proc->registers.esp = proc->registers.useresp; @@ -66,11 +68,14 @@ struct process *elf_load(char *path) case 0: break; case 1: { - u32 loc = (u32)malloc(PAGE_SIZE); + u32 loc = (u32)valloc(PAGE_SIZE); + warn("1"); paging_map(loc, program_header->vaddr, PT_USER); + warn("2"); memcpy((void *)program_header->vaddr, ((void *)((u32)file) + program_header->offset), program_header->filesz); + warn("3"); if (program_header->filesz > PAGE_SIZE) panic("ELF binary section too large"); break; @@ -81,5 +86,6 @@ struct process *elf_load(char *path) } paging_switch_directory(prev_dir); + log("ELF END"); return proc; }
\ No newline at end of file diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 82937f2..bd22dfc 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -22,8 +22,9 @@ u32 stack_hold; -void kernel_main(u32 magic, u32 multiboot_address, u32 esp) +void kernel_main(u32 magic, u32 addr, u32 esp) { + multiboot_address = addr; stack_hold = esp; if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { diff --git a/src/kernel/lib/lib.h b/src/kernel/lib/lib.h index 6f2c04d..bdf0794 100644 --- a/src/kernel/lib/lib.h +++ b/src/kernel/lib/lib.h @@ -34,7 +34,7 @@ int memcmp(const void *a_ptr, const void *b_ptr, u32 size); void memory_info_init(struct multiboot_tag_basic_meminfo *tag); void memory_mmap_init(struct multiboot_tag_mmap *tag); -int memory_init(u32 multiboot_address); +int memory_init(); void memory_print(); u32 memory_get_all(); diff --git a/src/kernel/lib/memory.c b/src/kernel/lib/memory.c index 0f3cb34..0519492 100644 --- a/src/kernel/lib/memory.c +++ b/src/kernel/lib/memory.c @@ -98,7 +98,7 @@ void memory_mmap_init(struct multiboot_tag_mmap *tag) total = sum >> 10; // I want kb } -int memory_init(u32 multiboot_address) +int memory_init() { int ret = 0; struct multiboot_tag *tag; diff --git a/src/kernel/memory/alloc.h b/src/kernel/memory/alloc.h index 2e8697f..bb3f452 100644 --- a/src/kernel/memory/alloc.h +++ b/src/kernel/memory/alloc.h @@ -4,7 +4,7 @@ #include <stdint.h> void *malloc(u32); -void *valloc(u32 req_size); // Page-aligned +void *valloc(u32); 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 c0c1a6a..94b777e 100644 --- a/src/kernel/memory/paging.c +++ b/src/kernel/memory/paging.c @@ -4,47 +4,54 @@ #include <stdint.h> #include <system.h> -struct page_dir *current_page_directory; -struct page_dir kernel_page_directory[1024] __attribute__((aligned(4096))); +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))); -void paging_init(struct page_dir *dir, int user) +void paging_init(u32 *dir, u32 tables[1024][1024], int user) { for (u32 i = 0; i < 1024; i++) { for (u32 j = 0; j < 1024; j++) { - dir->tables[i][j] = + tables[i][j] = ((j * 0x1000) + (i * 0x400000)) | PT_RW | (user ? PT_USER : 0); } } for (u32 i = 0; i < 1024; i++) { - dir[i] = *(struct page_dir *)(((u32)dir->tables[i]) | PD_RW | PD_PRESENT | - (user ? PD_USER : 0)); + dir[i] = ((u32)tables[i]) | PD_RW | PD_PRESENT | (user ? PD_USER : 0); } } extern void KERNEL_END(); -void paging_install(u32 multiboot_address) +void paging_install() { - kernel_page_directory->tables = kernel_page_tables; + paging_init(kernel_page_directory, kernel_page_tables, 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); // /4 - paging_set_used(0, ((u32)KERNEL_END >> 12) + 1); // /4096 + if (!memory_init()) + paging_set_present(0, memory_get_all() >> 3); + paging_set_used(0, ((u32)KERNEL_END >> 12) + 1); paging_enable(); log("Installed paging"); + + // Test! + 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("Malloc test succeeded!"); } -struct page_dir *paging_make_directory(int user) +u32 *paging_make_directory(int user) { - struct page_dir *dir = valloc(1024 * 1024 * 32); - dir->tables = valloc(1024 * 1024 * 32); + u32 *dir = valloc(1024 * 1024 * 32); + u32 *tables = valloc(1024 * 1024 * 32); - paging_init(dir, user); + paging_init(dir, tables, user); return dir; } @@ -60,6 +67,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; @@ -67,10 +75,11 @@ void paging_enable() paging_enabled = 1; } -void paging_switch_directory(struct page_dir *dir) +void paging_switch_directory(u32 *dir) { + current_page_tables = dir; current_page_directory = dir; - asm("mov %0, %%cr3" ::"r"(dir)); + asm("mov %0, %%cr3" ::"r"(current_page_directory)); } void invlpg(u32 addr) @@ -82,7 +91,7 @@ void paging_map(u32 phy, u32 virt, u16 flags) { u32 pdi = virt >> 22; u32 pti = virt >> 12 & 0x03FF; - current_page_directory->tables[pdi][pti] = phy | flags; + current_page_tables[pdi][pti] = phy | flags; invlpg(virt); } @@ -90,21 +99,21 @@ u32 paging_get_phys(u32 virt) { u32 pdi = virt >> 22; u32 pti = (virt >> 12) & 0x03FF; - return current_page_directory->tables[pdi][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 current_page_directory->tables[pdi][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++) { - current_page_directory->tables[i / 1024][i % 1024] |= flag; + current_page_tables[i / 1024][i % 1024] |= flag; invlpg(i * 0x1000); } } @@ -113,7 +122,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_directory->tables[i / 1024][i % 1024] &= ~flag; + current_page_tables[i / 1024][i % 1024] &= ~flag; invlpg(i * 0x1000); } } @@ -138,6 +147,15 @@ 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; @@ -145,8 +163,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_directory->tables[i][j] & PT_PRESENT) || - (current_page_directory->tables[i][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; @@ -165,6 +183,7 @@ u32 paging_alloc_pages(u32 count) { u32 ptr = paging_find_pages(count); paging_set_used(ptr, count); + paging_set_user(ptr, count); return ptr; } @@ -173,7 +192,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_directory->tables[i][j] & PT_USED; + u8 flags = current_page_tables[i][j] & PT_USED; if (flags == 1) n++; } diff --git a/src/kernel/memory/paging.h b/src/kernel/memory/paging.h index 17dde1d..553c0e6 100644 --- a/src/kernel/memory/paging.h +++ b/src/kernel/memory/paging.h @@ -23,22 +23,16 @@ #define PT_GLOBAL 1 << 8 #define PT_USED 1 << 9 -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))); +u32 *current_page_directory; +u32 kernel_page_directory[1024] __attribute__((aligned(4096))); int paging_enabled; -void paging_install(u32 multiboot_address); +void paging_install(); void paging_enable(); void paging_disable(); -struct page_dir *paging_make_directory(int user); -void paging_switch_directory(struct page_dir *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); @@ -52,6 +46,7 @@ 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/system.h b/src/kernel/system.h index f9efe94..57a55fe 100644 --- a/src/kernel/system.h +++ b/src/kernel/system.h @@ -5,6 +5,8 @@ #include <stddef.h> #include <stdint.h> +u32 multiboot_address; + /** * The ASM registers as packed structure */ diff --git a/src/kernel/tasks/process.c b/src/kernel/tasks/process.c index f90df89..900d775 100644 --- a/src/kernel/tasks/process.c +++ b/src/kernel/tasks/process.c @@ -179,7 +179,7 @@ struct process *process_from_pid(u32 pid) struct process *process_make_new() { debug("Making new process %d", pid); - struct process *proc = (struct process *)malloc(sizeof(struct process)); + struct process *proc = (struct process *)valloc(sizeof(struct process)); proc->registers.cs = 0x1B; proc->registers.ds = 0x23; proc->registers.ss = 0x23; diff --git a/src/kernel/tasks/process.h b/src/kernel/tasks/process.h index 92d5ec2..96ef44b 100644 --- a/src/kernel/tasks/process.h +++ b/src/kernel/tasks/process.h @@ -13,7 +13,7 @@ struct mmap { }; struct process { - struct page_dir *cr3; + u32 *cr3; struct regs registers; u32 pid; |