Page 1 of 1

Inserting the Page Directory into itself

Posted: Thu Feb 23, 2012 9:13 am
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.

Re: Getting free page for page table itself

Posted: Thu Feb 23, 2012 10:16 am
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

Re: Getting free page for page table itself

Posted: Thu Feb 23, 2012 1:06 pm
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 :) ).

Re: Getting free page for page table itself

Posted: Thu Feb 23, 2012 2:13 pm
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

Re: Getting free page for page table itself

Posted: Thu Feb 23, 2012 3:10 pm
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.

Re: Getting free page for page table itself

Posted: Thu Feb 23, 2012 3:46 pm
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 :)

Re: Getting free page for page table itself

Posted: Thu Feb 23, 2012 5:22 pm
by invalid
Thanks! :)

Re: Mapping the Page Directory into itself

Posted: Thu Feb 23, 2012 10:22 pm
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.

Re: Mapping the Page Directory into itself

Posted: Fri Feb 24, 2012 6:46 am
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.