Page 1 of 1

Triple Fault at Paging

Posted: Sun Feb 24, 2013 6:00 am
by erhardt
Hi there I've a serious problem with my Paging:
Source Code?
https://docs.google.com/file/d/0B-x3QNi ... UzLUk/edit
What I want to do?
I've allready declared Functions for allocating memory in the virtual address space copyout/in and mapping for the Usermode,but I'm not trying to get those work yet. I just want to setup the Page and Page directory tables for the kernel enable Paging and stay in an endless while loop.

What's going wrong?
As you can see in the qemu.log below I'm having a triplefault as I haven't mapped anything. 101 can be found in cr2 at he first fault.

Code: Select all

check_exception old: 0xffffffff new 0xe
     0: v=0e e=0000 i=0 cpl=0 IP=0008:000000000010051d pc=000000000010051d SP=0010:0000000000126fac CR2=000000000010051d
EAX=80000011 EBX=00000011 ECX=00126f36 EDX=000003d5
ESI=0005d99b EDI=0005d990 EBP=00126fd4 ESP=00126fac
EIP=0010051d EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00009108 00000027
IDT=     00000000 000003ff
CR0=80000011 CR2=0010051d CR3=00001000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000008 CCD=80000011 CCO=LOGICL  
EFER=0000000000000000
check_exception old: 0xe new 0xe
     1: v=08 e=0000 i=0 cpl=0 IP=0008:000000000010051d pc=000000000010051d SP=0010:0000000000126fac EAX=0000000080000011
