getting into paging

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
GLneo
Member
Member
Posts: 237
Joined: Wed Dec 20, 2006 7:56 pm

getting into paging

Post by GLneo »

hi all, ok, with the kernel in paging the kernel needs to be linked to 0xC0000000, but if i do that i'll need to set up paging in the boot loader, does anyone have examples of how to do this?

thx
Otter
Member
Member
Posts: 75
Joined: Sun Dec 31, 2006 11:56 am
Location: Germany

Post by Otter »

You need to decide how you use your physical and your virtual space. That of cause does not only mean that you know where to map your kernel. You also have to think about the following:
- Where to load the kernel physically ?
- Where to put the page directory physically ?
- Where to put the page tables you need for the beginning ?
- Where to map the page directories and the page tables ( this not necessary for the moment but one day you have to, at least when you try to code a vmm for your kernel )
- Where to map the stack ?
- Maybe map everthing before 1 MB to the same virtual adresses so you can easily access things like 0x000B8000 for text output.

In the boot loader, paging is not active yet so you can use the (physical) memory like you want. Now, you should set everything in your page directory to zero. Depending on your decisions above you should know which page tables you need ( example: If everything in virtual memory is in the lower 4 MB, you only need page table #0. But you seem to map your kernel to 0xC0000000 so you need page table #0x300 too ). So let's say you want these two page tables.

Now, you have to register this two page tables by filling the correct dwords of the page directory ( first dword for page table #0 and 0x300th dword for page table #0x300). For the moment, you could use the physical address of the page table ( which has to to be aligned to a page, that means the last three digits in hexadecimal notation should be zero ) | 3.

Then, you have to register all pages you want. So lets say you want all below 4 MB so need to set up every dword of page table #0. The first has to be 0x00000003, the second 0x00001003, the third 0x00002003 and so on ( the last one 0x003FF003 of course ). Then, you should map your kernel to virtual space. I think your kernel size is less 4 kb so one page should be enough, you only need to set up the first dword of page table #0x00300.

Repeat this for all pages you want to map, like stack, pagedirectory and so on.

After all you have to set cr3 to the physical address of your page directory and to set bit 31 of cr0.
GLneo
Member
Member
Posts: 237
Joined: Wed Dec 20, 2006 7:56 pm

Post by GLneo »

ok, i've desided to have a section (.setup) mapped to 0x00100000, which sets up paging and jumps to the kernel (.kernel) at 0xC0000000, this doesn't work and i think it is this file:
http://lemonos.cvs.sourceforge.net/lemo ... iew=markup ( this runs at 0x00100000 and sets up paging), what i am trying to do is map the first 4MB's to 0x00000000 and 0xC0000000

Am i doing it correctly?

Thx
Otter
Member
Member
Posts: 75
Joined: Sun Dec 31, 2006 11:56 am
Location: Germany

Post by Otter »

Why do you use "+0x40100000" ? If you have set up a flat environment you should not add this offset.
User avatar
xyjamepa
Member
Member
Posts: 397
Joined: Fri Sep 29, 2006 8:59 am

Post by xyjamepa »

deadmopo3
Posts: 4
Joined: Sat Feb 17, 2007 5:40 pm

Post by deadmopo3 »

Sorry for the offtopic:

Is linking and mapping kernel to 0xC0000000 required for paging implementation or is it possible to work with kernel staying at 0x0001000?
Will it bring much difficulties later?
GLneo
Member
Member
Posts: 237
Joined: Wed Dec 20, 2006 7:56 pm

Post by GLneo »

[EDIT: sorry, i thought he was asking something else] :oops:
Last edited by GLneo on Tue Feb 20, 2007 9:31 am, edited 1 time in total.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
deadmopo3 wrote:Is linking and mapping kernel to 0xC0000000 required for paging implementation or is it possible to work with kernel staying at 0x0001000?
Will it bring much difficulties later?
It's possible to have the kernel linked and mapped at 0x0001000, with user-space going from 0x40000000 to 0xFFFFFFFF. This (by itself) won't really cause any difficulties later. The reason most people put the kernel at the end of the address space is because most people want to have applications at the start of the address space.

Putting the kernel at the end of the address space also makes more sense if you're planning to write a 64-bit version of your kernel that is capable of running the original 32-bit applications. In this case, if applications are at the start of the address space then the 32-bit applications could use from 0x00000000 to 0xFFFFFFFF when running on the 64-bit kernel (instead of still using from 0x40000000 to 0xFFFFFFFF and not being able to easily use the extra 1 GB).

Of course there's a seperate issue here - whether or not the kernel uses dynamically allocated pages. There's good reasons for using dynamically allocated pages for the kernel (regardless of where it's mapped), but some people just want to enable paging and protected mode as soon as possible so they can go "Woot" now and "Doh" later (Linus included).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
deadmopo3
Posts: 4
Joined: Sat Feb 17, 2007 5:40 pm

Post by deadmopo3 »

such a great forum where everyone tries to answers questions )
I really respect everyone here.
It's possible to have the kernel linked and mapped at 0x0001000, with user-space going from 0x40000000 to 0xFFFFFFFF. This (by itself) won't really cause any difficulties later. The reason most people put the kernel at the end of the address space is because most people want to have applications at the start of the address space.
why 0x40000000? why not 0x10000000?[/code][/quote]
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
deadmopo3 wrote:
It's possible to have the kernel linked and mapped at 0x0001000, with user-space going from 0x40000000 to 0xFFFFFFFF. This (by itself) won't really cause any difficulties later. The reason most people put the kernel at the end of the address space is because most people want to have applications at the start of the address space.
why 0x40000000? why not 0x10000000?
Applications could use from 0x10000000 to 0xFFFFFFFF.

The problem is that it's annoying if you ever want to support PAE (which is the easiest way to support 32-bit systems with more than 4 GB of RAM IMHO). The reason for this is that with PAE there's 4 page directories for each address space and each page directory covers 1 GB. If the kernel consumes one page directory, then you can just put that page directory into every address space (rather than putting N page tables in the first page directory of every address space and having problems when you add an new page table in kernel space).

I guess that's the general problem with having the kernel at the start of the address space (e.g. at 0x00001000). It's easy to adjust the upper address used by applications as this is usually dynamically allocated space (just make "malloc()" use a "highest usable address" value returned by the kernel), but it's hard to adjust the lower address used by applications as this is usually where the code is (it means recompiling/relinking the application to suit).

In my case, I'm using 32-bit processes with 3 different kernels - one for 32-bit plain paging, one for 32-bit with PAE paging and another 64-bit kernel. In this case the same 32-bit binary could use from 0x00000000 to 0xD0000000, from 0x00000000 to 0xC0000000 or from 0x00000000 to 0xFFFFFFFF (depending on which kernel is being used).

The other thing is that 128 MB isn't very much space. It would be good to decide exactly what needs to go in kernel space and then determine the maximum limits your kernel could support based on how much space there is.

For example, my last kernel used 4 KB per process, 8 KB per thread and used message queues (I allowed another 8 KB per thread for message queues). If you assume each process will have an average of 3 threads, then it works out to 52 KB per process on average. This is a maximum of about 20000 processes for 1 GB of kernel space, or 2500 processes for 128 MB of kernel space. Of course don't forget we're talking about space here, not RAM...

For monolithic kernels things can turn ugly fast - imagine a server with 8 CPUs, 16 GB of RAM, 600 GB of hard drive space and 32 MB of file system cache... ;)


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply