Page 1 of 1

System hang at paging enable

Posted: Tue Apr 15, 2008 1:39 pm
by voidlogic
Hey Guys,

I'm having a system hang when I enable paging and I'm not sure whats going on. I have checked to confirm that the physical memory manager is providing correctly aligned pages. Any ideas or tips would be great! :)

I am identity mapping up the the end of the kernel and its initial heap and I am mapping on page directory onto the last 4 MB of virtual memory for easy access.

Code: Select all

VirtMemMgr::VirtMemMgr(void* nonIdentPagingStart)
{
    system.console<<"Configuring Virtual/Physical Memory Managers... ";
    phyMem = new PhyMemMgr(nonIdentPagingStart);
    uint* pageDir = (uint*)phyMem->getPage();
    uint* pageTable = (uint*)phyMem->getPage();
    //map the first 4MB of memory to page table
    uint i = 0;
    //map exiting memory one to one
    for(; i < (uint)nonIdentPagingStart; i += 4096)
        pageTable[i] = i | GLBL_SUPER_RW_PRESENT;
    kCurPTE = i >> 12;
    //map remainder of PDE to address 0 and mark GLBL_SUPER_RO_NOTPRESENT
    //which will for our purposes mean unbacked virtual memory 
    for(; i < 0x400000; i += 4096)
	    pageTable[i] = 0 | GLBL_SUPER_RO_NOTPRESENT; 
    pageDir[0] = (uint)pageTable | SUPER_RW_PRESENT;
    for(uint j = 1; j < 1023; i++)
	    pageDir[i] = 0 | SUPER_RO_NOTPRESENT;
    //Map TPE to last 4 MB of VM
    mappedPTE = (uint*)0xFFC00000;
    pageDir[1023] = (uint)pageDir;
    //enable paging
    writeCR3((uint)pageDir);
    writeCR0(readCR0() | 0x80000000);
    system.console<<"done"<<endl;
}
Here is the code for the writeCRX etc

Code: Select all

readCR0:
	mov eax, cr0
	retn

writeCR0:
	push ebp
	mov ebp, esp
	mov eax, [ebp+8]
	mov cr0,  eax
	pop ebp
	retn

readCR3:
	mov eax, cr3
	retn

writeCR3:
	push ebp
	mov ebp, esp
	mov eax, [ebp+8]
	mov cr3, eax
	pop ebp
	retn


:(

Posted: Tue Apr 15, 2008 4:37 pm
by Zenith
Have you debugged? - what does Bochs output when your kernel crashes, or does your kernel just go unresponsive (it might be executing code where it shouldn't be...)? Also, make sure that the page mappings are being done properly.

Other than that, check if you're interfacing your ASM and C++ code correctly.

Hope this helps!

RE:

Posted: Tue Apr 15, 2008 6:50 pm
by voidlogic
Hey karekare0,

Thanks for the advice. I have been using asm extensively so far so I am rather confident that the C++/ASM linking is working OK. As to what exactly happens, I should have said, sorry. The machine locks up between the last two lines of the function I posted above, VirtMemMgr::VirtMemMgr.

That is:

Code: Select all

    writeCR0(readCR0() | 0x80000000);
    system.console<<"done"<<endl;
I'm going to keep working at it :( ; If you have any ideas I would really appreciate it :).

Re: System hang at paging enable

Posted: Tue Apr 15, 2008 7:10 pm
by Cognition
It looks like the problem is with your identity mapping code for the first 4mb worth of page tables, you're increasing your index value by 4096 so it's probably writing an entry every 16384 bytes instead of every 4. You're also trying to map the memory you've marked as not present in the same fashion.

I'm not sure how your phyMem->getPage() code works but if it's only allocating 4096 bytes to your page tables you're overrunning it by a good margin, make sure your page allocator knows you're using 1024 pages otherwise you'll likely end up corrupting your page tables later on.

RE

Posted: Thu Apr 17, 2008 11:24 am
by voidlogic
Hey,

I think I had changed the way I was handling my loops half way though and forgot to go back and correct it. In case anyone is interested the working code is posted below:

Code: Select all

VirtMemMgr::VirtMemMgr(void* heapEnd)
{
    system.console<<"Configuring Virtual/Physical Memory Managers... ";
    system.idt.installException(14, pageFaultHandler);
    phyMem = new PhyMemMgr(heapEnd);
    uint identMapEndPage = ((uint)heapEnd + (PAGESIZE<<1)) >> 12;
    uint i;
    
    //setup first page table    
    uint* pageTable = (uint*) phyMem->getPage();
    for(i = 0; i < identMapEndPage; i++)
        pageTable[i] = (i << 12) | GLBL_SUPER_RW_PRESENT;
    for(; i < 1024; i++)
        pageTable[i] = (i << 12) | GLBL_SUPER_RO_NOTPRESENT;
    
    //setup page directory
    uint* pageDir = (uint*) phyMem->getPage();
    pageDir[0] = (uint)pageTable | SUPER_RW_PRESENT;
    pageDir[1023] = (uint)pageDir | SUPER_RW_PRESENT;
    for(i = 1; i < 1023; i++)
	    pageDir[i] = 0 | SUPER_RO_NOTPRESENT;

    installPageDir(pageDir);
    system.console<<"done"<<endl;
}
:)