Error 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
shiz98
Posts: 10
Joined: Sun Jul 29, 2007 8:59 pm

Error enabling paging?

Post by shiz98 »

Hi guys,

I've been trying to get paging working, but I haven't had much success. I've got a working physical page (de)allocator, and everything seems to be fine up to setting CR0. I haven't been able to figure out what I've been doing wrong from the tutorials I've read. I'd be much obliged if someone could point me in the right direction. Here's the pertinent code:

This assembly code is pretty straight forward - SetPageDirectory works fine, but EnablePaging fails at mov cr0, eax. I haven't tested DisablePaging.

Code: Select all

global _SetPageDirectory
_SetPageDirectory:
    push ebp ;stack stuff
    mov ebp, esp
    mov eax, [ebp + 8] ;"pop" the directory
    and eax, 0xFFFFF000
    mov cr3, eax
    pop ebp
    ret
global _EnablePaging
_EnablePaging:
    mov eax, cr0
    or eax, 0x80000000
    mov cr0, eax
    ret
global _DisablePaging
_DisablePaging:
    mov eax, cr0
    and eax, 0x7FFFFFFF
    mov cr0, eax
    ret
Here's the code that calls enable paging:

Code: Select all

    KernelPageDirectoryAddress = AllocatePage();
    memset(KernelPageDirectoryAddress, 0, 4096); //clear the page directory
    KernelPageDirectoryAddress[1023] = ((unsigned int)KernelPageDirectoryAddress & 0xFFFFF000) | 0x3; //maps the page directory's last entries into itself
    //map the pages we've claimed
    PrintString("\nMapping Pages");
    MapPages(0xC0000000, 0x100000, kernelPages); //map our kernel to its virtual location
    MapPages(0xD0000000, 0x100000 + kernelPages * 4096, kernelHeapPages); //map the currently used heap pages
    
    SetPageDirectory(KernelPageDirectoryAddress);
    EnablePaging(); //problem here
There's not much to this either - MapPages maps continuous sets of pages, but isn't implemented yet. In fact, the only mapping that gets done is to map the page directory into itself. I don't think that would prevent me from enabling paging.

I haven't yet written an interrupt handler - I want to get some memory management done first - so I can't get details on the failure. Any help would be greatly appreciated!
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Unfortunately I would have to say that being unable to get information on the failure (GPF? Page fault?) really limits your (and our) debugging ability. I would hack up a quick IDT and use that.
shiz98
Posts: 10
Joined: Sun Jul 29, 2007 8:59 pm

Post by shiz98 »

Yeah, I thought I might have to. Just wanted to make sure I wasn't making an obvious mistake.

I'll throw an IDT together and post the results.
shiz98
Posts: 10
Joined: Sun Jul 29, 2007 8:59 pm

Post by shiz98 »

Alright, I've written up a simple IDT that deals with interrupts 0-31. I tested it with a division by zero, and it seems to work. Unfortunately, it doesn't do me any good in debugging this problem: virtual pc just tells me that an unrecoverable processor error has occurred and shuts itself down.

So what do I do now? I'm going to download bochs and see if it gives me any more information, but I doubt it'll help much.

Here's how my kernel initializes itself, in case it helps:
Sets up basic GDT (code, data covering entire address range)
Clears the screen
Initializes the physical memory manager
Sets up interrupts
Initializes virtual memory (problem is here)
User avatar
JoeKayzA
Member
Member
Posts: 79
Joined: Wed Aug 24, 2005 11:00 pm
Location: Graz/Austria

Post by JoeKayzA »

Just a wild guess, but where is your stack located? Are you sure it is mapped after you enable paging? When the stack is unreachable, you won't even receive a pagefault (immediate triple fault instead).

cheers
Joe
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post by frank »

You have to map in the pages where the kernel is located at. I see that you are mapping the kernel to 0xC0000000 but you also say in your post that MapPages isn't implemented yet. Without mapping in the kernel how is the processor supposed to find the it to run it?
shiz98
Posts: 10
Joined: Sun Jul 29, 2007 8:59 pm

Post by shiz98 »

Hmm. Right now I haven't mapped anything to virtual memory(haven't yet implemented the needed functions). I didn't think this would cause a problem yet, because I just have an endless loop after enabling paging.

I had also completely forgotten about the stack (not a good idea, it seems). Do ebp and esp point to physical or virtual addresses?

Looking at the bochs output, the code that deals with CR0 and CR3 works correctly, so the problem lies with my understanding :). I'm getting a page not present, then triple fault. I wonder why my IDT isn't picking that up. Maybe it's related to the stack...
shiz98
Posts: 10
Joined: Sun Jul 29, 2007 8:59 pm

Post by shiz98 »

Thanks frank, that didn't even occur to me until you pointed it out. Looks like mapping some pages would be a really good idea. I guess while I was debugging I found that disabling that mov cr0, eax call made everything work, and naturally concluded that the problem lies there. Didn't even occur to me that not enabling paging might avoid the problem... I should stop debugging so late at night.

Thanks for the help guys - I'm going to write my mapping functions and see if I can get things working. I'll let you know if I do.

On final question though. Once I start using virtual memory, are ALL addresses mapped, save the one in CR3? The addresses of the IDT and GDT, for example.
shiz98
Posts: 10
Joined: Sun Jul 29, 2007 8:59 pm

Post by shiz98 »

*Bump*

Alright, so a couple of weeks later, I've finally gotten around to implementing those paging functions... Still not working though.

I've managed to hone my bochs skills now, and here's what I've found:

My page directory and entries are all set up fine. CR3 points to the right location.

The exact instruction that the EnablePaging function fails on is mov cr0, eax - I'm sure of it this time :P

As soon as I attempt to execute that line, bochs gives me a ??? (Physical Address Not Available) error. At the time of this error, the paging bit in CR0 is actually set; I can even look at my stack, which is now mapped into virtual memory, through bochs' memory viewer.

Any ideas on this?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

you probably forgot to identity map the currently executing code.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
Post Reply