Question about 32-bits paging

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.
Post Reply
NotSchur
Posts: 2
Joined: Fri Sep 20, 2019 10:37 am
Contact:

Question about 32-bits paging

Post by NotSchur »

Hi all!

I'm getting back into osdev and there is one thing I can't figure out about paging.
My code for getting a page table entry from a virtual address looks basically like this

Code: Select all

uint32_t dir_index = DIRECTORY_INDEX(virt);
uint32_t table_index = TABLE_INDEX(virt);

directory_entry_t* dir = (directory_entry_t*) 0xFFFFF000;
page_t* table = ((uint32_t*) 0xFFC00000) + (0x400 * dir_index);

if (dir[dir_index] & PAGE_PRESENT) {
	return &table[table_index];
}
It's about the same code given in the wiki page about paging (https://wiki.osdev.org/Paging#Manipulation) and it works like a charm.

My question: why is table not calculated like in the following code? Why does my current code work?

Code: Select all

page_t* table = ((uint32_t*) 0xFFC00000) + (dir_index << 12);
Why do we multiply the index by 0x400 (i.e left-shift by 10) instead of multiplying by 0x1000? Multiplying by 0x400 is like left-shifting by 10 bits, so the index in the page directory should be mangled by 2 bits... I don't get it. Isn't that address translated the same way every other linear address is?

That's the last thing standing in my way for understanding paging :(
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Question about 32-bits paging

Post by alexfru »

NotSchur wrote:

Code: Select all

page_t* table = ((uint32_t*) 0xFFC00000) + (0x400 * dir_index);
My question: why is table not calculated like in the following code? Why does my current code work?

Code: Select all

page_t* table = ((uint32_t*) 0xFFC00000) + (dir_index << 12);
Why do we multiply the index by 0x400 (i.e left-shift by 10) instead of multiplying by 0x1000? Multiplying by 0x400 is like left-shifting by 10 bits, so the index in the page directory should be mangled by 2 bits... I don't get it.
It's C. You're adding to a pointer to uint32_t. Adding 1 advances the pointer to the next uint32_t (4 bytes away).
linguofreak
Member
Member
Posts: 510
Joined: Wed Mar 09, 2011 3:55 am

Re: Question about 32-bits paging

Post by linguofreak »

NotSchur wrote: My question: why is table not calculated like in the following code? Why does my current code work?

Code: Select all

page_t* table = ((uint32_t*) 0xFFC00000) + (dir_index << 12);
To expand on alexfru's response, if this code snippet were instead:

Code: Select all

page_t* table = (uint32_t*)((0xFFC00000) + (dir_index << 12)); 
So that you cast to a pointer *after* adding dir_index, it should work identically to your code.
NotSchur
Posts: 2
Joined: Fri Sep 20, 2019 10:37 am
Contact:

Re: Question about 32-bits paging

Post by NotSchur »

That makes perfect sense now! Kicking myself for not having spotted this #-o
Thanks a lot to both of you!
Post Reply