Hard time understanding recursive mapping

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Hard time understanding recursive mapping

Post by mariuszp »

Previously when I had to modify the data of a page (such as a page table, page directory, etc, as they are also one page long each), I just mapped them to a page called an "ISP", and I switched the frame of the ISP whenever I had to work with a different page. This proved extremely inefficient when trying to copy address spaces (e.g. when calling fork()).

I'm trying to do recursive mapping. I don't need to do this for the entire PML4 - each process only gets one PDPT (mapped as the first PML4 entry) and I want to recursive-map that. So the equations for a PD and PT would be as follows:

Code: Select all

addr_pdpt = 0xFFFFFFFFF000;
addr_pd = 0xFFFFFFE00000 + i_pd * 0x1000;
addr_pt = 0xFFFFC0000000 + i_pd * 0x200000 + i_pt * 0x1000;
But if I substitute 511 into i_pd, I get addr_pd = addr_pdpt, so the PD struct for the last directory would be at the same address as the address of the PDPT struct. Then how do I access the last PD so that I can map more tables into it (as tables in the last PD contain pages that map to PTs of other PDs).

Am I missing something here? If I treat the PDPT and the last PD as the same structure, then setting its first entry to some frame would mean that adress 0 would simultaneously contain the page data and all levels of paging structures, which clearly makes no sense.

Could someone show some sample code maybe? (or pseudo-code?)

Please help :(

P.S. I'm in 64-bit Long Mode.
User avatar
eryjus
Member
Member
Posts: 286
Joined: Fri Oct 21, 2011 9:47 pm
Libera.chat IRC: eryjus
Location: Tustin, CA USA

Re: Hard time understanding recursive mapping

Post by eryjus »

You might take a look at this post: http://forum.osdev.org/viewtopic.php?f=1&t=28734
Adam

The name is fitting: Century Hobby OS -- At this rate, it's gonna take me that long!
Read about my mistakes and missteps with this iteration: Journal

"Sometimes things just don't make sense until you figure them out." -- Phil Stahlheber
jbemmel
Member
Member
Posts: 53
Joined: Fri May 11, 2012 11:54 am

Re: Hard time understanding recursive mapping

Post by jbemmel »

User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Hard time understanding recursive mapping

Post by iansjack »

There's an explanation, with diagrams, that might help here: http://pdosnew.csail.mit.edu/6.828/2014 ... /uvpt.html
thomasloven
Member
Member
Posts: 89
Joined: Tue Feb 26, 2008 10:47 am
Location: Sweden

Re: Hard time understanding recursive mapping

Post by thomasloven »

And yet another one: http://thomasloven.com/blog/2012/06/Rec ... Directory/
though not for long mode..
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: Hard time understanding recursive mapping

Post by mariuszp »

So, I take that mapping the PDPT's last entry onto itself would cause the last 1GB it encompasses to be mapped, and therefore each structure will be accessible, and then I can use the equations above to find each structure and therefore not bother about mapping the last PD, PT etc? But then I'm still confused, because only 1 frame gets allocated, and all those structures cannot be stored in 1 frame.

Just to make sure I understand: I initalize the PDPT as follows, correct?

Code: Select all

PDPT *pdpt = getPDPT();
pdpt->entries[511].present = 1;
pdpt->entries[511].pdPhysFrame = pdptPhysFrame;
Then, if I want a pointer to a specific page table entry, I'd do the following, correct?

Code: Select all

PTe *getPTE(uint64_t addr)
{
	uint64_t pageIndex = (addr & 0xFFF);
	addr >>= 12;
	uint64_t tableIndex = (addr & 0x1FF);
	addr >>= 12;
	uint64_t dirIndex = (addr & 0x1FF);

	PDPT *pdpt = (PDPT*) (0xFFFFFFFFF000);
	if (!pdpt->entries[dirIndex].present)
	{
		pdpt->entries[dirIndex].present = 1;
		pdpt->entries[dirIndex].pdPhysFrame = phmAllocFrame();
	};
	
	PD *pd = (PD*) (0xFFFFFFE00000 + dirIndex * 0x1000);
	if (!pd->entries[tableIndex].present)
	{
		pd->entries[tableIndex].present = 1;
		pd->entries[tableIndex].ptPhysFrame = phmAllocFrame();
	};
	
	PT *pt = (PT*) (0xFFFFC0000000 + dirIndex * 0x200000 + tableIndex * 0x1000);
	return &pt->entries[pageIndex];
};
Am I getting this right? The PDPT itself is the first entry of the PML4.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: Hard time understanding recursive mapping

Post by Candy »

Yes. The trick is that you should see the table as containing itself 4 times -- every time mapped as the top (or bottom) entry. Accessing the next layer is done from the top or bottom as you first enter the location of that entry in the toplevel page table, then the next layer (which is now mappable as there is a page table for it!) and so on.
mariuszp
Member
Member
Posts: 587
Joined: Sat Oct 16, 2010 3:38 pm

Re: Hard time understanding recursive mapping

Post by mariuszp »

Candy wrote:Yes. The trick is that you should see the table as containing itself 4 times -- every time mapped as the top (or bottom) entry. Accessing the next layer is done from the top or bottom as you first enter the location of that entry in the toplevel page table, then the next layer (which is now mappable as there is a page table for it!) and so on.
OK, thank you for the help. It appears to be working :)
Post Reply