Page 1 of 1

Triple fault when switching page directory

Posted: Tue May 24, 2016 8:08 am
by codyd51
Let me start off by saying that I know this question has been asked before; I searched through all the related posts I could find, and couldn't find a solution.

I'm using James Molloy's tutorials to develop parts of my OS and I'm looking at the section where he implements multitasking. However, I get a triple fault whenever I use switch_page_directory at the end of my init_paging function.

Code: Select all

current_directory = clone_directory(kernel_directory);
switch_page_directory(current_directory);
switch_page_directory is implemented as follows:

Code: Select all

void switch_page_directory(page_directory_t* dir) {
	current_directory = dir;
	asm volatile("mov %0, %%cr3" : : "r"(dir->physicalAddr));
}


And clone_directory looks like

Code: Select all

page_directory_t* clone_directory(page_directory_t* src) {
	uint32_t phys;

	//make new page directory and get physaddr
	page_directory_t* dir = (page_directory_t*)kmalloc_ap(sizeof(page_directory_t), &phys);
	//blank it
	memset((uint8_t*)dir, 0, sizeof(page_directory_t));

	//get offset of tablesPhysical from start of page_directory_t
	uint32_t offset = (uint32_t)dir->tablesPhysical - (uint32_t)dir;
	dir->physicalAddr = phys + offset;

	printf_dbg("dir->physicalAddr: %x", dir->physicalAddr);

	//for each page table
	//if in kernel directory, don't make copy
	for (int i = 0; i < 1024; i++) {
		if (!src->tables[i]) continue;

		if (kernel_directory->tables[i] == src->tables[i]) {
			//in kernel, so just reuse same pointer
			dir->tables[i] = src->tables[i];
			dir->tablesPhysical[i] = src->tablesPhysical[i];
		}
		else {
			//copy table
			uint32_t phys;
			dir->tables[i] = clone_table(src->tables[i], &phys);
			dir->tablesPhysical[i] = phys | 0x07;
		}
	}
	return dir;
}
Feel free to let me know if you'd like to see any other parts of the implementation. I've printed the address being loaded into cr3, 0x1000, which seems low. Does anyone have any idea as to what I'm doing wrong or what I should try to fix it?

Thanks!

Re: Triple fault when switching page directory

Posted: Tue May 24, 2016 8:16 am
by BrightLight
Run it in Bochs, and see the log messages. ;) They usually tell you more than enough.
Oh, and your page fault handler should not be in the directory being switched -- you should be able to handle this page fault.

Re: Triple fault when switching page directory

Posted: Tue May 24, 2016 9:25 am
by codyd51
omarrx024 wrote:Run it in Bochs, and see the log messages. ;) They usually tell you more than enough.
Oh, and your page fault handler should not be in the directory being switched -- you should be able to handle this page fault.
Thanks, I'll try that. I've never used Bochs, only QEMU.

Re: Triple fault when switching page directory

Posted: Thu May 26, 2016 11:28 am
by Boris
Hi,
Before changing CR3:
Check if your IDT handlers are present in the other pages directory.
Then, check the current instruction pointer, and stack pointers .

Re: Triple fault when switching page directory

Posted: Thu May 26, 2016 2:27 pm
by ggwpez
Hi,

I had the exact same problem (since also following James Molloy) as you,
and ended up using memcpy.
I know thats probably a bad idea, though it worked.
So you could also try it, to determine where the error is.

And the address of the new PageDir is 0x1000?
Where is your kernel located?