diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index b8d57ad3..ef989927 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h @@ -106,8 +106,8 @@ int arch_paging_init(void); int get_kernel_pgd(task_t* task); /* - * Create a new page directory for a new user-level task + * Setup a new page directory for a new user-level task */ -page_dir_t* create_pgd(void); +int get_user_pgd(task_t* task); #endif diff --git a/arch/x86/kernel/gdt.c b/arch/x86/kernel/gdt.c index a68079aa..1763e822 100644 --- a/arch/x86/kernel/gdt.c +++ b/arch/x86/kernel/gdt.c @@ -75,7 +75,7 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg) task_state_segments[id].gs = ds; task_state_segments[id].es = ds; task_state_segments[id].eflags = 0x1202; - task_state_segments[id].cr3 = (uint32_t) (task->pgd); + task_state_segments[id].cr3 = (uint32_t) (virt_to_phys(per_core(current_task), (size_t)task->pgd)); task_state_segments[id].eip = (uint32_t) ep; task_state_segments[id].esp = (uint32_t) kstacks[id] + KERNEL_STACK_SIZE - sizeof(size_t); diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index 62944017..84c5d88a 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -38,7 +38,7 @@ * 0x00100000 - 0x0DEADFFF: Kernel (size depends on the configuration) * 0x0DEAE000 - 0x3FFFEFFF: Kernel heap * 0x3FFFF000 - 0x3FFFFFFF: Page Tables are mapped in this region - * (The first 256 entries belongs to kernel space) + * (The last 256 entries belongs to kernel space) */ /* @@ -64,20 +64,67 @@ int get_kernel_pgd(task_t* task) return 0; } -page_dir_t* create_pgd(void) +int get_user_pgd(task_t* task) { page_dir_t* pgd; + page_table_t* pgt; + page_table_t* pgt_container; uint32_t i; + uint32_t index1, index2; + size_t viraddr; + if (BUILTIN_EXPECT(!paging_enabled, 0)) + return -EINVAL; + + // we already know the virtual address of the "page table container" + // (see file header) + pgt_container = (page_table_t*) ((KERNEL_SPACE - PAGE_SIZE) & 0xFFFFF000); + + // create new page directory for the new task pgd = kmalloc(sizeof(page_dir_t)); if (!pgd) - return NULL; - memset(pgd, 0, sizeof(page_dir_t)); + return -ENOMEM; + //memcpy(pgd, &boot_pgd, sizeof(page_dir_t)); - for(i=0; ientries[i] = boot_pgd.entries[i]; + if (pgd->entries[i]) { + kprintf("pgd->entries[%d] = %p\n", i, pgd->entries[i]); + pgt->entries[i] = pgt_container->entries[i]; + kprintf("pgt->entries[%d] = %p\n", i, pgt->entries[i]); + } + } - return pgd; + //for(i=0/*1024-KERNEL_SPACE/(1024*4096)*/; i<1024; i++) { + // pgt->entries[i] = pgt_container->entries[i]; + // if (pgt->entries[i]) + // kprintf("pgt->entries[%d] = %p\n", i, pgt->entries[i]); + //} + + // map page table container at the end of the kernel space + viraddr = (KERNEL_SPACE - PAGE_SIZE) & 0xFFFFF000; + index1 = viraddr >> 22; + index2 = (viraddr >> 12) & 0x3FF; + + // now, we create a self reference + pgd->entries[index1] = ((size_t) virt_to_phys(per_core(current_task), (size_t) pgt) & 0xFFFFF000)|KERN_TABLE; + pgt->entries[index2] = ((size_t) virt_to_phys(per_core(current_task), (size_t) pgt) & 0xFFFFF000)|KERN_PAGE; + + kprintf("AAA pgd->entries[%d] = %p\n", index1, pgd->entries[index1]); + kprintf("AAA pgt->entries[%d] = %p\n", index2, pgt->entries[index2]); + + task->pgd = pgd; + task->pgd_lock = &boot_pgd_lock; + + return 0; } size_t virt_to_phys(task_t* task, size_t viraddr) @@ -86,7 +133,10 @@ size_t virt_to_phys(task_t* task, size_t viraddr) page_table_t* pgt; size_t ret = 0; - if (BUILTIN_EXPECT(!task || !task->pgd || !paging_enabled, 0)) + if (!paging_enabled) + return viraddr; + + if (BUILTIN_EXPECT(!task || !task->pgd, 0)) return 0; index1 = viraddr >> 22; diff --git a/kernel/tasks.c b/kernel/tasks.c index 94ba5e4a..1553282b 100644 --- a/kernel/tasks.c +++ b/kernel/tasks.c @@ -109,7 +109,7 @@ void NORETURN abort(void) { do_exit(-1); } -static int create_task(tid_t* id, entry_point_t ep, void* arg) +static int create_task(tid_t* id, entry_point_t ep, void* arg, int user) { int ret = -ENOMEM; unsigned int i; @@ -121,9 +121,18 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg) for(i=0; itype == FS_FILE)) return -EINVAL; - return create_task(id, user_entry, node); + return create_task(id, user_entry, node, 1); } int join_task(tid_t id, int* result) diff --git a/kernel/tests.c b/kernel/tests.c index 43e7d90f..26140de1 100644 --- a/kernel/tests.c +++ b/kernel/tests.c @@ -98,18 +98,18 @@ static int STDCALL join_test(void* arg) int test_init(void) { - tid_t id1, id2, id3, id4, id5; - char* argv[1] = {"/bin/hello"}; + char* argv[1] = {"dummy"}; sem_init(&producing, 1); sem_init(&consuming, 0); mailbox_int32_init(&mbox); - create_kernel_task(&id1, foo, "Hello from foo1\n"); - //create_kernel_task(&id2, join_test, NULL); - //create_kernel_task(&id3, producer, NULL); - //create_kernel_task(&id4, consumer, NULL); - create_user_task(&id5, 8192, "/bin/hello", 1, argv); + create_kernel_task(NULL, foo, "Hello from foo1\n"); + //create_kernel_task(NULL, join_test, NULL); + //create_kernel_task(NULL, producer, NULL); + //create_kernel_task(NULL, consumer, NULL); + create_user_task(NULL, 8192, "/bin/hello", 1, argv); + create_user_task(NULL, 8192, "/bin/test_fork", 1, argv); return 0; }