create a new pgd for each process

This commit is contained in:
Stefan Lankes 2011-02-18 21:20:15 +01:00
parent da3a81b471
commit c355adb300
5 changed files with 81 additions and 21 deletions

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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)

View file

@ -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;
}