I've been working some more on paging, and I'm to the point where I have to start worrying about page frame allocations. What I'm needing to do is figure out how to create new page tables, at the proper indices so I can map virtual addresses to physical addresses when a page fault occurs. I understand that there are quite a number of opinions on how to do this, and was wondering if what I have in mind is a good approach to the issue.
Here's the source code I'm discussing.
Here's a screen shot of what I'm getting.
My memory is currently set up as follows:
0x0 - 0xF,FFFF = GRUB space
0x10,0000 - 0x10,9D90 = my kernel
0x10,A000 - 0x12,9FFC = a stack of page aligned physical memory addresses
0x12,A000 = the page I'm using for my page directory
0x12,B000 = the page I'm using for my page table.
What I've done is created a stack of the page aligned physical addresses available to the system after the kernel, a page directory, and a page table. I then identity mapped everything up to the page table, and enabled paging. What I'm having a problem with is the chicken and the egg issue that goes along with creating new page directories, and page tables, when a page fault happens. When a page fault happens I need to map the physical address of a page to a virtual address, but in order to do that I need to be able to zero out the contents of the page which requires the memory to be mapped so I can write to it. If I attempt to write to memory that's not mapped I'll cause a page fault which will create an infinite loop of page faults, and get me no where. What's the solution to this dilemma?
Here's what I'm thinking I'll do to create a new page table, and page, when a page fault happens:
* Get the physical address of a free page off the stack.
* Put that physical address on my existing page table to map it to a given virtual address so I can write to the page.
* Zero out that page so there's no garbage in it.
* Copy the physical address for that page table to the proper index in the page directory.
* Get another physical memory address from the stack.
* Put that physical address on my existing page table to map it to a given virtual address so I can write to the page.
* Zero out that page so there's no garbage in it.
* Copy the physical address of that page to the proper index on my previously created, and mapped, page table.
* Mark the newly created page table as being present in memory by updating the value in the page directory.
* Mark the newly created page as being present in memory by updating the value in the page table using the mapped address I created to write to it.
* Unmap the virtual addresses I used to write to the two pages.
I was wondering if this sounds sane to everybody else. I realize there are some steps that I've excluded, but I wasn't looking to lay out all of the details of the page fault handler. Are there any big "gotchas" I'm missing?
EDIT TO THE MODS: Please PM me if I'm creating too many discussions about similar topics. The feedback from the forum is proving to be very helpful to me, but I don't want to step on any toes. I figured this question was different enough from the thread I created yesterday to be worthy of its own post.
Creating new page directories, and page tables on demand
Creating new page directories, and page tables on demand
Last edited by PatSanf on Tue Mar 03, 2015 6:13 pm, edited 1 time in total.
- eryjus
- Member
- Posts: 286
- Joined: Fri Oct 21, 2011 9:47 pm
- Libera.chat IRC: eryjus
- Location: Tustin, CA USA
Re: Creating new page directories, and page tables on demand
If at some point you want to move away from identity mapping, you will need some method of finding your page tables in virtual memory. For that, you might consider recursive mapping.PatSanf wrote:Are there any big "gotchas" I'm missing?
Here is the section of the Wiki article.
The forum conversation that solidified the concept for me.
There are several other posts that you can search for as well.
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
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
Re: Creating new page directories, and page tables on demand
I will be sure to read those links. Is recursive mapping putting the address of the page directory in the page directory as a page table so you can have it mapped, and write to it whenever you want to?eryjus wrote:If at some point you want to move away from identity mapping, you will need some method of finding your page tables in virtual memory. For that, you might consider recursive mapping.PatSanf wrote:Are there any big "gotchas" I'm missing?
Here is the section of the Wiki article.
The forum conversation that solidified the concept for me.
There are several other posts that you can search for as well.
Re: Creating new page directories, and page tables on demand
That's the gist of it, yes.PatSanf wrote:Is recursive mapping putting the address of the page directory in the page directory as a page table so you can have it mapped, and write to it whenever you want to?
Re: Creating new page directories, and page tables on demand
This is kind of a general problem- not only do you need to access potentially-unmapped memory when dealing with page tables, but when dealing with IPC, memory-mapped IO, firmware tables, etc. Recursive page tables solve one piece of this, but nothing beyond that. You'll still need a more general solution.
With a 64-bit address space you have enough room to just identity-map all of physical memory somewhere (even in massive servers with 2TB of ram you won't even notice- x86_64 Linux actually reserves 64TB of address space for this), and access it by adding a fixed offset to the physical address; with a 32-bit address space you probably need to reserve a section of address space to dynamically map and unmap physical pages the way you described.
With a 64-bit address space you have enough room to just identity-map all of physical memory somewhere (even in massive servers with 2TB of ram you won't even notice- x86_64 Linux actually reserves 64TB of address space for this), and access it by adding a fixed offset to the physical address; with a 32-bit address space you probably need to reserve a section of address space to dynamically map and unmap physical pages the way you described.