Inserting the Page Directory into itself

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
invalid
Member
Member
Posts: 60
Joined: Thu Feb 23, 2012 8:39 am

Inserting the Page Directory into itself

Post by invalid »

Hello!

Not much of a surprise, I'm developing a hobby OS :) I have learned a lot doing it, thanks to your impressively helpful wiki and forum community.
But I'm still a newbie, and I'd like to hear opinion of someone more experienced.

I'm trying to keep things simple, and introduce more sophisticated mechanisms only when the code seems stable. Now, I want to upgrade my paging management. So far, I've just identity-mapped all available RAM - but I believe that it's inefficient, especially when I start to provide tasks with their instance of Page Directory (not necessarily identity-mapped). Hence, I need some sort of dynamic page-table/page-entry marking/creating for allocated physical memory...

As I think about it, it seems quite simple except for one thing: say that I allocated a page frame. To mark (map) it, I lookup the Table in Directory, and set appropriate entry. But, when the Table is not present - I need a page for the Table itself :) This obviously leads to loop.
To solve this problem, I wanted to use one of Tables as a container for Tables pointers; then I read about trick with mapping a Page Directory as Table - is this correct (I mean, can a Page Directory pointer be an entry in Page Directory itself? The CPU sets some bits on Table entries, won't it be a problem?). Is this acceptable solution?

Thanks in advance.
Last edited by invalid on Mon Feb 27, 2012 7:31 pm, edited 2 times in total.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: Getting free page for page table itself

Post by JamesM »

Hi,

I think you'd be better served by separating out the concerns of physical memory management and virtual memory management.

A physical memory manager merely tracks the use/free state of pages of physical memory. A virtual memory manager merely maps or unmaps memory.

Now, the virtual memory manager will rely on the physical memory manager for the situation you mentioned where you need a new page for a page table (PDE). Similarly the PMM may require the VMM to map it some more memory to hold free pages (if using a stack to hold them, which is one of the two standard techniques).

This should never cause an infinite loop or dependency however. The worst case is that the PMM needs to map a page for its storage, and then the VMM needs to get a page from the PMM to map a page table. But that should be it - as long as your locking in the PMM can deal with this case and doesn't deadlock, you'll be fine.

Cheers,

James
invalid
Member
Member
Posts: 60
Joined: Thu Feb 23, 2012 8:39 am

Re: Getting free page for page table itself

Post by invalid »

Yes, the physical memory manager keeps track of physical regions (marked used/free), so it's able to provide a page without even knowing about Page Directory. But, to use that physical page, I need to map it at some virtual address. That means that I need to fill empty entry in some Page Table. What is my concern, is the moment when there are no free entries in any existing Table. Then I need to allocate,and map a page - which creates a loop (I need a free entry to get a free entry). Or am I missing something?

I like the idea of dedicated Table holding addresses of all Tables - then they all would be in contiguous virtual space. If this special Table can be a Directory itself, that would be great (KISS FTW :) ).
User avatar
gravaera
Member
Member
Posts: 737
Joined: Tue Jun 02, 2009 4:35 pm
Location: Supporting the cause: Use \tabs to indent code. NOT \x20 spaces.

Re: Getting free page for page table itself

Post by gravaera »

Yo:

That moment doesn't exist simply because it is impossible for it to exist :)

If you load the address of a completely blank page directory your next memory access will cause a triple fault. If you load the address of a page directory with only the kernel mapped safely for access, you will be unable to effect any changes to that address space; think of page tables and linear address mode as "trapping" yourself into a cell, which represents your address space. You cannot access anything outside of that address space unless the tables are changed.

Therefore before you enable paging, in simple terms, you have to load a page directory which was specially pre-designed and pre-filled to:
  • Map the kernel's image in pmem to the desired location in vmem.
  • Map the kernel's image in pmem to the same address in vmem. This "identity mapping" is needed really for one reason only: when you enable paging, the very next instruction you execute will require a TLB load for the address of the next instruction. You may discard the identity mapping after this.
  • Find a way to ensure that you can read and write to the page directory from within that page directory's address space, and optionally from other address spaces as well.
--Peace out
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.
invalid
Member
Member
Posts: 60
Joined: Thu Feb 23, 2012 8:39 am

Re: Getting free page for page table itself

Post by invalid »

Thanks! Luckily I have paging set up and running, I understand the concept and develop algorithms around it.

I'll try to narrow down my question:
Is putting a Page Directory address into itself (thus making it to act as the Page Table as well) correct and guaranteed to work, or is it just a hack? After all, PD is not a PT, although they have similar structure. I can't find any clear answer, so I ask here.
Bit 6 of PD entry is "0", but it means "Dirty" in PT entry. Is there no conflict?



I believe this tip should be pointed out in "Setting Up Paging" wiki page:
gravaera wrote: [*] Map the kernel's image in pmem to the same address in vmem. This "identity mapping" is needed really for one reason only: when you enable paging, the very next instruction you execute will require a TLB load for the address of the next instruction. You may discard the identity mapping after this.
User avatar
gravaera
Member
Member
Posts: 737
Joined: Tue Jun 02, 2009 4:35 pm
Location: Supporting the cause: Use \tabs to indent code. NOT \x20 spaces.

Re: Getting free page for page table itself

Post by gravaera »

I would say that it is a clever use of legal MMU mechanics and a valid, though inflexible solution to a real design problem.

--Peace out :)
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.
invalid
Member
Member
Posts: 60
Joined: Thu Feb 23, 2012 8:39 am

Re: Getting free page for page table itself

Post by invalid »

Thanks! :)
FallenAvatar
Member
Member
Posts: 283
Joined: Mon Jan 03, 2011 6:58 pm

Re: Mapping the Page Directory into itself

Post by FallenAvatar »

ydoom, I think what you are referring to is using one PT entry that points to the whole (parent) PD. Not a PD entry that points to the PD.
invalid
Member
Member
Posts: 60
Joined: Thu Feb 23, 2012 8:39 am

Re: Mapping the Page Directory into itself

Post by invalid »

tjmonk15 wrote:ydoom, I think what you are referring to is using one PT entry that points to the whole (parent) PD. Not a PD entry that points to the PD.
Nope. The PD entry pointing to the PD (and making it act as PT). Results are e.g. described here: http://forum.osdev.org/viewtopic.php?p=152010#p152010

However, I'm still not sure that this is not an ugly hack (there are some "reserved" bits....). But, since it works, and everyone does it - I did that too :)

EDIT:
In 32-Bit Page-Directory Entry that References a Page Table,
bit 6, and bits 8-11 are ignored (good!),
bit 7: If CR4.PSE = 1, must be 0 (otherwise, this entry maps a 4-MByte page); otherwise, ignored

In 32-Bit Page-Table Entry that Maps a 4-KByte Page,
bit 7: If the PAT is supported, indirectly determines the memory type used to access the 4-KByte page referenced by this entry; otherwise, reserved (must be 0)

So the only thing that might get fishy is bit 7, i guess.
Post Reply