create a new pgd for each process
This commit is contained in:
parent
da3a81b471
commit
c355adb300
5 changed files with 81 additions and 21 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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; i<KERNEL_SPACE/(1024*4096); i++)
|
||||
// create a new "page table container" for the new task
|
||||
pgt = kmalloc(sizeof(page_table_t));
|
||||
if (!pgt) {
|
||||
kfree(pgd, sizeof(page_dir_t));
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(pgt, 0, sizeof(page_table_t));
|
||||
|
||||
for(i=0; i<1024 /*KERNEL_SPACE/(1024*4096)*/; i++) {
|
||||
pgd->entries[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;
|
||||
|
|
|
@ -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; i<MAX_TASKS; i++) {
|
||||
if (task_table[i].status == TASK_INVALID) {
|
||||
if (!user)
|
||||
ret = get_kernel_pgd(task_table+i);
|
||||
else
|
||||
ret = get_user_pgd(task_table+i);
|
||||
|
||||
if (ret != 0) {
|
||||
ret = -ENOMEM;
|
||||
goto create_task_out;
|
||||
}
|
||||
|
||||
task_table[i].id = i;
|
||||
task_table[i].status = TASK_READY;
|
||||
get_kernel_pgd(task_table+i);
|
||||
atomic_int32_set(&task_table[i].mem_usage, 0);
|
||||
memset(task_table[i].mbox, 0x00, sizeof(mailbox_int32_t*)*MAX_TASKS);
|
||||
|
||||
|
@ -135,6 +144,7 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg)
|
|||
}
|
||||
}
|
||||
|
||||
create_task_out:
|
||||
spinlock_unlock_irqsave(&table_lock);
|
||||
|
||||
return ret;
|
||||
|
@ -142,7 +152,7 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg)
|
|||
|
||||
int create_kernel_task(tid_t* id, entry_point_t ep, void* arg)
|
||||
{
|
||||
return create_task(id, ep, arg);
|
||||
return create_task(id, ep, arg, 0);
|
||||
}
|
||||
|
||||
static int STDCALL user_entry(void* arg)
|
||||
|
@ -243,7 +253,7 @@ int create_user_task(tid_t* id, size_t sz, const char* fname, int argc, char** a
|
|||
if (!node || !(node->type == 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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue