Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
You should set a breakpoint just before enabling paging. Then use your debugger to examine your Page Table to see that it contains the entries you expect it to.
A page table entry for protected mode is a 32bit value. I just skimmed your code and as far as I can see your code creates entries as a struct that's 40 bytes in size.
You either want to change your structs to use bool and be packed or more reliably use macros to create the entry you want. Below is what I use to create a pml4 entry. It's for 64bit tho but the principle is the same.
There are also some other issues so you might want to grab a cup of coffee and read the relevant part of the Intel docs again. The accessed bit is best set to zero on creation for example. Also unless 32bit paging is way different then 64bit the caching bit only selects between write-through and write-back, it doesn't disable caching as a whole.
"Always code as if the guy who ends up maintaining it will be a violent psychopath who knows where you live." - John F. Woods
A page table entry for protected mode is a 32bit value. I just skimmed your code and as far as I can see your code creates entries as a struct that's 40 bytes in size.
Slight correction here - his structures would be 32 bits on any sane compiler that implements bit fields properly.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
A page table entry for protected mode is a 32bit value. I just skimmed your code and as far as I can see your code creates entries as a struct that's 40 bytes in size.
Slight correction here - his structures would be 32 bits on any sane compiler that implements bit fields properly.
At the moment he's defining every member in his structs as an int.
"Always code as if the guy who ends up maintaining it will be a violent psychopath who knows where you live." - John F. Woods
Right, and under the assumption that sizeof(int) = 32 bits, the bit fields he creates would be 32 bits in size. I.e. he is using bit fields - he is not defining a normal structure. If he was not using bit fields, you would be right.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
catnikita255 - Your code is incomplete. Most importantly, paging_ident doesn't completely identity map the space you want. Think of it from the perspective of the cpu, given only the page directory, how can it find your page table when you marked all of its entries as non-usable? In fact, I don't see anywhere where you set tbl_addr which should store the page frame number.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
neon wrote:catnikita255 - Your code is incomplete. Most importantly, paging_ident doesn't completely identity map the space you want. Think of it from the perspective of the cpu, given only the page directory, how can it find your page table when you marked all of its entries as non-usable? In fact, I don't see anywhere where you set tbl_addr which should store the page frame number.
Oh, I realized it before you. Here's an updated code:
I have to assume the code does not work. tbl_addr stores a page frame number not an address. For example, something like pgdir[0].tbl_addr = pgtbl >> 12; should work. I don't quite know what tbl.phys_addr is since its not in the original post, however the same concept applies to the page directory tbl_addr field here. Although in this case you can actually just do "tbl.phys_addr = i" assuming phys_addr = tbl_addr.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
I have to assume the code does not work. tbl_addr stores a page frame number not an address. For example, something like pgdir[0].tbl_addr = pgtbl >> 12; should work. I don't quite know what tbl.phys_addr is since its not in the original post, however the same concept applies to the page directory tbl_addr field here. Although in this case you can actually just do "tbl.phys_addr = i" assuming phys_addr = tbl_addr.
phys_addr is a renamed tbl_addr in page_table_t. And it doesn't have anything about table address or index, I forgot to rename it.
Your page directory is at a physical address higher than 2GB, and the page table address is much lower in physical memory (just above the 1MB mark)? That just doesn't feel right. I don't know how you are assigning physical pages but I would guess that most people assign the lowest available page first.
Without going in to the full details of how you are managing your pages I just have the gut feeling that your page table is screwed up.