Page 1 of 2
VM resets on initialise_paging
Posted: Sat Feb 09, 2008 5:28 am
by redDot
I am trying to implement paging, but while initialising ,its causing triple fault, and the VM gets reset. I traced out the code, putting an infinite loop after each line in the initialise_paging(), and finally got the culprit. Its in
[code]
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!
for(;;);
__asm__ __volatile__("mov %0, %%cr0":: "r"(cr0));
}
[\code]
the line after the for(;;); is causing the triple fault...
could anyone please help me out with this problem ...
Posted: Sat Feb 09, 2008 6:05 am
by AndrewAPrice
I'm guessing the problem is with:
.
I'm unsure how your code works but is "tablesPhysical" pointing to the physical address of your page tables? If you're using 4KB pages then it should point to your page
directory.
A few more common mistakes people make that you should ask yourself:
- Are your page tables correctly being set up?
- Is the code your executing being mapped into the same position? If you're executing code which was compiled to run at location 0x0500 then you trying to map it to virtual address 0x10000:
- You're memory locations will be all mixed up.
- The code will still be trying to execute from 0x0500 which isn't mapped anywhere causing a page fault.
Triple faulting is a clear indication your page directory/tables are not set up correctly. After the processor enables paging, it's trying to execute the next line of code. But the page that code is in doesn't exist, so it tries to call a page fault interrupt. But when it tries to execute your exception handler, that page doesn't exist neither, so it generates a double fault. The double fault page doesn't exist, so it generates a triple fault. By this stage the VM/processor says "this is getting ridicules" and just reboots.
Posted: Sat Feb 09, 2008 2:27 pm
by redDot
the error was in the kheap.c file, i had wrongly written the code as
[code]u32int kmalloc_a(u32int sz)
{
return kmalloc_int(sz, 0, 0);
}[/code]
and hence the alignment problem was there.
i have changed it to
[code]u32int kmalloc_a(u32int sz)
{
return kmalloc_int(sz, 1, 0);
}[/code]now no more triple faults are ocurring, but i am back to square 1 now.
The page fault is still not happening ???
Posted: Sat Feb 09, 2008 5:22 pm
by Combuster
Any reason for double posting? I can find large bits of both posts in another thread.
Posted: Sun Feb 10, 2008 12:38 am
by redDot
i thought the bochs problem and this paging problem r independent, hence two threads.
nyways, as for this paging problem, i ran the OS in bochs and it give the following log output:
[code]
00197105500p[WGUI ] >>PANIC<< POWER button turned off.
00197105500i[SYS ] Last time is 1202625168
00197105500i[CPU ] protected mode
00197105500i[CPU ] CS.d_b = 32 bit
00197105500i[CPU ] SS.d_b = 32 bit
00197105500i[CPU ] | EAX=00000018 EBX=00026260 ECX=000b8000 EDX=001003d3
00197105500i[CPU ] | ESP=00104fe0 EBP=00067edc ESI=00026373 EDI=00026385
00197105500i[CPU ] | IOPL=0 NV UP EI PL NZ NA PO NC
00197105500i[CPU ] | SEG selector base limit G D
00197105500i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00197105500i[CPU ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00197105500i[CPU ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00197105500i[CPU ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00197105500i[CPU ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00197105500i[CPU ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00197105500i[CPU ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00197105500i[CPU ] | EIP=00100493 (00100493)
00197105500i[CPU ] | CR0=0xe0000011 CR1=0x00000000 CR2=0x00000000
00197105500i[CPU ] | CR3=0x00108000 CR4=0x00000000
00197105500i[ ] restoring default signal behavior
00197105500i[CTRL ] quit_sim called with exit code 1
[/code]
ny sugession as to why the page fault is not happening when its suppose to happen ....
Posted: Sun Feb 10, 2008 10:00 am
by Combuster
for the nth time: ENABLE BBCODE
Posted: Sun Feb 10, 2008 10:56 am
by Brynet-Inc
Combuster wrote:for the nth time: ENABLE BBCODE
I couldn't agree more!
And as I have nothing better to do.. I've prepared some insightful pictures.
The recommend method:
1) Click "Profile" at the top of this site, (
Pretty illustration..)
2) Set "Always allow BBCode" to Yes, (
Another..)
The cheaters method:
1) Click "Edit" atop of your post, (
Pretty illustration..)
2) Keep "Disable BBCode in this post" unchecked, (
Yet another..)
Have yourself a nice day..
Posted: Sun Feb 10, 2008 12:33 pm
by redDot
ok friends,
i have enabled BBCode...
now can i have ur help ?
Posted: Sun Feb 10, 2008 3:43 pm
by jerryleecooper
Use the movl instruction, not the mov instruction.
Personnaly, I put everything in the "a" register and modify the cr3 cr0 from eax. I never had problems. But your way can be good too. Use the movl instruction, the mov instruction I think just move a byte, which is not good.
Posted: Sun Feb 10, 2008 3:50 pm
by pcmattman
The mov instruction will work, GAS can figure out what to use (postfixes are used if you want to make a specific size move).
As for the OP's problem...
You aren't getting the fault because paging isn't actually enabled:
Try this instead:
Code: Select all
u32int cr0;
__asm__ __volatile__("mov %%cr0, %0": "=r"(cr0));
if( ! ( cr0 & 0x80000000 ) )
cr0 |= 0x80000000; // Enable paging!
__asm__ __volatile__("mov %0, %%cr0":: "r"(cr0));
And then post the bochs log.
Posted: Sun Feb 10, 2008 4:22 pm
by Combuster
pcmattman wrote:You aren't getting the fault because paging isn't actually enabled:
uhm, the PG bit is set there (0xe = 8 + 4 + 2), although the CD and NW bits are set too (why are the caches disabled?!)
ny sugession as to why the page fault is not happening when its suppose to happen ....
You keep fixing the pagefaults, where would you even want to get that pagefault? (in other words,
we can't possibly have a clue)
Posted: Mon Feb 11, 2008 12:29 am
by pcmattman
Combuster wrote:pcmattman wrote:You aren't getting the fault because paging isn't actually enabled:
uhm, the PG bit is set there (0xe = 8 + 4 + 2), although the CD and NW bits are set too (why are the caches disabled?!)
My mistake. I should have looked in the manuals before I posted.
OP: what code do you want to have page faulting?
Posted: Mon Feb 11, 2008 4:15 am
by JamesM
This is getting tedious, reading through post after post, trying to work out which ones have been crossposted where (and which were double-emailed to me personally, I might add!)
The code he wants to get pagefaulting is an access to 0xA0000000 - a delibarately non-mapped page in order to check the faulting mechanism (his code is lifted from my tutorials).
OP: You're not giving enough information. Please post your code (in bbtags for the love of God!). Also I do wonder why you have caches disabled and the NW bit enabled...
Posted: Mon Feb 11, 2008 4:37 am
by redDot
hi friends,
this problem z eating my head up. Its been about a week now. tried about everything possible. read the manual about 10 times, but all in vain. i wanted to test if my page fault handler had been registered properly, so i called the page fault explicitely (by int $0xE)Now i am getting a new problem, there is general protection fault occuring after the page fault (both are happening) ...
Code: Select all
initialise_paging();
puts("paging installed\n");
//puts("\n\ntushar's Kernel $");
//test the interrupt subroutines
__asm__ __volatile__ ("int $0xE");
//cls();
puts("\nHello, paging world !!!");
u32int *ptr = (u32int*) 0xA0000000;
u32int do_page_fault;
do_page_fault =*ptr;
the page fault should occur at the line
Code: Select all
u32int *ptr = (u32int*) 0xA0000000;
as i have only done identity mapping in the initialise_paging, so this address 0xA0000000 should cause a page fault.
the o/p in bochs is
Code: Select all
00055859000i[CPU ] protected mode
00055859000i[CPU ] CS.d_b = 32 bit
00055859000i[CPU ] SS.d_b = 32 bit
00055859000i[CPU ] | EAX=00000023 EBX=00104f84 ECX=000b8000 EDX=00101014
00055859000i[CPU ] | ESP=00104f70 EBP=00067edc ESI=00000000 EDI=00026385
00055859000i[CPU ] | IOPL=0 NV UP DI PL ZR NA PE NC
00055859000i[CPU ] | SEG selector base limit G D
00055859000i[CPU ] | SEG sltr(index|ti|rpl) base limit G D
00055859000i[CPU ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00055859000i[CPU ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00055859000i[CPU ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00055859000i[CPU ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00055859000i[CPU ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00055859000i[CPU ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00055859000i[CPU ] | EIP=00100c19 (00100c19)
00055859000i[CPU ] | CR0=0xe0000011 CR1=0x00000000 CR2=0x00000000
00055859000i[CPU ] | CR3=0x00108000 CR4=0x00000000
I have attached the source code of my kernel, its similar to james molly's tutorial...
guys, need ur help... please guide me through this...
thanks
Posted: Mon Feb 11, 2008 4:44 am
by AJ
redDot wrote:
the page fault should occur at the line
Code: Select all
u32int *ptr = (u32int*) 0xA0000000;
No it shouldn't. It should occur at:
as i have only done identity mapping in the initialise_paging, so this address 0xA0000000 should cause a page fault.
Have you identity mapped the entire 4GB range? If you have, the system doesn't care that the RAM you are accessing does not exist - it will attempt the read silently anyway. You only get a PFE if 0xA0000000 is not paged in (whether or not the physical RAM exists). Try:
Code: Select all
printf("%x", your_page_directory[0x280]);
If that prints a valid entry, try:
If that also prints a valid entry, the range is paged in and you will get no PFE. Of course, this assumes you have some kind of working printf...
Cheers,
Adam