Hi all,
After reading through all the example kernels and tutorials on osdev's site, viewing lots of other peoples source and comparing to my own past choices I have realized that most kernels identity map most of the ram below 1mb if not all. Thinking about it more carefully though is this such a good idea? I am thinking that perhaps it is best to purposefully leave the first page between 0x0 and 0x1000 unmapped so that any access causes a protection fault namely to catch out bad coding, bugs and especially null pointers in the kernel and its modules. Has anyone else done this and would it be a good idea? I realise this won't catch out many other errors and bugs but imho its a good start. please note I am referring here to code executing in ring 0, not userspace apps. Thoughts?
Thanks everyone!
First page of ram always unmapped?
- gravaera
- Member
- Posts: 737
- Joined: Tue Jun 02, 2009 4:35 pm
- Location: Supporting the cause: Use \tabs to indent code. NOT \x20 spaces.
Re: First page of ram always unmapped?
Hey:
A way to access lowmem is to ID map it into the kernel's page directory. You do need to access it, and this is a very easy and functional way to do so. However, if drivers, the kernel, or something else needs to access lowmem later on when you are running user processes, the identify mapping will not be available since you won't be working from the kerne's page directory; you'll be working from within the page dir of the currently running process. The other disadvantage of this approach is that you also don't have PFN 0 unmapped, so you can't catch null pointer dereferences during the kernel boot-up.
A better way to get access to lowmem is to leave a statically allocated, 1MB large gap between the kernel's virtual start address and the kernel image as mapped in vmem. So if the kernel is at 0xC0100000, you have lowmem mapped at 0xC0000000. This enables you to use lowmem at will. This method addresses both problems associated with the first method, and is completely workable.
An even better way to get access to lowmem is to write a proper VMM so that you don't need to make explicit allowance to accessing lowmem, and you can just demand map it later on in the boot and leave it there, or unmap it and reclaim the vmem as needed. So if your kernel image is at 0xC0000000, that's where it is, and later on you just dynamically allocate any random stretch of 1MB of vmem and map it to 0x0, and reclaim it wholly or in part. Naturally you don't need to map all 1MB of lowmem either and you can map whatever portions you need at the moment. That said most people opt for the second method.
--Peace out
gravaera
A way to access lowmem is to ID map it into the kernel's page directory. You do need to access it, and this is a very easy and functional way to do so. However, if drivers, the kernel, or something else needs to access lowmem later on when you are running user processes, the identify mapping will not be available since you won't be working from the kerne's page directory; you'll be working from within the page dir of the currently running process. The other disadvantage of this approach is that you also don't have PFN 0 unmapped, so you can't catch null pointer dereferences during the kernel boot-up.
A better way to get access to lowmem is to leave a statically allocated, 1MB large gap between the kernel's virtual start address and the kernel image as mapped in vmem. So if the kernel is at 0xC0100000, you have lowmem mapped at 0xC0000000. This enables you to use lowmem at will. This method addresses both problems associated with the first method, and is completely workable.
An even better way to get access to lowmem is to write a proper VMM so that you don't need to make explicit allowance to accessing lowmem, and you can just demand map it later on in the boot and leave it there, or unmap it and reclaim the vmem as needed. So if your kernel image is at 0xC0000000, that's where it is, and later on you just dynamically allocate any random stretch of 1MB of vmem and map it to 0x0, and reclaim it wholly or in part. Naturally you don't need to map all 1MB of lowmem either and you can map whatever portions you need at the moment. That said most people opt for the second method.
--Peace out
gravaera
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.
-
- Member
- Posts: 141
- Joined: Thu Jun 17, 2010 2:36 am
Re: First page of ram always unmapped?
Having virtual address 0x0 being mapped\present is a terrible idea IMO. This makes NULL pointers valid (assuming NULL = 0 in your kernel) which will cause numerous headaches, even for non buggy code. It also means that the real mode IDT is easily overwritten, which you never want to do. The only thing of any use in the the 0x0 -> 0x1000 region is the BDA, which in my kernel I just physically copy to a statically allocated buffer, then unmap the page (I boot in long mode, so paging has to be enabled). This guarantees that not only will I never end up with a virtual address in the lowest page frame, but I'll also never have a physical one either.
Re: First page of ram always unmapped?
I have first 4MiB unaccessible to ring3, so things like this can be detected:
The 4MiB is used to store process specific information accessible only in ring0. And yes, the very first 4KiB is unmapped.
Code: Select all
int * foo = NULL;
int bar = foo[16384];
Re: First page of ram always unmapped?
Identity mapping is used only during initial phases of initialisation while exception handling is not activated so you can't catch "null pointers" anyway. Moreover the first physical page can hold useful data for your kernel. After enabling paging I free and unmap base memory reserving its pages for driver needs (exept first page). The first transpage (4 kb page table) is unmapped too and its entry is not more used so the first 4 mb region is not used for mapping in any virtual address space.
If you have seen bad English in my words, tell me what's wrong, please.