Page 1 of 1

Qemu shows no problem, on real PC triple fault in initPaging

Posted: Thu Mar 26, 2009 10:58 am
by Raven
Hi everybody
I followed James tutorials for paging (Nicely done).
Well problem is when i am trying to come out of the routine that changes cr0 to enable paging.

Code: Select all

void switch_page_directory(page_directory_t *dir)

{

unsigned short *t= (unsigned short *)0xB8000;//added for testing
    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));

goto down;//short jump to flush queue
for(;;);
down:

*t='A';//This works fine both on Qemu and on real machine
//puts("Paging Set\n");//If this is uncommented, works on qemu, triple faults on real PC
for(;;);//If  this is commented  works fine on qemu but triple faults on real machine

}

The thing that confuses me is that if routine for Identity mapping, PD or PT are incorrect then *t='A' and for(;;); should triple fault too.
This means there is something wrong with call and ret, hence wrong with SS and ESP.
I searched forum and found fixes to James paging.c but even after adding those snippets could get rid off it.

I am not creating an elf file rather a pure binary using gcc and fc7 to be loaded by my Second Stage Bootloader.
Please help!

Re: Qemu shows no problem, on real PC triple fault in initPaging

Posted: Thu Mar 26, 2009 6:55 pm
by gzaloprgm
Where is your kernel being loaded? Paste your initPaging function, I think I know how to solve it.

Re: Qemu shows no problem, on real PC triple fault in initPaging

Posted: Fri Mar 27, 2009 1:31 pm
by Raven
Thanks a lot and sorry for delay.

Code: Select all

void initPaging()

{

    // The size of physical memory(actual 512), say 16MB
    u32int mem_end_page = 0x1000000;
   

    nframes = mem_end_page / 0x1000;

    frames = (u32int*)kmalloc_a(INDEX_FROM_BIT(nframes));

    memset(frames, 0, INDEX_FROM_BIT(nframes));

    

    // Let's make a page directory.

    kernel_directory = (page_directory_t*)kmalloc_a(sizeof(page_directory_t));

    memset(kernel_directory, 0, sizeof(page_directory_t)); // JAMESM CHANGED

    current_directory = kernel_directory;

    kernel_directory->physicalAddr = (u32int)kernel_directory->tablesPhysical; // JAMESM ADDED

    // We need to identity map (phys addr = virt addr) from

    // 0x0 to the end of used memory, so we can access this

    // transparently, as if paging wasn't enabled.

    // NOTE that we use a while loop here deliberately.

    // inside the loop body we actually change placement_address

    // by calling kmalloc(). A while loop causes this to be

    // computed on-the-fly rather than once at the start.

    int i = 0;

    while (i < placement_address)

    {

        // Kernel code is readable but not writeable from userspace.

        alloc_frame( get_page(i, 1, kernel_directory), 0, 0);

        i += 0x1000;

    }

    // Before we enable paging, we must register our page fault handler.

    idt_set_gate(14, (unsigned)page_fault, 0x08, 0x8E);    

    // Now, enable paging!

    switch_page_directory(kernel_directory);

}


This code is from James tutorials embedded in mine.

Re: Qemu shows no problem, on real PC triple fault in initPaging

Posted: Fri Mar 27, 2009 1:46 pm
by gzaloprgm
Hmm. Try changing while (i < placement_address) to while (i < 1024*1024) . In which address are you loading your kernel?

Re: Qemu shows no problem, on real PC triple fault in initPaging

Posted: Fri Mar 27, 2009 2:51 pm
by Raven
Thanks a lot
My kernel is loaded at 0x100000.

Do i need to set whole page directory, i mean what will it do?
Please help.

Re: Qemu shows no problem, on real PC triple fault in initPa

Posted: Sun Dec 19, 2010 9:50 am
by padmalcom
I have exactly the same problem, are there any solutions yet?

Re: Qemu shows no problem, on real PC triple fault in initPa

Posted: Mon Dec 20, 2010 3:59 am
by padmalcom
Thanks for that hint!