Page 1 of 1

Paging question

Posted: Wed Jul 04, 2007 4:15 am
by Jeko
I'm writing code for the handling of paging. But I don't know if it is better to map the kernel in each address space, or if it is better to do address space translation.
I think the first is faster, but what are the pros and cons of the two methods?

Posted: Wed Jul 04, 2007 9:32 am
by frank
kernel mapped into each address space:
Pros:
* Switches to the kernel are relatively quick and cheap.
* You can set the kernel pages to global and they won't be flushed from the tlb on a change of CR3

Cons:
* Device drives could potentially corrupt the kernel.

separate address space for the kernel:
Pros:
* If device drivers had their own address space then there is no chance that anything besides the kernel could corrupt the kernel.

Cons:
* Every switch to the kernel would need to change to the kernels address space, eg on every clock tick the address space would need to be changed. That results in needless tlb flushes and extra overhead.
* The kernel would have to do extra work in order to access the pages of the applications ie it would have to map the pages in to its address space in order to access them.

This is just some of the things I came up with in 5 minutes. I'm sure that there are many more.

Posted: Thu Jul 05, 2007 4:27 am
by Jeko
frank wrote:kernel mapped into each address space:
Pros:
* Switches to the kernel are relatively quick and cheap.
* You can set the kernel pages to global and they won't be flushed from the tlb on a change of CR3

Cons:
* Device drives could potentially corrupt the kernel.

separate address space for the kernel:
Pros:
* If device drivers had their own address space then there is no chance that anything besides the kernel could corrupt the kernel.

Cons:
* Every switch to the kernel would need to change to the kernels address space, eg on every clock tick the address space would need to be changed. That results in needless tlb flushes and extra overhead.
* The kernel would have to do extra work in order to access the pages of the applications ie it would have to map the pages in to its address space in order to access them.

This is just some of the things I came up with in 5 minutes. I'm sure that there are many more.
Thank you!
what method use windows and Linux (and other important OSes)?

Posted: Thu Jul 05, 2007 5:01 am
by Combuster
It's not the entire story. Keeping the kernel in a separate address space does not guarantee safety from broken drivers. Keeping the kernel in every address space does not make it inherently insecure from broken drivers.

The essential difference is that keeping the kernel in a different address space requires full context switches for all system calls, which is slow. The only advantage frank listed does not apply.
There is one other advantage: if you modify the kernel address space, you have to propagate the changes to all address spaces. This can easily be achieved by sharing page directories, and hence is not a big issue.
The net result is that virtually everybody maps the kernel into every address space. Linux and Windows are no different.

The more interesting question (which probably is what frank interpreted) is the choice between keeping drivers in the kernel (monolithic/modular kernel) or keeping the drivers in separate address spaces (microkernel). The advantage of the microkernel is that it isolates drivers from each other making the system more robust against broken drivers. The disadvantage is that you need to do context switches to execute driver code, which makes the system slower. Also, a microkernel can not prevent accidents arising from a broken DMA transfer - current hardware doesn't provide the required tools to fix that, although Brendan recently mentioned AMD having an IOMMU which is designed just for that.

In most cases, Windows and Linux do not have the drivers isolated. (Not so sure about Vista), but there are exceptions for both.

Posted: Thu Jul 05, 2007 5:25 am
by Jeko
Combuster wrote:It's not the entire story. Keeping the kernel in a separate address space does not guarantee safety from broken drivers. Keeping the kernel in every address space does not make it inherently insecure from broken drivers.

The essential difference is that keeping the kernel in a different address space requires full context switches for all system calls, which is slow. The only advantage frank listed does not apply.
There is one other advantage: if you modify the kernel address space, you have to propagate the changes to all address spaces. This can easily be achieved by sharing page directories, and hence is not a big issue.
The net result is that virtually everybody maps the kernel into every address space. Linux and Windows are no different.

The more interesting question (which probably is what frank interpreted) is the choice between keeping drivers in the kernel (monolithic/modular kernel) or keeping the drivers in separate address spaces (microkernel). The advantage of the microkernel is that it isolates drivers from each other making the system more robust against broken drivers. The disadvantage is that you need to do context switches to execute driver code, which makes the system slower. Also, a microkernel can not prevent accidents arising from a broken DMA transfer - current hardware doesn't provide the required tools to fix that, although Brendan recently mentioned AMD having an IOMMU which is designed just for that.

In most cases, Windows and Linux do not have the drivers isolated. (Not so sure about Vista), but there are exceptions for both.
Thank you, I think I'll map the kernel in each address space, because I want to develop a fast OS.
Another question:
if the kernel's heap grows bigger, I must update every address space?
my kernel's heap starts from 0xC0000000, because it is a higher-half kernel.
And:
How can I use shared directories?

Posted: Thu Jul 05, 2007 5:25 am
by Jeko
Combuster wrote:It's not the entire story. Keeping the kernel in a separate address space does not guarantee safety from broken drivers. Keeping the kernel in every address space does not make it inherently insecure from broken drivers.

The essential difference is that keeping the kernel in a different address space requires full context switches for all system calls, which is slow. The only advantage frank listed does not apply.
There is one other advantage: if you modify the kernel address space, you have to propagate the changes to all address spaces. This can easily be achieved by sharing page directories, and hence is not a big issue.
The net result is that virtually everybody maps the kernel into every address space. Linux and Windows are no different.

The more interesting question (which probably is what frank interpreted) is the choice between keeping drivers in the kernel (monolithic/modular kernel) or keeping the drivers in separate address spaces (microkernel). The advantage of the microkernel is that it isolates drivers from each other making the system more robust against broken drivers. The disadvantage is that you need to do context switches to execute driver code, which makes the system slower. Also, a microkernel can not prevent accidents arising from a broken DMA transfer - current hardware doesn't provide the required tools to fix that, although Brendan recently mentioned AMD having an IOMMU which is designed just for that.

In most cases, Windows and Linux do not have the drivers isolated. (Not so sure about Vista), but there are exceptions for both.
Thank you, I think I'll map the kernel in each address space, because I want to develop a fast OS.
Another question:
if the kernel's heap grows bigger, I must update every address space?
my kernel's heap starts from 0xC0000000, because it is a higher-half kernel.
And:
How can I use shared directories?
As you can see, I'm very confused!

sorry for the double post!

Posted: Thu Jul 05, 2007 5:39 am
by Combuster
MarkOS wrote:How can I use shared directories?
The idea is that part of the paging structures are shared at one place. In your case, you would create page tables for 0xC0000000-0xFFFFFFFF and then write this set of page tables to ALL page directories you create. The result is that you only have to load the necessary values once: when you create a page directory. If you change any of the page tables representing the kernel the changes will be propagated to all address spaces since all of the page directories map to the same set of page tables.

P.S. you can delete your (double) posts if there have not been any replies yet

Posted: Thu Jul 05, 2007 5:46 am
by Jeko
Combuster wrote:
MarkOS wrote:How can I use shared directories?
The idea is that part of the paging structures are shared at one place. In your case, you would create page tables for 0xC0000000-0xFFFFFFFF and then write this set of page tables to ALL page directories you create. The result is that you only have to load the necessary values once: when you create a page directory. If you change any of the page tables representing the kernel the changes will be propagated to all address spaces since all of the page directories map to the same set of page tables.

P.S. you can delete your (double) posts if there have not been any replies yet
ok thank you. Now I've understood everything.