diff --git a/kernel/src/main.c b/kernel/src/main.c index b5b6fa0..02b8536 100755 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -63,6 +63,8 @@ static void hcf(void) { } } + + int init() { asm("int $0x80"); while (1) @@ -71,6 +73,8 @@ int init() { struct limine_framebuffer *fb; +char kstack[8192]; + // The following will be our kernel's entry point. // If renaming kmain() to something else, make sure to change the // linker script accordingly. @@ -99,7 +103,7 @@ void kmain(void) { printf("\n Soaplin 1.0-sild is booting up your computer...\n\n"); //printf("Physical kernel EP: %p", entrypoint_request.entry); - gdt_init(); + gdt_init(&kstack[8192]); idt_init(); sse_init(); @@ -108,15 +112,17 @@ void kmain(void) { vmm_init(); pit_init(1000); - sched_init(); + //sched_init(); + //user_init(); - uint64_t *mem = pmm_request_page(); + uint8_t *mem = pmm_request_page(); mem[0] = 0xCD; mem[1] = 0x80; - mem[2] = 0xFE; - mem[3] = 0xEB; - sched_process *proc = sched_create("Init", 0x1000, SCHED_USER_PROCESS); - vmm_map(proc->pm, 0x1000, (uint64_t)mem, VMM_PRESENT | VMM_USER); + mem[2] = 0xF4; + //mem[3] = 0xFE; + pagemap_t* pm = vmm_alloc_pm(); + vmm_map(pm, 0x1000, (uint64_t)mem, VMM_PRESENT | VMM_USER); + sched_process *proc = sched_create("Init", 0x1000, pm, SCHED_USER_PROCESS); log("kernel - Soaplin initialized sucessfully.\n"); while (1) diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c index 6d905e2..f7df03e 100755 --- a/kernel/src/mm/vmm.c +++ b/kernel/src/mm/vmm.c @@ -3,6 +3,7 @@ #include "mm/pmm.h" #include "mm/memop.h" #include "sys/log.h" +#include "vmm.h" #include @@ -148,12 +149,26 @@ void vmm_load_pagemap(pagemap_t *pm) { } static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry, uint64_t flags) { - if (level[entry] & 1) - return HIGHER_HALF(PTE_GET_ADDR(level[entry])); - uint64_t *pml = HIGHER_HALF(pmm_request_page()); - memset(pml, 0, PMM_PAGE_SIZE); - level[entry] = (uint64_t)PHYSICAL(pml) | (flags & 0xFFF); // N'ajoute que les flags pertinents - return pml; + if (!(level[entry] & 1)){ + uint64_t *pml = HIGHER_HALF(pmm_request_page()); + memset(pml, 0, PMM_PAGE_SIZE); + level[entry] = (uint64_t)PHYSICAL(pml); + } + level[entry] |= (flags & 0xFFF); // N'ajoute que les flags pertinents + return HIGHER_HALF(PTE_GET_ADDR(level[entry])); +} + +uint64_t vmm_get_flags(pagemap_t* pm, uint64_t vaddr) { + uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; + uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; + uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; + uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; + + uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, 0); + uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0); + uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0); + + return pml1[pml1_entry] & 0x7000000000000FFF; } void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { diff --git a/kernel/src/mm/vmm.h b/kernel/src/mm/vmm.h index 97239b4..4e4c8aa 100755 --- a/kernel/src/mm/vmm.h +++ b/kernel/src/mm/vmm.h @@ -37,5 +37,6 @@ pagemap_t *vmm_alloc_pm(); void vmm_init(); void vmm_release_pm(pagemap_t *pm); void vmm_load_pagemap(pagemap_t *pm); +uint64_t vmm_get_flags(pagemap_t* pm, uint64_t vaddr); void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags); void vmm_unmap(pagemap_t *pm, uint64_t vaddr) ; \ No newline at end of file diff --git a/kernel/src/sched/sched.c b/kernel/src/sched/sched.c index b39c2fc..02f31ab 100755 --- a/kernel/src/sched/sched.c +++ b/kernel/src/sched/sched.c @@ -29,7 +29,7 @@ void sched_init() { "mode.\n"); } -sched_process *sched_create(char *name, uint64_t entry_point, uint32_t flags) +sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t* pm, uint32_t flags) { // TODO: implement a separate strlen function // as there's like 4 strlen impls in the kernel. @@ -43,12 +43,13 @@ sched_process *sched_create(char *name, uint64_t entry_point, uint32_t flags) memcpy(proc->name, name, i); proc->pid = current_pid; proc->type = SCHED_RUNNING; + proc->flags = flags; // We are about to setup the registers ourself. // If it's broken, it's a boom in the ass of your computer // (and a CPU exception) - proc->pm = vmm_alloc_pm(); + proc->pm = pm; uint64_t *stack_phys = pmm_request_page(); uint64_t *stack_virt = (uint64_t*)0x40000000; @@ -107,5 +108,5 @@ void schedule(registers_t *regs) memcpy(regs, &curr_proc->regs, sizeof(registers_t)); // Finally, load our pagemap - //vmm_load_pagemap(curr_proc->pm); + vmm_load_pagemap(curr_proc->pm); } \ No newline at end of file diff --git a/kernel/src/sched/sched.h b/kernel/src/sched/sched.h index f5d2b04..db14199 100755 --- a/kernel/src/sched/sched.h +++ b/kernel/src/sched/sched.h @@ -16,6 +16,7 @@ typedef struct _sched_process { char name[128]; int pid; int type; + int flags; registers_t regs; pagemap_t *pm; @@ -34,6 +35,6 @@ extern sched_process *proc_list; //extern sched_process *idle_process; void sched_init(); -sched_process *sched_create(char *name, uint64_t entry_point, uint32_t flags); +sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, uint32_t flags); void sched_exit(sched_process *proc); void schedule(registers_t *regs); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/gdt.c b/kernel/src/sys/arch/x86_64/gdt.c index 0559625..d6d712a 100755 --- a/kernel/src/sys/arch/x86_64/gdt.c +++ b/kernel/src/sys/arch/x86_64/gdt.c @@ -2,6 +2,7 @@ #include #include #include +#include gdt_table def_table = { { @@ -25,10 +26,10 @@ gdt_table def_table = { tssr tss_list[256]; // One tssr per CPU -void gdt_init() { +void gdt_init( char* kstack ) { // TODO: adapt for multiprocessor kernel - tss_list[0].iopb = sizeof(tssr); + tss_list[0].rsp[0] = (uint64_t)kstack; uintptr_t tss = (uintptr_t)&tss_list[0]; def_table.tss_entry.length = sizeof(tss_entry); diff --git a/kernel/src/sys/arch/x86_64/gdt.h b/kernel/src/sys/arch/x86_64/gdt.h index 8e51e53..6004d06 100755 --- a/kernel/src/sys/arch/x86_64/gdt.h +++ b/kernel/src/sys/arch/x86_64/gdt.h @@ -26,7 +26,7 @@ typedef struct { typedef struct { uint32_t resv; - uint64_t rsp[3]; + uint64_t rsp[4]; uint64_t resv1; uint64_t ist[7]; uint64_t resv2; @@ -34,4 +34,4 @@ typedef struct { uint16_t iopb; } __attribute__((packed)) tssr; // Per CPU -void gdt_init(); \ No newline at end of file +void gdt_init(char* kstack); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/idt.c b/kernel/src/sys/arch/x86_64/idt.c index 37b058a..e556eb4 100755 --- a/kernel/src/sys/arch/x86_64/idt.c +++ b/kernel/src/sys/arch/x86_64/idt.c @@ -29,10 +29,16 @@ void idt_init() { idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1; for (uint16_t vector = 0; vector <= 256; vector++) { + if (vector == 0x80) + continue; // We skip the syscall handler, since it should be called from user space. idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); vectors[vector] = 1; } + uint16_t vector = 0x80; + idt_set_descriptor(vector, isr_stub_table[vector], 0xEE); + vectors[vector] = 1; + pic_init(); pic_unmask_irq(1); diff --git a/kernel/src/sys/arch/x86_64/interrupts.c b/kernel/src/sys/arch/x86_64/interrupts.c index d243629..1c791e3 100755 --- a/kernel/src/sys/arch/x86_64/interrupts.c +++ b/kernel/src/sys/arch/x86_64/interrupts.c @@ -39,6 +39,14 @@ void exception_handler(registers_t *regs) { if (regs->int_no < 32) { //panic(kmode_cpu_exception, regs); log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip, regs->err_code); + + if(regs->int_no == 0xe) { + uint64_t cr2; + asm ("mov %%cr2, %0" : "=r"(cr2)); + log("ints - PF: Faulting location: %p\n", cr2); + log("ints - PF: Faulting page flags: %p\n", vmm_get_flags(vmm_current_pm, cr2)); + } + dump_backtrace(regs); asm ("cli"); while (1) @@ -63,7 +71,9 @@ void exception_handler(registers_t *regs) { } else if (regs->int_no == 0x80) { - log("syscall - Hello World! Current process: %s", curr_proc->name); + log("syscall - Hello World! Current process: %s\n", curr_proc->name); + if (curr_proc->flags == SCHED_USER_PROCESS) + log("syscall - Btw we made it to userspace, baby!\n", curr_proc->name); } //logln(info, "arch/ints", "Received interrupt %d\n", regs->int_no); pic_ack(regs->int_no - 32); diff --git a/kernel/zgpAU9u.patch b/kernel/zgpAU9u.patch new file mode 100644 index 0000000..b6aecfb --- /dev/null +++ b/kernel/zgpAU9u.patch @@ -0,0 +1,208 @@ +diff --git a/kernel/src/main.c b/kernel/src/main.c +index b5b6fa0..2d326ef 100755 +--- a/kernel/src/main.c ++++ b/kernel/src/main.c +@@ -63,6 +63,8 @@ static void hcf(void) { + } + } + ++ ++ + int init() { + asm("int $0x80"); + while (1) +@@ -71,6 +73,8 @@ int init() { + + struct limine_framebuffer *fb; + ++char kstack[8192]; ++ + // The following will be our kernel's entry point. + // If renaming kmain() to something else, make sure to change the + // linker script accordingly. +@@ -99,7 +103,7 @@ void kmain(void) { + printf("\n Soaplin 1.0-sild is booting up your computer...\n\n"); + //printf("Physical kernel EP: %p", entrypoint_request.entry); + +- gdt_init(); ++ gdt_init(&kstack[8192]); + idt_init(); + + sse_init(); +@@ -115,8 +119,9 @@ void kmain(void) { + mem[1] = 0x80; + mem[2] = 0xFE; + mem[3] = 0xEB; +- sched_process *proc = sched_create("Init", 0x1000, SCHED_USER_PROCESS); +- vmm_map(proc->pm, 0x1000, (uint64_t)mem, VMM_PRESENT | VMM_USER); ++ pagemap_t* pm = vmm_alloc_pm(); ++ vmm_map(pm, 0x1000, (uint64_t)mem, VMM_PRESENT | VMM_USER); ++ sched_process *proc = sched_create("Init", 0x1000, pm, SCHED_USER_PROCESS); + + log("kernel - Soaplin initialized sucessfully.\n"); + while (1) +diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c +index 6d905e2..f7df03e 100755 +--- a/kernel/src/mm/vmm.c ++++ b/kernel/src/mm/vmm.c +@@ -3,6 +3,7 @@ + #include "mm/pmm.h" + #include "mm/memop.h" + #include "sys/log.h" ++#include "vmm.h" + #include + + +@@ -148,12 +149,26 @@ void vmm_load_pagemap(pagemap_t *pm) { + } + + static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry, uint64_t flags) { +- if (level[entry] & 1) +- return HIGHER_HALF(PTE_GET_ADDR(level[entry])); +- uint64_t *pml = HIGHER_HALF(pmm_request_page()); +- memset(pml, 0, PMM_PAGE_SIZE); +- level[entry] = (uint64_t)PHYSICAL(pml) | (flags & 0xFFF); // N'ajoute que les flags pertinents +- return pml; ++ if (!(level[entry] & 1)){ ++ uint64_t *pml = HIGHER_HALF(pmm_request_page()); ++ memset(pml, 0, PMM_PAGE_SIZE); ++ level[entry] = (uint64_t)PHYSICAL(pml); ++ } ++ level[entry] |= (flags & 0xFFF); // N'ajoute que les flags pertinents ++ return HIGHER_HALF(PTE_GET_ADDR(level[entry])); ++} ++ ++uint64_t vmm_get_flags(pagemap_t* pm, uint64_t vaddr) { ++ uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; ++ uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; ++ uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; ++ uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; ++ ++ uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, 0); ++ uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0); ++ uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0); ++ ++ return pml1[pml1_entry] & 0x7000000000000FFF; + } + + void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { +diff --git a/kernel/src/mm/vmm.h b/kernel/src/mm/vmm.h +index 97239b4..4e4c8aa 100755 +--- a/kernel/src/mm/vmm.h ++++ b/kernel/src/mm/vmm.h +@@ -37,5 +37,6 @@ pagemap_t *vmm_alloc_pm(); + void vmm_init(); + void vmm_release_pm(pagemap_t *pm); + void vmm_load_pagemap(pagemap_t *pm); ++uint64_t vmm_get_flags(pagemap_t* pm, uint64_t vaddr); + void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags); + void vmm_unmap(pagemap_t *pm, uint64_t vaddr) ; +\ No newline at end of file +diff --git a/kernel/src/sched/sched.c b/kernel/src/sched/sched.c +index b39c2fc..f09da0d 100755 +--- a/kernel/src/sched/sched.c ++++ b/kernel/src/sched/sched.c +@@ -29,7 +29,7 @@ void sched_init() { + "mode.\n"); + } + +-sched_process *sched_create(char *name, uint64_t entry_point, uint32_t flags) ++sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t* pm, uint32_t flags) + { + // TODO: implement a separate strlen function + // as there's like 4 strlen impls in the kernel. +@@ -48,7 +48,7 @@ sched_process *sched_create(char *name, uint64_t entry_point, uint32_t flags) + // If it's broken, it's a boom in the ass of your computer + // (and a CPU exception) + +- proc->pm = vmm_alloc_pm(); ++ proc->pm = pm; + + uint64_t *stack_phys = pmm_request_page(); + uint64_t *stack_virt = (uint64_t*)0x40000000; +@@ -107,5 +107,5 @@ void schedule(registers_t *regs) + memcpy(regs, &curr_proc->regs, sizeof(registers_t)); + + // Finally, load our pagemap +- //vmm_load_pagemap(curr_proc->pm); ++ vmm_load_pagemap(curr_proc->pm); + } +\ No newline at end of file +diff --git a/kernel/src/sched/sched.h b/kernel/src/sched/sched.h +index f5d2b04..5dcf23d 100755 +--- a/kernel/src/sched/sched.h ++++ b/kernel/src/sched/sched.h +@@ -34,6 +34,6 @@ extern sched_process *proc_list; + //extern sched_process *idle_process; + + void sched_init(); +-sched_process *sched_create(char *name, uint64_t entry_point, uint32_t flags); ++sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, uint32_t flags); + void sched_exit(sched_process *proc); + void schedule(registers_t *regs); +\ No newline at end of file +diff --git a/kernel/src/sys/arch/x86_64/gdt.c b/kernel/src/sys/arch/x86_64/gdt.c +index 0559625..d6d712a 100755 +--- a/kernel/src/sys/arch/x86_64/gdt.c ++++ b/kernel/src/sys/arch/x86_64/gdt.c +@@ -2,6 +2,7 @@ + #include + #include + #include ++#include + + gdt_table def_table = { + { +@@ -25,10 +26,10 @@ gdt_table def_table = { + + tssr tss_list[256]; // One tssr per CPU + +-void gdt_init() { ++void gdt_init( char* kstack ) { + + // TODO: adapt for multiprocessor kernel +- tss_list[0].iopb = sizeof(tssr); ++ tss_list[0].rsp[0] = (uint64_t)kstack; + uintptr_t tss = (uintptr_t)&tss_list[0]; + + def_table.tss_entry.length = sizeof(tss_entry); +diff --git a/kernel/src/sys/arch/x86_64/gdt.h b/kernel/src/sys/arch/x86_64/gdt.h +index 8e51e53..6004d06 100755 +--- a/kernel/src/sys/arch/x86_64/gdt.h ++++ b/kernel/src/sys/arch/x86_64/gdt.h +@@ -26,7 +26,7 @@ typedef struct { + + typedef struct { + uint32_t resv; +- uint64_t rsp[3]; ++ uint64_t rsp[4]; + uint64_t resv1; + uint64_t ist[7]; + uint64_t resv2; +@@ -34,4 +34,4 @@ typedef struct { + uint16_t iopb; + } __attribute__((packed)) tssr; // Per CPU + +-void gdt_init(); +\ No newline at end of file ++void gdt_init(char* kstack); +\ No newline at end of file +diff --git a/kernel/src/sys/arch/x86_64/interrupts.c b/kernel/src/sys/arch/x86_64/interrupts.c +index d243629..6bab678 100755 +--- a/kernel/src/sys/arch/x86_64/interrupts.c ++++ b/kernel/src/sys/arch/x86_64/interrupts.c +@@ -39,6 +39,14 @@ void exception_handler(registers_t *regs) { + if (regs->int_no < 32) { + //panic(kmode_cpu_exception, regs); + log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip, regs->err_code); ++ ++ if(regs->int_no == 0xe) { ++ uint64_t cr2; ++ asm ("mov %%cr2, %0" : "=r"(cr2)); ++ log("faulting locations: %p\n", cr2); ++ log("faulting page flags: %p\n", vmm_get_flags(vmm_current_pm, cr2)); ++ } ++ + dump_backtrace(regs); + asm ("cli"); + while (1)