Code: Select all
/* Set the page directory. */
void switch_page_directory(page_directory_t *dir) {
current_directory = dir;
/* Tell the CPU where the pagedir is. */
asm volatile ("mov %0, %%cr3" : : "r" (dir->tablesPhysical));
u32int cr0;
/* Make sure paging is enabled. */
asm volatile ("mov %%cr0, %0" : "=r" (cr0));
cr0 |= 0x80000000; // enable paging bit
asm volatile ("mov %0, %%cr0" : : "r" (cr0));
}
Code: Select all
/* Clones a page directory, linking those tables that are used by the kernel and copying those
not.
*/
page_directory_t *clone_directory(page_directory_t *src) {
u32int phys;
page_directory_t *new_dir = (page_directory_t *) kmalloc_ap(sizeof(page_directory_t), &phys);
memset(new_dir, 0, sizeof(page_directory_t));
u32int off = (u32int) new_dir->tablesPhysical - (u32int) new_dir;
new_dir->physicalAddr = phys + off;
u32int i;
for (i = 0; i < 1024; i++) {
if (!src->tables[i])
continue;
if (kernel_directory->tables[i] == src->tables[i]) { // If it's kernel, then link it.
new_dir->tables[i] = src->tables[i];
new_dir->tablesPhysical[i] = src->tablesPhysical[i];
}
else { // Else, copy it.
u32int np;
new_dir->tables[i] = clone_table(src->tables[i], &np);
new_dir->tablesPhysical[i] = np | 0x07;
}
}
return new_dir;
}
/* Clones a page table. */
page_table_t *clone_table(page_table_t *src, u32int *phys) {
page_table_t *new_table = (page_table_t *) kmalloc_ap(sizeof(page_table_t), phys);
memset(new_table, 0, sizeof(page_table_t));
u32int i;
for (i = 0; i < 1024; i++) {
// If it's not allocated, than don't bother
if (src->pages[i].frame) {
// Allocate space for page
alloc_frame(&new_table->pages[i], 0, 0);
// Copy attributes of page
if (src->pages[i].present) new_table->pages[i].present = 1;
if (src->pages[i].rw) new_table->pages[i].rw = 1;
if (src->pages[i].user) new_table->pages[i].user = 1;
if (src->pages[i].accessed) new_table->pages[i].accessed = 1;
if (src->pages[i].dirty) new_table->pages[i].dirty = 1;
// Copy page data
copy_frame(src->pages[i].frame * 0x1000, new_table->pages[i].frame * 0x1000);
}
}
return new_table;
}