Triple fault when switching page directory

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
codyd51
Member
Member
Posts: 77
Joined: Fri May 20, 2016 2:29 pm
Location: London, UK
GitHub: https://github.com/codyd51
Contact:

Triple fault when switching page directory

Post 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!
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: Triple fault when switching page directory

Post 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.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
codyd51
Member
Member
Posts: 77
Joined: Fri May 20, 2016 2:29 pm
Location: London, UK
GitHub: https://github.com/codyd51
Contact:

Re: Triple fault when switching page directory

Post 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.
Boris
Member
Member
Posts: 145
Joined: Sat Nov 07, 2015 3:12 pm

Re: Triple fault when switching page directory

Post 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 .
ggwpez
Posts: 2
Joined: Wed Sep 16, 2015 3:23 am
Libera.chat IRC: ggwpez
Location: (0, 0, 0)

Re: Triple fault when switching page directory

Post 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?
My Bootloader Does Not Work?!
Post Reply