Page 1 of 1
paging kernel and user address spaces
Posted: Mon Nov 19, 2007 1:13 pm
by sigler
Hello,
I'm trying for my user programs running in ring3 to have their own address space. So I set up a different page directory for the user app, and in my timer interrupt, when switching to this task I set cr3 to point to the page directory of the task. So far I haven't gotten it to work, but for now my question is this:
How can this work? After I've set cr3, doesn't it take effect immediately? and I still need to access the kernel stack, perform iret etc. but I don't want the kernel stack to be available to the user program, so the kernel stack isn't in the page directory that I've just set.
what am I missing ?
thanks,
--
Sigurd Lerstad
Posted: Mon Nov 19, 2007 1:23 pm
by JAAman
After I've set cr3, doesn't it take effect immediately?
yes it does
and I still need to access the kernel stack, perform iret etc.
yes you do...
but I don't want the kernel stack to be available to the user program,
of course not, thats why its in ring0 not ring3...
so the kernel stack isn't in the page directory that I've just set.
thats your mistake
the way it normally works is, the page directory is divided into 2 parts (i use a 50/50 split: 2GB for each), and one (usually the higher portion) is given to the kernel, so that it is mapped identically into every page directory, the other portion is then given to the user application
the kernel stack will never be available to the user application, because its located in ring0, with the supervisor-only permissions selected in the page tables
suggested reading: 3A:4.11 (and really the entirety of chapter 4)
Posted: Mon Nov 19, 2007 2:09 pm
by sigler
JAAman wrote:
the way it normally works is, the page directory is divided into 2 parts (i use a 50/50 split: 2GB for each), and one (usually the higher portion) is given to the kernel, so that it is mapped identically into every page directory, the other portion is then given to the user application
the kernel stack will never be available to the user application, because its located in ring0, with the supervisor-only permissions selected in the page tables
suggested reading: 3A:4.11 (and really the entirety of chapter 4)
What's the best way to give the kernel the upper half, it's physically in a low address, loaded by the bootloader. If I map it logically to other addresses, memory references in the kernel will start to malfunction.
Should I have a kernel that has been compiled to have it's image-base in upper-half memory? in the boot loader, load that kernel in physical ram, have a page_directory that maps that physical ram to upper half. Set cr3, then call the first instruction of the upper-half kernel?
thanks,
--
Sigurd Lerstad
Posted: Mon Nov 19, 2007 3:31 pm
by JAAman
its really quite simple:
1) link it to run at the higher location
2) load it into memory
3) use paging to map it to both the upper and lower portion
4) activate paging, while still in ASM code, jump to the higher portion
using this method is very simple, but requires that you enable paging from ASM code, at the very start -- but you must be sure to not reference any code or data since the linker will link it to the wrong address before paging is enabled -- this is a very simple step, and should be easy to implement with only a few lines of location-independent ASM code
there is another method, called 'the GDT trick' -- but its actually harder both to use and to understand
alternatively, you can enable paging in another section of code (in your second-stage loader for instance...), which is identity mapped, and simply removed from memory once your main code is running
Posted: Mon Nov 19, 2007 4:17 pm
by egos
What's the best way to give the kernel the upper half, it's physically in a low address, loaded by the bootloader. If I map it logically to other addresses, memory references in the kernel will start to malfunction.
If you don't need the low memory, you can map it to high addresses, otherwise allocate the memory and move the kernel to it.
Should I have a kernel that has been compiled to have it's image-base in upper-half memory? in the boot loader, load that kernel in physical ram, have a page_directory that maps that physical ram to upper half. Set cr3, then call the first instruction of the upper-half kernel?
You must have the kernel, which contains two parts. One has been compiled to have it's base in low addresses, another in high addresses. Set up cr3 before you pass control to the upper-half kernel.
Posted: Mon Nov 19, 2007 4:46 pm
by JAAman
you must have the kernel, which contains two parts. One has been compiled to have it's base in low addresses, another in high addresses. Set up cr3 before you pass control to the upper-half kernel.
its not actually necessary to compile it for the lower portion, if your careful
Posted: Mon Nov 19, 2007 5:19 pm
by egos
JAAman wrote:its not actually necessary to compile it for the lower portion, if your careful
Yes it is. The code usually is position-independent. But the data is not like this.
Posted: Mon Nov 19, 2007 5:21 pm
by JAAman
that is only true if you reference data by absolute references -- ie you allow the linker to resolve names into addresses -- if you dont do that, then its not necessary