EAX=80000011 EBX=00000011 ECX=00126f36 EDX=000003d5
ESI=0005d99b EDI=0005d990 EBP=00126fd4 ESP=00126fac
EIP=0010051d EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS   [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     00009108 00000027
IDT=     00000000 000003ff
CR0=80000011 CR2=00000070 CR3=00001000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000008 CCD=80000011 CCO=LOGICL  
EFER=0000000000000000
check_exception old: 0x8 new 0xe
What I found out?
I placed lots of text outputs in "vmm_map_page"(in my Paging source file src/kernel/mm/vmm.c) and figured out that the page directory and the page table were setup as it should be(I could also use GDB and examine the Memory, but "remote target :1234" doesn't work). It's still possible,that I have forgotten something in the tables,but well it could be also something with my inline ASM.

Thanks a lot for the help ;)(verdammt Kevin ist auch im englischen Forum^^)

HELP
SOS
HELP

Re: Triple Fault at Paging

Posted: Sun Feb 24, 2013 6:13 am
by iansjack
What assembler instruction is it faulting on (at location 0x10051d)? Perhaps a disassembly of the surrounding code would make things clearer.

Re: Triple Fault at Paging

Posted: Sun Feb 24, 2013 6:16 am
by erhardt
iansjack as you can see at the code on google drive that's the point where I'm enabling Paging with

Code: Select all

#define ENABLE_PAGING 	uint32_t cr0;\
			asm volatile("mov %%cr0, %0" : "=r" (cr0));\
			cr0 |= (1 << 31);\
			asm volatile("mov %0, %%cr0" : : "r" (cr0));

...
vmm_context* vmm_init(void)
{
    kprintf("[VMM] I: VMM setup...");
    /* Speicherkontext anlegen */
    vmm_context* startup_context = vmm_crcontext();
    kprintf("map it ...");
    vmm_map_kernel(startup_context);
    kprintf("enabling it ...");
    //while(1){}
    ENABLE_PAGING 
    kprintf("SUCCESS\n");
    while(1){}
    return startup_context;
}
Here is some other important code for those who can't find it:

Code: Select all

vmm_context* vmm_crcontext(){
    vmm_context* new_context = pmm_malloc(4096+BITMAP_SIZE*4);
    if((uintptr_t)new_context+4096+BITMAP_SIZE*4 >= KERNEL_SPACE){//Is it inside the Kernel?; We are using a Bitmap so 
        kprintf("[VMM] E: Not enough Kenrelspace\n");
	return NULL;
    }
    //kprintf("[VMM] I: vmm_crcontext created Context at 0x%x\n",(uintptr_t)new_context);
    memset(new_context,0x00000000,4096);// clear the PgDIR to avoid invalid values
    memset((void*)((uintptr_t)(new_context+4096)),0xffffffff,BITMAP_SIZE*4);//fill the Virt Bitmap with ones
    vmm_set_context(new_context);
    return new_context;
}
int vmm_map_page(vmm_context* context, uintptr_t virt, uintptr_t phys,uint8_t flgs){
    uint32_t page_index = virt / PAGE_SIZE;
    uint32_t pd_index = page_index / 1024;
    uint32_t pt_index = page_index % 1024;
    struct vmm_pagetbl* page_table=NULL;
    
    // Wir brauchen 4k-Alignment 
    if (((virt % PAGE_SIZE)!=0) || ((phys % PAGE_SIZE)!= 0)) {
	kprintf("[VMM] W: vmm_map_page has no 4k alignment(virt: 0x%x,phys: 0x%x)\n",virt,phys);
    }
    phys=phys/PAGE_SIZE;
    virt =virt/PAGE_SIZE;
    
    struct vmm_pagetblentr new_pgtblentr ={
	.rw_flags = flgs,
	.free = 0x0,
	.page_ptr =phys
    };
    
    /* Page Table heraussuchen bzw. anlegen */
    if (context->pgdir[pd_index].rw_flags & FLG_IN_MEM) {
        /* Page Table ist schon vorhanden */
        page_table = (void*)(context->pgdir[pd_index].pagetbl_ptr*PAGE_SIZE);
	//kprintf("context at: 0x%x\n",(uintptr_t)context);
	//kprintf("pd_index: 0x%x\n",pd_index);
	//kprintf("[VMM] I: vmm_map_page found page_table and stored at 0x%x\n ",(uintptr_t)page_table);
    } else {
        /* Neue Page Table muss angelegt werden */
        page_table = (struct vmm_pagetbl*)(pmm_malloc_4k());
        memset(page_table, 0x00000000, PAGE_SIZE);
	/*set Pagedir entry*/
	struct vmm_pagedirentr new_pgdirentr ={
	    .rw_flags = flgs,
	    .free=0x0,
	    .pagetbl_ptr =(uintptr_t)(page_table)/PAGE_SIZE
	};
	//kprintf("[VMM] I: vmm_map_page found free space at 0x%x\n",(uintptr_t)page_table);
	//kprintf("[VMM] I: vmm_map_page found free space for pgtbls stored at 0x%x\n",new_pgdirentr.pagetbl_ptr);
        context->pgdir[pd_index] =new_pgdirentr;
    } 
    if(page_table==NULL){
	kprintf("[VMM] E: vmm_map_page doesn't found a Page Table\n");
	return -1;
    }
    //kprintf("[VMM] I: vmm_map_page using Context at 0x%x\n",(uintptr_t)context);
    //set pagetableentry 
    page_table->pgtbl[pt_index] =new_pgtblentr;
    //kprintf("[VMM] I: vmm_map_page found free space for pgs stored at 0x%x\n", page_table->pgtbl[pt_index].page_ptr);
    //asm volatile("invlpg %0" : : "m" (*(char*)virt));
    virt=virt*PAGE_SIZE;
    INVALIDATE_TLB(virt)
    return 0;
}
static void vmm_map_kernel(vmm_context* context){
    uint32_t* virt_bitmap =  (void*)(uintptr_t)(context+4096);
    int i=0;
     /* map everything within Kernel space */
    for (i = 0x00000000; i < KERNEL_SPACE; i +=PAGE_SIZE) {
	//if(pmm_is_alloced(i)==TRUE){
	    vmm_map_page(context, i, i,FLGCOMBAT_KERNEL);
	    vmm_mark_used(virt_bitmap,i/PAGE_SIZE);
	//}
    }
}

Re: Triple Fault at Paging

Posted: Sun Feb 24, 2013 6:35 am
by iansjack
Are you saying that the faulting instruction is at

mov %0, %%cr0?

If so then, whatever you think, I would suspect that your page table is invalid.

Re: Triple Fault at Paging

Posted: Sun Feb 24, 2013 6:44 am
by erhardt
iansjack wrote:Are you saying that the faulting instruction is at

mov %0, %%cr0?

If so then, whatever you think, I would suspect that your page table is invalid.
I've made an endless while loop before enabling Paging and found out, that the RW_Flags where 0xb and the last PagetablePointer 0x64

Re: Triple Fault at Paging

Posted: Sun Feb 24, 2013 7:31 am
by iansjack
Are you saying the faulting instruction is the move to %cr0? I'm still not clear about this. You have just given us a general function in which the fault occurs. How do you know the problem is not in the following print function? Do your page tables map virtual addresses to the same physical addresses or what?

It really would help if you could provide a disassembly listing of the code in the region of the fault.

Re: Triple Fault at Paging

Posted: Sun Feb 24, 2013 7:32 am
by erhardt
I found out that GCC is storing the fields of my Pagetable/Pagedir entries in the opposite order.
I also use 3 bits for free space and 21 bits for pointers. Now my last PageTable is 0xb00FFFF and my last PDIR entry is 0xb000064, but I'm still getting a triplefault :(

Re: Triple Fault at Paging

Posted: Sun Feb 24, 2013 7:42 am
by Combuster
erhardt wrote:Now my last PageTable is 0xb00FFFF and my last PDIR entry is 0xb000064
And both seem to point to nonexistent RAM...

Re: Triple Fault at Paging

Posted: Sun Feb 24, 2013 8:27 am
by erhardt
Hi, I changed my source Code again now It is here.
https://docs.google.com/file/d/0B-x3QNi ... JQcXM/edit
In changed my PageTbl and PageDir so that The Pointer is coming first.
Now 0x7fff80bf is my last PGTbl entry and 0x0003200b my last PDir entry.
But it's still not working.

Re: Triple Fault at Paging

Posted: Sun Feb 24, 2013 10:28 am
by iansjack
I think that it's your computer's way of telling you that it's time to learn how to debug with qemu. Sort that out first and then you will be in a better position to examine your page tables and find what you have done wrong. It would also be a good idea to implement some simple exception handlers (if you haven't already done so) so that every exception doesn't end up as an uninformative triple fault.

If you are using Linux and can't get qemu debugging to work (it's very simple, so I can't think what your problem is there) you might like to look at SimNow for assembler-level debugging.

Re: Triple Fault at Paging

Posted: Mon Feb 25, 2013 8:03 am
by erhardt
@iansjack I allready found and solved the problem with xp memory in Qemu. Some german guys in the IRC told me how to do.

Thanks a lot for the help