Page 1 of 1

PML4 paging in long mode

Posted: Tue Mar 01, 2011 11:16 am
by itisiuk
Hi

I have been working on a 64bit kernel for some time now and have gotten most of the basics working.

I am now working on the pml4 paging code. I am using 4kb page size as described in the AMD64 Architecture Programmers Manual, Volume 2: System Programming

for 2 weeks now I have not been able to find out why my code is not working, the system hangs once the PML4E physical address is written into cr3

I have attached the code to this post

Re: PML4 paging in long mode

Posted: Tue Mar 01, 2011 2:24 pm
by a5498828
2 weeks and you cannot find single bug?
you learn basics using c?
AND you are suprised you have such problems?


for learning i suggest bochs + fasm, i am using it and been able to find every bug i made without much problems.


if you use real hardware and enter long mode from p mode, setup excpetion entries in idt and tell me what exception are you getting.

Re: PML4 paging in long mode

Posted: Tue Mar 01, 2011 2:31 pm
by AlfaOmega08
may I suggest to use the packed attribute on the structures in the paging.h file?

Edit:
moreover all the set_* functions have this line:

Code: Select all

PML4E_4K *p = (PML4E_4K *)&pml4e;
Why taking the pointer of a pointer? The following should be a step further to the solution:

Code: Select all

PML4E_4K *p = (PML4E_4K *) pml4e;

Re: PML4 paging in long mode

Posted: Tue Mar 01, 2011 2:44 pm
by itisiuk
thanks AlfaOmega08, ive added the packed structure missed that thanks
also removed the pointer of a pointer

a5498828, i am not getting an exception when im testing, idt entries are setup. the system just hangs.
i jsut cant see what ive done wrong as i have been going though the code to much and am now making more mistakes than solutions.

im not learning, ive already have a working 32bit kernel but am currently trying a 64bit kernel as i wanted to try something else.
im currently using qemu, gcc and nasm

**** edit ****
still not working
going to read the documents again, doing something wrong with the physical address in the tables i think

Re: PML4 paging in long mode

Posted: Tue Mar 01, 2011 2:56 pm
by Tosi
I don't know 64-bit (inline) assembly too well so this might be wrong, but:

Code: Select all

void write_cr3(unsigned long long value)
{
 __asm__ __volatile__("movq %%rax, %%cr3"
                      :
                      :"r"(value));
}
You are specifically using RAX to move the value into cr3, but the constraint "r" for the input lets the compiler decide which register to put it in. That means code like this could be getting generated:

Code: Select all

movq value, rcx
movq rax, cr3
And cr3 is getting written with garbage data from RAX. To fix this, either do:

Code: Select all

void write_cr3(unsigned long long value)
{
 __asm__ __volatile__("movq %0, %%cr3"
                      :
                      :"r"(value));
}
To let the compiler decide which register to use, or:

Code: Select all

void write_cr3(unsigned long long value)
{
 __asm__ __volatile__("movq %%rax, %%cr3"
                      :
                      :"a"(value));
}
To specifically choose RAX.

Re: PML4 paging in long mode

Posted: Fri Mar 04, 2011 11:42 am
by itisiuk
hi, thanks tosi,
just got around to testing again, been at work far to much.
although that solution didnt fix then problem, i decided to try

void write_cr3(unsigned long long value)
{
asm volatile (
"mov %[value], %%rax\n"
"mov %%cr3, %%rax"
: [value] "=r" (value)
);
}

this works perfectly now, i still have no idea why
void write_cr3(unsigned long long value)
{
__asm__ __volatile__("movq %%rax, %%cr3"
:
:"r"(value));
}
didnt work as it does the same thing

anyway, thanks for your help guys.
if anyone wants the revised code, please msg me and ill post it up

Re: PML4 paging in long mode

Posted: Fri Mar 04, 2011 12:16 pm
by DLBuunk
itisiuk wrote:i decided to try

void write_cr3(unsigned long long value)
{
asm volatile (
"mov %[value], %%rax\n"
"mov %%cr3, %%rax"
: [value] "=r" (value)
);
}

this works perfectly now, i still have no idea why
Sorry to burst your bubble, but it does not. If it appears to work that is because you use identity paging.
The code above does move the value into rax and than it moves cr3 into rax, not the other way around. The way the original did not work was because you allowed gcc to put value in any register, and than assumed it was in rax. Furthermore you are putting value in the outputs, rather than at the inputs of the asm template, where it belongs.
See the post by Tosi for the solution, also read here: http://www.ibiblio.org/gferg/ldp/GCC-In ... HOWTO.html

And a general word of advise: if you don't know why something works, don't use it, as it may break unexpectedly.

Re: PML4 paging in long mode

Posted: Fri Mar 04, 2011 1:09 pm
by itisiuk
yup, just noticed myself
dammit, think im gonna have a break for a while. turning out so much stupid code at the min

Re: PML4 paging in long mode

Posted: Fri Mar 11, 2011 11:18 am
by itisiuk
well, finally found why it appears to hang after writing a complete different method and the same thing happening.
my screen pointer was pointing to the a0xb800 rather than the higher half memory address.
re-wrote everything to point to the serial port output now so i can debug easyer.

again thanks for your help guys

ill tidy up the code and if anyone wants it msg me