Page 1 of 1
Page Fault or Triple Fault on Page Directory Switch
Posted: Mon Jul 04, 2011 2:20 pm
by Nessphoro
I've ran into a problem,
When I clone a page directory and switch it, I either triple fault or page fault, though I've checked that that cloned directory has kernel pages present and linked properly.
Code for directory switch:
Code: Select all
void switch_page_directory(page_directory *newDir)
{
current_directory = newDir;
__asm __volatile("mov %0, %%cr3":: "r"(current_directory->physicalAddr));
unsigned int cr0;
__asm __volatile("mov %%cr0, %0": "=r"(cr0));
cr0 |= 0x80000000; // Enable paging!
__asm __volatile("mov %0, %%cr0":: "r"(cr0));
}
A funny thing though, I know this code works because I switch and clone the kernel directory at startup.
Any help is appreciated.
P.S. Where can I find the error codes for Protected Mode Exceptions?
Re: Page Fault or Triple Fault on Page Directory Switch
Posted: Tue Jul 05, 2011 1:13 am
by Combuster
Do you know the difference between linear and physical addresses, and you are using the right ones at the right place? What does bochs' debugger tell you about the exact page table mapping?
P.S. Where can I find the error codes for Protected Mode Exceptions?
Surely you RTFM'd before asking?
Re: Page Fault or Triple Fault on Page Directory Switch
Posted: Tue Jul 05, 2011 1:37 am
by xenos
If you have already enabled paging before, there is no need to do it again when you change the page directory. So the following should do exactly the same:
Code: Select all
void switch_page_directory(page_directory *newDir)
{
current_directory = newDir;
__asm __volatile("mov %0, %%cr3":: "r"(current_directory->physicalAddr));
}
However, since it should do the same, it will probably not solve the problem - there must be a bug somewhere else...
P.S. Where can I find the error codes for Protected Mode Exceptions?
Intel Manuals, Volume 3A, Chapter 6.13.
Re: Page Fault or Triple Fault on Page Directory Switch
Posted: Tue Jul 05, 2011 2:10 am
by Nessphoro
Combuster wrote:Do you know the difference between linear and physical addresses, and you are using the right ones at the right place? What does bochs' debugger tell you about the exact page table mapping?
P.S. Where can I find the error codes for Protected Mode Exceptions?
Surely you RTFM'd before asking?
I'm sure, I'm using the right address.
Not quite in a good relationship with bochs since never used it - I use QEMU
Re: Page Fault or Triple Fault on Page Directory Switch
Posted: Tue Jul 05, 2011 2:46 am
by Combuster
Nessphoro wrote:I'm sure, I'm using the right address.
Earlier, Nessphoro wrote:I either triple fault or page fault
It is not the right address, your mind is playing tricks on you. It even coerced you into posting a contradiction
Re: Page Fault or Triple Fault on Page Directory Switch
Posted: Tue Jul 05, 2011 1:23 pm
by Nessphoro
Combuster wrote:Nessphoro wrote:I'm sure, I'm using the right address.
Earlier, Nessphoro wrote:I either triple fault or page fault
It is not the right address, your mind is playing tricks on you. It even coerced you into posting a contradiction
Well here is the thing why I'm pretty sure thats the right address,mate.
First two megabytes of memory are identity mapped, and page directories are being allocated there so virtual address=physical address.
And secondly it works because I already did switch to a page directory that is a clone of the kernel one, but I can't do that again.
Re: Page Fault or Triple Fault on Page Directory Switch
Posted: Tue Jul 05, 2011 2:47 pm
by xenos
Nessphoro wrote:And secondly it works because I already did switch to a page directory that is a clone of the kernel one, but I can't do that again.
And the page directory you switch to the second time is also a clone of the kernel page directory (so the first 2 MB are identity-mapped)? If you switch to a different page directory where the first 2 MB (and thus the virtual address where you are executing code, i.e., EIP) are not identity mapped, your code will run into nowhere, and thus cause a page fault or even triple fault.
Re: Page Fault or Triple Fault on Page Directory Switch
Posted: Tue Jul 05, 2011 2:58 pm
by Nessphoro
But I'm cloning a clone of the kernel directory
Re: Page Fault or Triple Fault on Page Directory Switch
Posted: Tue Jul 05, 2011 4:29 pm
by Combuster
Well here is the thing why I'm pretty sure
Prove it.
What you posted so far is not a proof. Robbing the same place a second time when you got away with the first also has that tendency to not work.
Re: Page Fault or Triple Fault on Page Directory Switch
Posted: Tue Jul 05, 2011 4:43 pm
by Nessphoro
Okay so what do you suggest I do
Edit: I just tried to switch back to kernel directory - didn't work either
Re: Page Fault or Triple Fault on Page Directory Switch
Posted: Tue Jul 05, 2011 4:51 pm
by Nessphoro
Problem solved
And it wasn't related to the address at all
Re: Page Fault or Triple Fault on Page Directory Switch
Posted: Tue Jul 05, 2011 10:01 pm
by shadowH3
So WHAT DID you do?
Un rob the bank? LOL but really...
Running into an issue where GRUB reloads(not triple F) on page init, IE when you flip that paging bit.
Im assigning the kernel directory as physical @ 1023.This is what you didnt mention.
Phys<> always VIRTUAL.
Mine maps @ 4gb unless I do this, no matter what.
By default I get 4GB address, not a 1mb one, mapped or not.(then grub reloads on paging init)
The page_init code can be in pascal, I put it where it is to test a theory, and in part for RING3, I WAS CORRECT. That code HAS to be where it is(but it needs page [1](in this case [1022]..) online or it GPFs with a overflow/div by zero error(DUH!). At least i GET to ring3...
my bad...line should read:
kernel_directory:=longword(VirtToPhys(@pd^[1023].DirPhys));
..but it doesnt change the address given back to me....hmmm...
your C is confusing me...
__asm __volatile("mov %%cr0, %0": "=r"(cr0));
cr0 |= 0x80000000; // Enable paging!
__asm __volatile("mov %0, %%cr0":: "r"(cr0));
reads as:
mov eax,cr0
bts eax, 31 ;or eax, 0x8000 0000
mov cr0,eax ;enable paging....
--correct? otherwise it looks like you are moving the cr0 on itself, or a variable(undefined called cr0 onto the cr0 register)..which is it?
Re: Page Fault or Triple Fault on Page Directory Switch
Posted: Tue Jul 05, 2011 10:31 pm
by Nessphoro
The problem was far more deeper. I was cloning the directory far more early then was required to.
What "my" code does is mov value of cr0 register into a variable called cr0 (I know), then I OR the variable with 0x80000000 to set the bits I need to, and mov it back into cr0 register
P.S. Thats not C you silly, thats inline assembler
P.S.S I don't know Pascal but I read some of your ASM, and it's rather unorthodox, why don't you just push the Magic Number and Bootloader Info on stack?
And in your ISR code "ISRWithoutErrorCode 21 ; Unused- for DOS" - no it's not DOS uses Int 21h (0x21) = 33 decimal, but by all means if it makes sense to you - use it.
IRQ0 - adjust the timer to something more useful than 110ms intervals - but again if thats what you want.
And why do you have code for A20 line? I don't think you'll ever need to disable that - and GRUB enables it for you.
And where you enabled paging "; or eax,0x8000000 ;one too many zeroes??" that's actually one not enough, you need to set the bit 31 - last bit in a DWORD - it's the last( thirty second) one because we use zero-based index
Re: Page Fault or Triple Fault on Page Directory Switch
Posted: Mon Sep 03, 2012 10:09 pm
by Enerccio
Can you post detailed solution? Because I might be stuck on the same thing...