diff options
author | Marvin Borner | 2020-01-16 21:08:43 +0100 |
---|---|---|
committer | GitHub | 2020-01-16 21:08:43 +0100 |
commit | d5d1749257ff8b9aa6b5ace4b4720b484a2860f3 (patch) | |
tree | a2cd4f1c7995e32c1c02b191324fa63f9d30655b | |
parent | 602b98247e9c87e38870e39abf1d8b13aeae5d0f (diff) | |
parent | 366119b53d5148922c5df7c7bd088ed71e95499a (diff) |
Merged fancy userspace paging
-rwxr-xr-x | run | 4 | ||||
-rw-r--r-- | src/kernel/boot.asm | 12 | ||||
-rw-r--r-- | src/kernel/gdt/gdt.c | 17 | ||||
-rw-r--r-- | src/kernel/gdt/gdt.h | 4 | ||||
-rw-r--r-- | src/kernel/interrupts/isr.c | 2 | ||||
-rw-r--r-- | src/kernel/kernel.c | 9 | ||||
-rw-r--r-- | src/kernel/lib/stdlib/liballoc.c | 18 | ||||
-rw-r--r-- | src/kernel/paging/paging.c | 23 | ||||
-rw-r--r-- | src/kernel/paging/paging.h | 2 | ||||
-rw-r--r-- | src/kernel/syscall/syscall.c | 5 | ||||
-rw-r--r-- | src/kernel/system.c | 1 | ||||
-rw-r--r-- | src/userspace/main.c | 3 | ||||
-rw-r--r-- | src/userspace/mlibc/stdio/printf.c | 6 | ||||
-rw-r--r-- | src/userspace/start.asm | 4 |
14 files changed, 78 insertions, 32 deletions
@@ -107,10 +107,10 @@ make_build() { stripped=$(echo "${line}" | sed -r 's/\//_/g') stripped=${stripped#??????} stripped=${stripped%%?}o - compile_with_flags -O3 -c ./"${line}" -I ./src/userspace -o ./build/userspace/"${stripped}" + compile_with_flags -O2 -c ./"${line}" -I ./src/userspace -o ./build/userspace/"${stripped}" done <./build/tmp rm ./build/tmp - compile_with_flags -O3 ./build/userspace/*.o -T ./src/userspace/linker.ld -I ./src/userspace -o ./build/user.bin + compile_with_flags -O2 ./build/userspace/*.o -T ./src/userspace/linker.ld -I ./src/userspace -o ./build/user.bin # Create ISO mkdir -p ./iso/boot/ diff --git a/src/kernel/boot.asm b/src/kernel/boot.asm index 6b95f4c..85d4254 100644 --- a/src/kernel/boot.asm +++ b/src/kernel/boot.asm @@ -29,7 +29,11 @@ section .text global jump_userspace jump_userspace: cli - mov ebx, dword [esp + 4] + push ebp + mov ebp, esp + mov edx, dword [esp + 0xC] + mov esp, edx + push 0xABCDEF mov ax, 0x23 mov ds, ax @@ -48,10 +52,12 @@ section .text push eax push 0x1B - push ebx - mov ebp, ebx + push dword [ebp + 8] iret + pop ebp + ret + section .end_section global ASM_KERNEL_END ASM_KERNEL_END: diff --git a/src/kernel/gdt/gdt.c b/src/kernel/gdt/gdt.c index 49d5ce6..435528a 100644 --- a/src/kernel/gdt/gdt.c +++ b/src/kernel/gdt/gdt.c @@ -2,7 +2,7 @@ #include <kernel/gdt/gdt.h> #include <kernel/system.h> #include <kernel/lib/lib.h> -#include <kernel/lib/stdlib/liballoc.h> +#include <kernel/lib/stdlib.h> struct gdt_entry { unsigned short limit_low; @@ -93,7 +93,7 @@ void gdt_install() gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // Write TSS - tss_write(5, 0x10); + tss_write(5, 0x10, 0x0); // Remove old GDT and install the new changes! gdt_flush(); @@ -101,7 +101,7 @@ void gdt_install() vga_log("Installed Global Descriptor Table"); } -void tss_write(int32_t num, uint16_t ss0) +void tss_write(int32_t num, uint16_t ss0, uint32_t esp0) { uint32_t base = (uint32_t) &tss_entry; uint32_t limit = base + sizeof(tss_entry); @@ -111,13 +111,20 @@ void tss_write(int32_t num, uint16_t ss0) memset(&tss_entry, 0, sizeof(tss_entry)); tss_entry.ss0 = ss0; - tss_entry.iomap_base = sizeof(struct tss_entry_struct); + tss_entry.esp0 = esp0; tss_entry.cs = 0x0b; tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs = 0x13; + + tss_entry.iomap_base = sizeof(struct tss_entry_struct); } void tss_flush(void) { - tss_entry.esp0 = 4096 + (uint32_t) kmalloc(4096); + tss_entry.esp0 = 4096 + (uint32_t) umalloc(4096); asm volatile ("ltr %%ax": : "a" (0x2B)); +} + +void set_kernel_stack(uintptr_t stack) +{ + tss_entry.esp0 = stack; }
\ No newline at end of file diff --git a/src/kernel/gdt/gdt.h b/src/kernel/gdt/gdt.h index da36445..0e77103 100644 --- a/src/kernel/gdt/gdt.h +++ b/src/kernel/gdt/gdt.h @@ -6,8 +6,10 @@ */ void gdt_install(); -void tss_write(int32_t num, uint16_t ss0); +void tss_write(int32_t num, uint16_t ss0, uint32_t esp0); void tss_flush(); +void set_kernel_stack(uintptr_t stack); + #endif diff --git a/src/kernel/interrupts/isr.c b/src/kernel/interrupts/isr.c index eb932b2..8b2a9e5 100644 --- a/src/kernel/interrupts/isr.c +++ b/src/kernel/interrupts/isr.c @@ -3,6 +3,7 @@ #include <kernel/system.h> #include <kernel/lib/string.h> #include <kernel/lib/stdio.h> +#include <kernel/paging/paging.h> // Install ISRs in IDT void isrs_install() @@ -116,6 +117,7 @@ void fault_handler(struct regs *r) r->eip, r->eax, r->ebx, r->ecx, r->edx, r->esp, faulting_address, r->eflags, r->err_code, r->int_no, exception_messages[r->int_no] ); + serial_printf("%d", paging_get_flags(faulting_address)); // halt_loop(); // Idk loop? char *message = (char *) exception_messages[r->int_no]; strcat(message, " Exception"); diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index d8f8c66..b2b7ada 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -60,18 +60,19 @@ void kernel_main() info("Switching to user mode..."); syscalls_install(); tss_flush(); - uint32_t userspace = paging_alloc_pages(10); - paging_set_user(userspace, 10); + uint32_t userspace = (uint32_t) umalloc(8096); + paging_switch_directory(1); if (boot_drive_id == 0xE0) { char *user_p[] = {"USER.BIN"}; struct iso9660_entity *user_e = ISO9660_get(user_p, 1); if (!user_e) panic("Userspace binary not found!"); ATAPI_granular_read(1 + (user_e->length / 2048), user_e->lba, (uint8_t *) (userspace + 4096)); kfree(user_e); - jump_userspace(userspace + 4096); + jump_userspace(userspace + 4096, userspace + 4096); } else { marfs_read_whole_file(4, (uint8_t *) (userspace + 4096)); - jump_userspace(userspace + 4096); + paging_switch_directory(1); + jump_userspace(userspace + 4096, userspace + 4096); } panic("This should NOT happen!"); diff --git a/src/kernel/lib/stdlib/liballoc.c b/src/kernel/lib/stdlib/liballoc.c index e05cc24..c1a5de1 100644 --- a/src/kernel/lib/stdlib/liballoc.c +++ b/src/kernel/lib/stdlib/liballoc.c @@ -472,6 +472,7 @@ void *krealloc(void *p, size_t size) void *umalloc(size_t req_size) { + paging_switch_directory(1); int started_bet = 0; unsigned long long best_size = 0; void *p = NULL; @@ -497,6 +498,7 @@ void *umalloc(size_t req_size) l_mem_root_user = allocate_new_page(size, 1); if (l_mem_root_user == NULL) { liballoc_unlock(); + paging_switch_directory(0); return NULL; } } @@ -554,6 +556,7 @@ void *umalloc(size_t req_size) p = (void *) ((uintptr_t) (maj->first) + sizeof(struct liballoc_minor)); ALIGN(p); liballoc_unlock(); + paging_switch_directory(0); return p; } @@ -576,6 +579,7 @@ void *umalloc(size_t req_size) p = (void *) ((uintptr_t) (maj->first) + sizeof(struct liballoc_minor)); ALIGN(p); liballoc_unlock(); + paging_switch_directory(0); return p; } @@ -601,6 +605,7 @@ void *umalloc(size_t req_size) p = (void *) ((uintptr_t) min + sizeof(struct liballoc_minor)); ALIGN(p); liballoc_unlock(); + paging_switch_directory(0); return p; } } @@ -626,6 +631,7 @@ void *umalloc(size_t req_size) p = (void *) ((uintptr_t) new_min + sizeof(struct liballoc_minor)); ALIGN(p); liballoc_unlock(); + paging_switch_directory(0); return p; } } @@ -649,16 +655,19 @@ void *umalloc(size_t req_size) liballoc_unlock(); + paging_switch_directory(0); return NULL; } void ufree(void *ptr) { + paging_switch_directory(1); struct liballoc_minor *min; struct liballoc_major *maj; if (ptr == NULL) { l_warning_count_user += 1; + paging_switch_directory(0); return; } @@ -677,6 +686,7 @@ void ufree(void *ptr) } liballoc_unlock(); + paging_switch_directory(0); return; } @@ -703,10 +713,12 @@ void ufree(void *ptr) } } liballoc_unlock(); + paging_switch_directory(0); } void *ucalloc(size_t nobj, size_t size) { + paging_switch_directory(1); int real_size; void *p; @@ -716,17 +728,20 @@ void *ucalloc(size_t nobj, size_t size) liballoc_memset(p, 0, real_size); + paging_switch_directory(0); return p; } void *urealloc(void *p, size_t size) { + paging_switch_directory(1); void *ptr; struct liballoc_minor *min; unsigned int real_size; if (size == 0) { ufree(p); + paging_switch_directory(0); return NULL; } @@ -746,6 +761,7 @@ void *urealloc(void *p, size_t size) } liballoc_unlock(); + paging_switch_directory(0); return NULL; } @@ -754,6 +770,7 @@ void *urealloc(void *p, size_t size) if (real_size >= size) { min->req_size = size; liballoc_unlock(); + paging_switch_directory(0); return p; } @@ -763,5 +780,6 @@ void *urealloc(void *p, size_t size) liballoc_memcpy(ptr, p, real_size); ufree(p); + paging_switch_directory(0); return ptr; }
\ No newline at end of file diff --git a/src/kernel/paging/paging.c b/src/kernel/paging/paging.c index 6f7833d..c4a2940 100644 --- a/src/kernel/paging/paging.c +++ b/src/kernel/paging/paging.c @@ -12,11 +12,8 @@ uint32_t kernel_page_tables[1024][1024] __attribute__((aligned(4096))); uint32_t user_page_directory[1024] __attribute__((aligned(4096))); uint32_t user_page_tables[1024][1024] __attribute__((aligned(4096))); -void paging_install() +void paging_init() { - current_page_directory = kernel_page_directory; - current_page_tables = kernel_page_tables; - for (uint32_t i = 0; i < 1024; i++) { for (uint32_t j = 0; j < 1024; j++) { current_page_tables[i][j] = ((j * 0x1000) + (i * 0x400000)) | PT_RW; @@ -27,7 +24,19 @@ void paging_install() current_page_directory[i] = ((uint32_t) current_page_tables[i]) | PD_RW | PD_PRESENT; } - paging_set_present(0, memory_get_all() >> 2); // /4 + paging_set_present(0, memory_get_all() >> 3); // /4 +} + +void paging_install() +{ + // User paging + paging_switch_directory(1); + paging_init(); + paging_set_user(0, memory_get_all() >> 3); + + // Kernel paging + paging_switch_directory(0); + paging_init(); paging_set_used(0, ((uint32_t) ASM_KERNEL_END >> 12) + 1); // /4096 paging_enable(); @@ -44,9 +53,9 @@ void paging_disable() paging_enabled = 0; } -void paging_switch_directory() +void paging_switch_directory(int user) { - if (current_page_tables == kernel_page_tables) { + if (user == 1) { current_page_tables = user_page_tables; current_page_directory = user_page_directory; } else { diff --git a/src/kernel/paging/paging.h b/src/kernel/paging/paging.h index 684c3b2..b75bbe3 100644 --- a/src/kernel/paging/paging.h +++ b/src/kernel/paging/paging.h @@ -29,7 +29,7 @@ void paging_enable(); void paging_disable(); -void paging_switch_directory(); +void paging_switch_directory(int user); void paging_map(uint32_t phy, uint32_t virt, uint16_t flags); diff --git a/src/kernel/syscall/syscall.c b/src/kernel/syscall/syscall.c index 7ca7f99..93abc83 100644 --- a/src/kernel/syscall/syscall.c +++ b/src/kernel/syscall/syscall.c @@ -3,9 +3,12 @@ #include <kernel/interrupts/interrupts.h> #include <kernel/system.h> #include <kernel/lib/stdio.h> +#include <kernel/paging/paging.h> typedef uint32_t (*syscall_func)(unsigned int, ...); +extern void jump_userspace(); + uint32_t (*syscalls[])() = { [0] = (uint32_t (*)()) halt_loop, // DEBUG! [1] = sys_write, @@ -19,6 +22,7 @@ uint32_t (*syscalls[])() = { void syscall_handler(struct regs *r) { + paging_switch_directory(0); serial_printf("Received syscall!"); if (r->eax >= sizeof(syscalls) / sizeof(*syscalls)) @@ -31,6 +35,7 @@ void syscall_handler(struct regs *r) //serial_printf("[SYSCALL] %d (0x%x) 0x%x 0x%x 0x%x 0x%x 0x%x", r->eax, location, r->ebx, r->ecx, r->edx, r->esi, r->edi); r->eax = location(r->ebx, r->ecx, r->edx, r->esi, r->edi); + paging_switch_directory(1); } void syscalls_install() diff --git a/src/kernel/system.c b/src/kernel/system.c index c37c890..c01fb46 100644 --- a/src/kernel/system.c +++ b/src/kernel/system.c @@ -106,7 +106,6 @@ void assert(int x) void halt_loop() { - serial_printf("\n!!! HALT !!!"); asm ("cli"); loop: asm ("hlt"); diff --git a/src/userspace/main.c b/src/userspace/main.c index 6149573..c2307a8 100644 --- a/src/userspace/main.c +++ b/src/userspace/main.c @@ -14,6 +14,9 @@ void user_main() char text[] = "> Successfully switched to usermode!\n"; printf(text); + // TODO: PLEASE + printf("If this message shows up, I'll be happy.\n"); + while (1) { char *input = readline(); if (starts_with(input, "ls")) { diff --git a/src/userspace/mlibc/stdio/printf.c b/src/userspace/mlibc/stdio/printf.c index b582897..5617d03 100644 --- a/src/userspace/mlibc/stdio/printf.c +++ b/src/userspace/mlibc/stdio/printf.c @@ -1,14 +1,10 @@ #include <stdarg.h> #include <mlibc/stdio.h> -#include <mlibc/string.h> -#include <mlibc/stdlib.h> void printf(const char *fmt, ...) { - char *format = (char *) malloc(strlen(fmt)); - strcpy(format, fmt); va_list args; va_start(args, fmt); - vprintf(format, args); + vprintf(fmt, args); va_end(args); }
\ No newline at end of file diff --git a/src/userspace/start.asm b/src/userspace/start.asm index 7348825..c6bb2a0 100644 --- a/src/userspace/start.asm +++ b/src/userspace/start.asm @@ -4,6 +4,4 @@ section .text global _start extern user_main _start: - mov esp, ebp - call user_main - jmp $
\ No newline at end of file + call user_main
\ No newline at end of file |