Page 1 of 1
Kernel Address Space
Posted: Fri Jun 07, 2013 8:13 pm
by BMW
If I make a higher half kernel setup where the kernel is placed at 0xC0000000 (3GB) and is present in the address space of all processes, would the kernel have its own address space, or just use the top 1GB of all processes address spaces? Would I have a page directory which is just for the kernel?
Re: Kernel Address Space
Posted: Fri Jun 07, 2013 9:59 pm
by Brendan
Hi,
BMW wrote:If I make a higher half kernel setup where the kernel is placed at 0xC0000000 (3GB) and is present in the address space of all processes, would the kernel have its own address space, or just use the top 1GB of all processes address spaces? Would I have a page directory which is just for the kernel?
The kernel would just use the top 1 GiB of all processes virtual address spaces; however, if you've got a reason to do it, there's no reason you can't have special virtual address space/s for the kernel alone. For example, (for a monolithic kernel) you might have a special virtual address space for the VFS so that the extra 3 GiB of space can be used to cache file data.
Note: I'm using "cached file data" as an example because it's the only thing I can think of that might need a lot of RAM.
The problem is that switching virtual address spaces is expensive - temporarily switching to a special purpose virtual address space and back (e.g. to access cached file data) would trash all of the process' TLB entries and cause a lot of TLB misses afterwards. It's best to avoid that. For example, VFS could use physical memory that isn't mapped into any virtual address space to cache file data (with meta-data in the kernel's 1 GiB of space so it can find which physical pages contain what) and temporarily "map then unmap" any cached file data it actually needs; and this would be faster (despite the extra overhead of temporarily mapping/unmapping) because the currently running process' TLB entries don't get trashed. It would also mean (if PAE is used) that the VFS could use more than 4 GiB of RAM to cache file data (it'd be faster and less limited than the "special virtual address space" method).
Cheers,
Brendan
Re: Kernel Address Space
Posted: Sat Jun 08, 2013 12:44 am
by BMW
Ok, thanks.
Editing Page Tables
Posted: Sat Jun 08, 2013 1:28 am
by BMW
Will I have to store the virtual addresses of my page tables in the page directory, so I can edit the page tables? Or is there some other, more memory efficient way?
Re: Editing Page Tables
Posted: Sat Jun 08, 2013 2:41 am
by Brendan
Hi,
BMW wrote:Will I have to store the virtual addresses of my page tables in the page directory, so I can edit the page tables? Or is there some other, more memory efficient way?
Page directories store the physical addresses of page tables, so storing the virtual addresses of page tables in the page directory doesn't make any sense.
To be able to access the data (page table entries) in a page table; you'd map the physical page used for the page table into the virtual address space.
There's a trick to doing this much more efficiently; where you pretend that the page directory is a page table (e.g. so that the highest page directory entry points to the physical address of the page directory). This creates a 4 MiB mapping of all the paging structures; but can make your head hurt, especially if you're still getting used to how paging works.
Cheers,
Brendan
Re: Kernel Address Space
Posted: Sat Jun 08, 2013 5:47 am
by linguofreak
Brendan wrote:The problem is that switching virtual address spaces is expensive - temporarily switching to a special purpose virtual address space and back (e.g. to access cached file data) would trash all of the process' TLB entries and cause a lot of TLB misses afterwards. It's best to avoid that.
It is good to note, however, that this doesn't apply to all architectures (though it does apply to those that are prominent today). Several historically significant architectures have used separate sets of translation structures for kernel and user mode, which allows a separate kernel address space without requiring a context switch on every syscall.
Re: Editing Page Tables
Posted: Sat Jun 08, 2013 12:58 pm
by BMW
Brendan wrote:Hi,
BMW wrote:Will I have to store the virtual addresses of my page tables in the page directory, so I can edit the page tables? Or is there some other, more memory efficient way?
Page directories store the physical addresses of page tables, so storing the virtual addresses of page tables in the page directory doesn't make any sense.
To be able to access the data (page table entries) in a page table; you'd map the physical page used for the page table into the virtual address space.
There's a trick to doing this much more efficiently; where you pretend that the page directory is a page table (e.g. so that the highest page directory entry points to the physical address of the page directory). This creates a 4 MiB mapping of all the paging structures; but can make your head hurt, especially if you're still getting used to how paging works.
Cheers,
Brendan
Ahh, I see. So if I wanted to edit a specific page table, I would use something like this to get the virtual address of it:
Code: Select all
(EndOfVirtualAddressSpace - 4MB) + (4096B * PageTableNumber)
Thanks to linguofreak for pointing out my mistake in using KB instead of B.
Re: Editing Page Tables
Posted: Sat Jun 08, 2013 1:21 pm
by halofreak1990
BMW wrote:
Ahh, I see. So if I wanted to edit a specific page table, I would use something like this to get the virtual address of it:
Code: Select all
(EndOfVirtualAddressSpace - 4MB) + (4096KB * PageTableNumber)
Yes, and within every 4KB of that range are the contents of a page table
Re: Editing Page Tables
Posted: Sun Jun 09, 2013 12:49 am
by linguofreak
BMW wrote:
Ahh, I see. So if I wanted to edit a specific page table, I would use something like this to get the virtual address of it:
Code: Select all
(EndOfVirtualAddressSpace - 4MB) + (4096KB * PageTableNumber)
Yes, except I think you meant either (4096B * PageTableNumber) or (4KB * PageTableNumber). 4096KB is 4MB.
Re: Kernel Address Space
Posted: Sat Aug 10, 2013 11:23 pm
by chickendinner
IMO the most sane option for the vast majority of use cases will be the page the kernel in at the top of memory.
You'd want this for portability reasons too. Since some other architectures, armv6 for example have MMU's where you can specify 2 page tables. One for a configurable top section of memory and another for the lower end (The top can be 2GB, 3GB, 3.5Gb .etc strangely the preferred 1GB isn't supported). So you can just change the page tables for the bottom section while the top area of memory remains static. Having a separate address space for the kernel would miss out on a primary architectural feature of the only other architecture most would consider porting to in the current market. And unless the architectures syscall interface can change the address space when it executes so the place it intends to jump to is paged in, you'd need some kind of privileged stub in every address space to switch the address space anyway.
A separate address space would have a benefit in maximizing the amount of memory each application can use on a 32bit x86 PAE system with more than 4GB of RAM (And there would only be a few special case niche reasons for doing so with the high cost of switching address spaces), but i certainly wouldn't develop a kernel with *design* decisions based on a feature of a 32bit system (supporting it is justifiable but designing for it is not imo). With 64bit systems i can't think of a single use for freeing up more address space anytime soon.