Creating page tables with virtual addresses?

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
trime

Creating page tables with virtual addresses?

Post by trime »

I'm trying to write a routine to generate a set of page tables and a page directory for a new process image in my OS. However after a lot of thought I've come unstuck on how to compute the actual values to store in the page table directory. From what I read, these must be the physical addresses of the page tables. (I presume that if they were virtual, then it would try and resolve them by looking the address up in the table, and it would resolve that by looking it up... etc forever)

The only way I can create the tables and ensure that they're physical values is if I forcibly create them at a fixed position in memory, since my malloc will allocate them a virtual address. I can't even try and manually decode the address because of the infinite loop I mentioned above.

Google gives me lots of information about paging, but nothing really specific enough - just that it has 2 levels and that the top level contains 'pointers to' the lower levels (although exactly how that works is glossed over)

Any help would be much appreciated. Thanks
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Creating page tables with virtual addresses?

Post by Pype.Clicker »

may i suggest you to check the Intel Manuals (system programming, chapter on Paging) ?
trime

Re:Creating page tables with virtual addresses?

Post by trime »

I've just finished reading the chapter on paging and I'm still unsure of exactly how to calculate the physical addresses of the page tables that the page directory requires. The manual did confirm that physical addresses are required, but didn't give any suggestion of how to obtain them.

Am I required to build all my page tables in a linearly mapped part of memory? That seems pretty klunky, but it's the only solution I can think of.

Thanks for your time :)
Tim

Re:Creating page tables with virtual addresses?

Post by Tim »

Physical RAM addresses are 0..top, where top is the highest RAM address, i.e. the amount of memory you've got installed in the computer. Page directories and page tables must be page aligned, so you must split physical memory into page-sized chunks. You will need to build a physical page allocator before you can do anything useful, to make sure pages don't get mixed up. My memory management tutorials at http://www.osdever.net/ should explain it all -- if not, please ask.
trime

Re:Creating page tables with virtual addresses?

Post by trime »

Sorry perhaps I should have been clearer. I already have paging up and running fine by this stage, and I have a reasonably good understanding of the theory behind it (or so I hope :) )

At this point in my kernel I want to load in a new executable. I've parsed the headers etc in the file, and know how many pages to allocate and which require what data in them.

So, like you say in your tutorials, I need to set up a new set of page tables for the new process, but I don't know where to put them. If I allocate space for a table using malloc, it'll just give me a virtual address in the kernel space (above 0xC0000000, and I can align it simply enough), and while that's ideal in that it's nicely protected, I can't put the that into the page directory, I need it's physical address, and I have no idea what that is. Thanks again.
Slasher

Re:Creating page tables with virtual addresses?

Post by Slasher »

hi, to do what you want to do you will need a physical memory allocator that allocates 4k physical pages that are aligned as required.Only the kernel (or better only the paging system and routines) use this allocator. On system initialization, you build a bitmap or stack(i use this method cause its easier to implement and faster) of physical page addresses starting from 0 to top_ram ie stack will look like this
0,4k,8k,12k,16k,..........,(top_ram - 4k)k
so when you need an address that is a physical one just get the address at the top of the stack. to free a physical page,just put the address at the top of the stack.

hope this helps

this is the overall scheme (little details left out) like you should have 2 stacks
one with address under 16mb used for DMA and co that can only access addresses <=16mb
and the other with the rest of ram. Also remove addresses that are already in use like BIOS areas and PCI mapped addresses
Ozguxxx

Re:Creating page tables with virtual addresses?

Post by Ozguxxx »

If your paging is ok then why dont you just map first 4 Meg onto itself on system init and then put page dir and first page table somewhere in here? I think most people go in that way. If you are trying to ask how you can set seperate address space for each process, I think it will be better to use kernel address space for them FOR NOW and then proceed with this for some time until you get whole idea. I think this memory management stuff is kinda confusing for some time but as you do things, you get used to thinking more creatively and more clearly about it. I hope my explanation is doing some good. Good luck...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Creating page tables with virtual addresses?

Post by Pype.Clicker »

okay, let's say you have a physical allocator (i.e. pg_frame phys_alloc(pg_count)) and a virtual memory allocator (i.e. void* x=kmalloc(size)).

What you want to do (iiuc) is to set up a new address space to run your process in it, right ?

So the sequence you can use is:

Code: Select all

     pg_frame new_pdbr=phys_alloc(1);
     pgEntry* mapped_new_pdbr= pg_create_mapping(new_pdbr);
     
     memcpy(new_pdbr, old_pdbr, 4096);

     pg_remove_mapping(mapped_new_pdbr);
Which creates a new address space which is the exact copy of the existing one. Then it's up to you and your address space manager to replace my "memcpy" by something that better suits your need -- for instance copying only entries that are not tagged with the User bit so that you only have the kernel in the new space :)

You'll notice that i have used an extra service pg_create_mapping, which receives a physical address and returns a virtual address where the page get mapped. This is the reverse operation than what malloc does.

Such a service can be built by reserving a page table for such temporary mappings and looking for a free entry (unused), then filling the entry in the page table with the given page frame ;). You can get a look at clicker's PageFrameViewer
Post Reply