diff options
| author | Aleksa Vuckovic <aleksav013@gmail.com> | 2022-09-05 23:54:12 +0200 |
|---|---|---|
| committer | Aleksa Vuckovic <aleksav013@gmail.com> | 2022-09-07 17:46:10 +0200 |
| commit | 956bb743a3ba6939aaff2372fc45628cda6a9840 (patch) | |
| tree | 0d1fd304eb584c892e28e43bbc851cf66786d9da | |
| parent | 59f86fe8dd237e50c7fea03b506125e3abff0157 (diff) | |
userspace finally working
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | kernel/include/heap.h | 6 | ||||
| -rw-r--r-- | kernel/include/paging.h | 1 | ||||
| -rw-r--r-- | kernel/src/boot/boot.S | 2 | ||||
| -rw-r--r-- | kernel/src/boot/boot64.S | 12 | ||||
| -rw-r--r-- | kernel/src/cpu/gdt.c | 12 | ||||
| -rw-r--r-- | kernel/src/cpu/irq_stub.S | 4 | ||||
| -rw-r--r-- | kernel/src/cpu/registers.c | 57 | ||||
| -rw-r--r-- | kernel/src/cpu/tss.c | 9 | ||||
| -rw-r--r-- | kernel/src/main.c | 9 | ||||
| -rw-r--r-- | kernel/src/mem/paging.c | 14 | ||||
| -rw-r--r-- | kernel/src/sys/userspace_asm.S | 24 |
13 files changed, 114 insertions, 41 deletions
@@ -3,6 +3,5 @@ kernel.iso **/*.o **/*.d isodir -xbochs.log +*log bx_enh_dbg.ini -serial.log @@ -75,6 +75,6 @@ endif clean: @find -name "*.o" -exec rm {} \; @find -name "*.d" -exec rm {} \; - @rm -f kernel.iso $K/kernel.bin xbochs.log bx_enh_dbg.ini + @rm -f kernel.iso $K/kernel.bin xbochs.log bx_enh_dbg.ini log serial.log @rm -rf isodir @$(MAKE) umount diff --git a/kernel/include/heap.h b/kernel/include/heap.h index 62d3b6f..b2d9a00 100644 --- a/kernel/include/heap.h +++ b/kernel/include/heap.h @@ -3,9 +3,9 @@ #include <types.h> -#define HEAP_VMEM_ADDR 0xc1000000 -#define HEAP_PMEM_ADDR 0x01000000 -#define HEAP_SIZE 0x01000000 +#define HEAP_VMEM_ADDR 0xc2000000 +#define HEAP_PMEM_ADDR 0x02000000 +#define HEAP_SIZE 0x02000000 #define HEAP_BLOCK_SIZE 0x00000010 struct kheapblock_t { diff --git a/kernel/include/paging.h b/kernel/include/paging.h index 7c9fcd5..8f69224 100644 --- a/kernel/include/paging.h +++ b/kernel/include/paging.h @@ -6,6 +6,7 @@ #define PAGE_SIZE 0x00200000 #define FLAG_PRESENT 0x1 #define FLAG_WRITABLE 0x2 +#define FLAG_USER 0x4 #define FLAG_HUGE 0x80 #define KERNEL_VMA 0xc0000000 diff --git a/kernel/src/boot/boot.S b/kernel/src/boot/boot.S index e0c5326..a96be00 100644 --- a/kernel/src/boot/boot.S +++ b/kernel/src/boot/boot.S @@ -145,7 +145,7 @@ no_long_mode: // stack stack_bottom: - .skip 4096*4 + .skip 4096*16 stack_top: diff --git a/kernel/src/boot/boot64.S b/kernel/src/boot/boot64.S index 68eae38..cc79c36 100644 --- a/kernel/src/boot/boot64.S +++ b/kernel/src/boot/boot64.S @@ -4,12 +4,12 @@ .global begin_long_mode begin_long_mode: // reload segment registers - mov $0x10, %eax - mov %eax, %ss - mov %eax, %ds - mov %eax, %es - mov %eax, %fs - mov %eax, %gs + mov $0x10, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %ss + mov %ax, %fs + mov %ax, %gs popq %rdi popq %rsi diff --git a/kernel/src/cpu/gdt.c b/kernel/src/cpu/gdt.c index b4f1ec0..7ce51f1 100644 --- a/kernel/src/cpu/gdt.c +++ b/kernel/src/cpu/gdt.c @@ -23,10 +23,13 @@ void add_gdt_tss(uint32_t num, uint64_t offset, uint32_t limit, uint8_t access, void reload_gdt() { __asm__ volatile ( + // reload segment registers "mov $0x10, %ax;" "mov %ax, %ds;" "mov %ax, %es;" "mov %ax, %ss;" + "mov %ax, %fs;" + "mov %ax, %gs;" ); } @@ -42,12 +45,11 @@ void init_gdt() gdt_pointer.size = sizeof(gdt) - 1; add_gdt_entry(0, 0, 0, 0, 0); - add_gdt_entry(1, 0, 0xfffff, 0x9a, 0xa); - add_gdt_entry(2, 0, 0xfffff, 0x92, 0xc); - add_gdt_entry(3, 0, 0xfffff, 0xfa, 0xa); - add_gdt_entry(4, 0, 0xfffff, 0xf2, 0xc); + add_gdt_entry(1, 0, 0xfffff, 0x9a, 0xa); // code ring0 + add_gdt_entry(2, 0, 0xfffff, 0x92, 0xc); // data ring0 + add_gdt_entry(3, 0, 0xfffff, 0xf2, 0xc); // data ring3 + add_gdt_entry(4, 0, 0xfffff, 0xfa, 0xa); // code ring3 add_gdt_tss(5, (uint64_t)&tss, sizeof(tss_type), 0x89, 0); load_gdt(&gdt_pointer); - init_tss(); } diff --git a/kernel/src/cpu/irq_stub.S b/kernel/src/cpu/irq_stub.S index 9b2b2d8..5a8149c 100644 --- a/kernel/src/cpu/irq_stub.S +++ b/kernel/src/cpu/irq_stub.S @@ -24,7 +24,6 @@ pop %rax .endm - .macro isr_no_error number .global isr\number isr\number: @@ -38,11 +37,12 @@ isr\number: .macro isr_error number .global isr\number isr\number: - pop %rdi pushall + mov 0x50(%rsp), %rdi cld call isr\number\()_handler popall + add $8, %rsp iretq .endm diff --git a/kernel/src/cpu/registers.c b/kernel/src/cpu/registers.c new file mode 100644 index 0000000..7dc22d4 --- /dev/null +++ b/kernel/src/cpu/registers.c @@ -0,0 +1,57 @@ +#include <types.h> +#include <libk/stdio.h> + +struct registers_t { + uint64_t rax; + uint64_t rbx; + uint64_t rcx; + uint64_t rdx; + uint64_t rsi; + uint64_t rdi; + uint64_t rsp; + uint64_t rbp; + uint64_t r8; + uint64_t r9; + uint64_t r10; + uint64_t r11; + uint64_t r12; + uint64_t r13; + uint64_t r14; + uint64_t r15; + uint64_t rip; + uint16_t cs; + uint16_t ds; + uint16_t ss; + uint16_t es; + uint16_t fs; + uint16_t gs; +}; +typedef struct registers_t registers_t; + +void print_reg(registers_t* registers) +{ + printf("printing registers:"); + printf("rax: %x", registers->rax); + printf("rbx: %x", registers->rbx); + printf("rcx: %x", registers->rcx); + printf("rdx: %x", registers->rdx); + printf("rsi: %x", registers->rsi); + printf("rdi: %x", registers->rdi); + printf("rsp: %x", registers->rsp); + printf("rbp: %x", registers->rbp); + printf("r8: %x", registers->r8); + printf("r9: %x", registers->r9); + printf("r10: %x", registers->r10); + printf("r11: %x", registers->r11); + printf("r12: %x", registers->r12); + printf("r13: %x", registers->r13); + printf("r14: %x", registers->r14); + printf("r15: %x", registers->r15); + printf("rip: %x", registers->rip); + printf("cs: %x", registers->cs); + printf("ds: %x", registers->ds); + printf("ss: %x", registers->ss); + printf("es: %x", registers->es); + printf("fs: %x", registers->fs); + printf("gs: %x", registers->gs); +} diff --git a/kernel/src/cpu/tss.c b/kernel/src/cpu/tss.c index c7f9dc2..843c114 100644 --- a/kernel/src/cpu/tss.c +++ b/kernel/src/cpu/tss.c @@ -1,15 +1,22 @@ #include <tss.h> +#include <heap.h> +#include <libk/stdio.h> tss_type tss; void load_tss() { - __asm__ volatile ("mov $0x28, %ax; ltr %ax;"); + __asm__ volatile ("push %rax; mov $0x28, %ax; ltr %ax; pop %rax;"); } void init_tss() { tss.iopb = sizeof(tss_type); + uint64_t stack = (uint64_t)kalloc(4096*4); + stack = (uint64_t)kalloc(4096*4) + 8; + tss.rsp0_low = (uint32_t)stack; + tss.rsp0_high = (uint32_t)(stack >> 32); load_tss(); + printf("rsp0 addr in tss: 0x%x\n", stack); } diff --git a/kernel/src/main.c b/kernel/src/main.c index dce9c05..4b0d62a 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -22,14 +22,15 @@ int kernel_main(mb2_tag_header* multiboot_bootinfo, uint32_t multiboot_magic) init_serial(); init_gdt(); init_paging(); - init_idt(); init_timer(TICKS_PER_SECOND); + init_idt(); init_heap(); read_mb2(multiboot_bootinfo, multiboot_magic); - disc_init(); - ext2_init(); + init_tss(); +// disc_init(); +// ext2_init(); // ls(path_to_inode("/")); -// jump_userspace(); + jump_userspace(); for(;;) { __asm__ volatile ("hlt;"); diff --git a/kernel/src/mem/paging.c b/kernel/src/mem/paging.c index 630fb6d..19a2c3a 100644 --- a/kernel/src/mem/paging.c +++ b/kernel/src/mem/paging.c @@ -45,15 +45,15 @@ void map_addr(uint64_t virt, uint64_t phys, uint32_t flags) void init_paging(void) { - page_table_lvl4[0] = (uint64_t)page_table_lvl3 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA; - page_table_lvl3[0] = (uint64_t)page_table_lvl2_0 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA; - page_table_lvl3[1] = (uint64_t)page_table_lvl2_1 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA; - page_table_lvl3[2] = (uint64_t)page_table_lvl2_2 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA; - page_table_lvl3[3] = (uint64_t)page_table_lvl2_3 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA; + page_table_lvl4[0] = (uint64_t)page_table_lvl3 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER - KERNEL_VMA; + page_table_lvl3[0] = (uint64_t)page_table_lvl2_0 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER - KERNEL_VMA; + page_table_lvl3[1] = (uint64_t)page_table_lvl2_1 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER - KERNEL_VMA; + page_table_lvl3[2] = (uint64_t)page_table_lvl2_2 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER - KERNEL_VMA; + page_table_lvl3[3] = (uint64_t)page_table_lvl2_3 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER - KERNEL_VMA; // higher half map first 6mb for (size_t i = 0; i < 3; i++) { - map_addr(KERNEL_VMA + PAGE_SIZE * i, 0x00000000 + PAGE_SIZE * i, FLAG_PRESENT + FLAG_WRITABLE + FLAG_HUGE); + map_addr(KERNEL_VMA + PAGE_SIZE * i, 0x00000000 + PAGE_SIZE * i, FLAG_PRESENT + FLAG_WRITABLE + FLAG_USER + FLAG_HUGE); } load_pt_lvl4(page_table_lvl4); @@ -65,7 +65,7 @@ void page_fault(uint64_t error) uint64_t addr; __asm__ volatile ("mov %%cr2, %0;" : "=r"(addr) : : "memory"); - map_addr(addr, addr, FLAG_PRESENT | FLAG_WRITABLE | FLAG_HUGE); + map_addr(addr, addr, FLAG_PRESENT | FLAG_WRITABLE | FLAG_USER | FLAG_HUGE); printf("address: 0x%x, error code: %d\n", addr, error); } diff --git a/kernel/src/sys/userspace_asm.S b/kernel/src/sys/userspace_asm.S index 5838051..c722df0 100644 --- a/kernel/src/sys/userspace_asm.S +++ b/kernel/src/sys/userspace_asm.S @@ -4,17 +4,23 @@ .global jump_userspace jump_userspace: - mov $0x23, %ax + mov $0x1b, %ax mov %ax, %ds mov %ax, %es mov %ax, %fs mov %ax, %gs - mov %esp, %eax - push $0x23 - push %rax - pushf - push $0x1b - sub $8, %rsp - movabs $begin_userspace, %rsp - iretq + mov $0xc0000082, %rcx + wrmsr + mov $0xc0000080, %rcx + rdmsr + or $1, %eax + wrmsr + mov $0xc0000081, %rcx + rdmsr + mov $0x00100008, %edx + wrmsr + + mov $begin_userspace, %ecx + mov $0x202, %r11 + sysretq |
