OS Crashes when enabling paging

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
SlayterDev
Member
Member
Posts: 25
Joined: Wed Aug 13, 2014 4:22 pm

OS Crashes when enabling paging

Post by SlayterDev »

Ok, so I've been following James Molloy's kernel tutorial (yes I have read the known bugs list) and I'm trying to create my paging system. I've narrowed the crash down to this bit right here:

Code: Select all

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

    u32int cr0;
    asm volatile("mov %%cr0, %0": "=r"(cr0));
    cr0 |= 0x80000000; // Enable paging!
    asm volatile("mov %0, %%cr0":: "r"(cr0));
}
Also here is how paging is first initialized:

Code: Select all

void init_paging() {
	mon_write("Init paging\n");

	u32int mem_end_page = 0x10000000; // max of memory
									  // currently 16MB

	nframes = mem_end_page / 0x1000;
	frames = (u32int *)kmalloc(INDEX_FROM_BIT(nframes));
	memset(frames, 0, INDEX_FROM_BIT(nframes));

	// make page dir
	kernel_directory = (page_directory_t *)kmalloc_a(sizeof(page_directory_t));
	memset(kernel_directory, 0, sizeof(page_directory_t));
	current_directory = kernel_directory;

	// identity map from 0x0 to end memory
	int i = 0;
	while (i < placement_address) {
		alloc_frame(get_page(i, 1, kernel_directory), 0, 0);
		i += 0x1000;
	}

	// register fault handler
	register_interrupt_handler(14, page_fault);

	//firstSwitch = 1; // first time switching directory
	switch_page_directory(kernel_directory);
}
Here is what I believe is the relevant crash dump info (VirtualBox on OS X):

Code: Select all

00:00:12.562653 --------------------------------------------------------------------------------
00:00:12.563317 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00:00:12.563599 emR3Debug: rc=VINF_EM_TRIPLE_FAULT
00:00:13.571357 Changing the VM state from 'RUNNING' to 'GURU_MEDITATION'.
00:00:16.944542 Console::powerDown(): A request to power off the VM has been issued (mMachineState=Stopping, InUninit=0)
00:00:16.956102 Changing the VM state from 'GURU_MEDITATION' to 'POWERING_OFF'.
00:00:16.956191 ****************** Guest state at power off ******************
00:00:16.956205 Guest CPUM (VCPU 0) state: 
00:00:16.956218 eax=80000011 ebx=00010000 ecx=00001000 edx=001018c0 esi=00000000 edi=00000000
00:00:16.956228 eip=00101808 esp=0007fe94 ebp=0007fea4 iopl=0      rf nv up di nt zr na po nc
00:00:16.956240 cs={0008 base=0000000000000000 limit=ffffffff flags=0000c09b} dr0=00000000 dr1=00000000
00:00:16.956253 ds={0010 base=0000000000000000 limit=ffffffff flags=0000c093} dr2=00000000 dr3=00000000
00:00:16.956260 es={0010 base=0000000000000000 limit=ffffffff flags=0000c093} dr4=00000000 dr5=00000000
00:00:16.956268 fs={0010 base=0000000000000000 limit=ffffffff flags=0000c093} dr6=ffff0ff0 dr7=00000400
00:00:16.956276 gs={0010 base=0000000000000000 limit=ffffffff flags=0000c093} cr0=80000011 cr2=00104100
00:00:16.956284 ss={0010 base=0000000000000000 limit=ffffffff flags=0000c093} cr3=00000000 cr4=00000000
00:00:16.956292 gdtr=0000000000104060:0027  idtr=00000000001040c0:07ff  eflags=00210086
00:00:16.956300 ldtr={0000 base=00000000 limit=0000ffff flags=00000082}
00:00:16.956304 tr  ={0000 base=00000000 limit=0000ffff flags=0000008b}
00:00:16.956309 SysEnter={cs=0000 eip=00000000 esp=00000000}
00:00:16.956314 FCW=037f FSW=0000 FTW=0000 FOP=0000 MXCSR=00001f80 MXCSR_MASK=0000ffff
00:00:16.956322 FPUIP=00000000 CS=0000 Rsrvd1=0000  FPUDP=00000000 DS=0000 Rsvrd2=0000
Let me know if you want to see any other info. I've gone through this part of the tutorial before and didn't have an issue. I'm rewriting from scratch just because I want a different approach but can't seem to figure out the issue here. I feel like it's probably something small but I've gone through this code, my previous code, and the tutorial code and can't seem to figure it out.
User avatar
fa7d0
Posts: 1
Joined: Wed Aug 13, 2014 6:20 pm

Re: OS Crashes when enabling paging

Post by fa7d0 »

Here's my "switch_page_directory" function:

Code: Select all

void switch_page_directory(page_directory_t *dir)
{
    current_directory = dir;
    asm volatile("mov %0, %%cr3":: "r"(dir->physicalAddr));
    u32int cr0;
    asm volatile("mov %%cr0, %0": "=r"(cr0));
    cr0 |= 0x80000000; // Enable paging!
    asm volatile("mov %0, %%cr0":: "r"(cr0));
}
It works fine for me, so you could try to change

Code: Select all

asm volatile("mov %0, %%cr3":: "r"(&dir->tablesPhysical));
to

Code: Select all

asm volatile("mov %0, %%cr3":: "r"(dir->physicalAddr));
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: OS Crashes when enabling paging

Post by thepowersgang »

Looking at the dump from VBox, it appears that CR3 is 0 (it's on the same line as SS), I'd assume that you're passing NULL to the switch_page_directory function instead of the actual directory.

As a side note - The model used by JamesM's tutorial is very broken, it mixes the concept of physical and virtual addresses (As can be seen by it taking the address to a passed value and using it as a physical address, this only works with paging off). I'd suggest instead attempting to get virtual memory enabled as soon as you can (preferably before C code gets executed)
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
SlayterDev
Member
Member
Posts: 25
Joined: Wed Aug 13, 2014 4:22 pm

Re: OS Crashes when enabling paging

Post by SlayterDev »

So when you say set up virtual memory before executing C code, do you mean enabling paging before the C code? Sorry I'm still trying to wrap my head around virtual memory and paging.

And I will try using the dir->physAddr in the morning when I get to my dev machine.
Post Reply