PML4 paging in long mode
PML4 paging in long mode
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
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
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.
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.
- AlfaOmega08
- Member
- Posts: 226
- Joined: Wed Nov 07, 2007 12:15 pm
- Location: Italy
Re: PML4 paging in long mode
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:
Why taking the pointer of a pointer? The following should be a step further to the solution:
Edit:
moreover all the set_* functions have this line:
Code: Select all
PML4E_4K *p = (PML4E_4K *)&pml4e;
Code: Select all
PML4E_4K *p = (PML4E_4K *) pml4e;
Please, correct my English...
Motherboard: ASUS Rampage II Extreme
CPU: Core i7 950 @ 3.06 GHz OC at 3.6 GHz
RAM: 4 GB 1600 MHz DDR3
Video: nVidia GeForce 210 GTS... it sucks...
Motherboard: ASUS Rampage II Extreme
CPU: Core i7 950 @ 3.06 GHz OC at 3.6 GHz
RAM: 4 GB 1600 MHz DDR3
Video: nVidia GeForce 210 GTS... it sucks...
Re: PML4 paging in long mode
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
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
-
- Member
- Posts: 255
- Joined: Tue Jun 15, 2010 9:27 am
- Location: Flyover State, United States
- Contact:
Re: PML4 paging in long mode
I don't know 64-bit (inline) assembly too well so this might be wrong, but:
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:
And cr3 is getting written with garbage data from RAX. To fix this, either do:
To let the compiler decide which register to use, or:
To specifically choose RAX.
Code: Select all
void write_cr3(unsigned long long value)
{
__asm__ __volatile__("movq %%rax, %%cr3"
:
:"r"(value));
}
Code: Select all
movq value, rcx
movq rax, cr3
Code: Select all
void write_cr3(unsigned long long value)
{
__asm__ __volatile__("movq %0, %%cr3"
:
:"r"(value));
}
Code: Select all
void write_cr3(unsigned long long value)
{
__asm__ __volatile__("movq %%rax, %%cr3"
:
:"a"(value));
}
Re: PML4 paging in long mode
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
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
Sorry to burst your bubble, but it does not. If it appears to work that is because you use identity paging.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
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.
If you don't know what to say, please shut up.
Re: PML4 paging in long mode
yup, just noticed myself
dammit, think im gonna have a break for a while. turning out so much stupid code at the min
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
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
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