Higher half kernels
Higher half kernels
What is the point of a higher half kernel?
Because each process has its own virtual address space, so why not just put the kernel at 0x00 in its own address space????
It shouldn't matter where it is within its VAS, user space programs have their own VAS.
Because each process has its own virtual address space, so why not just put the kernel at 0x00 in its own address space????
It shouldn't matter where it is within its VAS, user space programs have their own VAS.
Currently developing Lithium OS (LiOS).
Recursive paging saves lives.
"I want to change the world, but they won't give me the source code."
Recursive paging saves lives.
"I want to change the world, but they won't give me the source code."
- 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: Higher half kernels
Yo:
The biggest reason is avoiding address space switches, and the TLB cooling that comes with switching address spaces constantly. If you map the kernel into every address space, then a syscall can be theoretically executed entirely within the calling process's address space. When you keep the kernel in its own address space, you every syscall requires you to do two address space switches -- one into the kernel's address space, and one back out into the userspace process' address space.
--Peace out,
gravaera
The biggest reason is avoiding address space switches, and the TLB cooling that comes with switching address spaces constantly. If you map the kernel into every address space, then a syscall can be theoretically executed entirely within the calling process's address space. When you keep the kernel in its own address space, you every syscall requires you to do two address space switches -- one into the kernel's address space, and one back out into the userspace process' address space.
--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: 595
- Joined: Mon Jul 05, 2010 4:15 pm
Re: Higher half kernels
One benefit of having the kernel at high address is that you have the possibility to move the kernel without affecting the program and that way adjust how much each process has. An example of this is the 3GB switch in Windows that moves the kernel one gigabyte up in order to give the processes more virtual memory.
It's simply easier to move the kernel than the programs. Think about x86-64 where you have a "hole" in the middle of the virtual address space. Let's say they would decide to make this hole smaller one day. Then you don't need to modify your program that starts a 0 but, if the program would be on high address it would require a recompilation in order to take advantage of the larger virtual address space. Possible with relocation though but if you can avoid it......
It's simply easier to move the kernel than the programs. Think about x86-64 where you have a "hole" in the middle of the virtual address space. Let's say they would decide to make this hole smaller one day. Then you don't need to modify your program that starts a 0 but, if the program would be on high address it would require a recompilation in order to take advantage of the larger virtual address space. Possible with relocation though but if you can avoid it......
Re: Higher half kernels
Personally, I can't see any valid reason why to place a program at address 0. Executable formats for 32 and 64 bits all have relocation information, and are usually not bound to a specific address, and at least not to 0. The reason why a user program should not execute at address 0 is that this is the address of null-pointers, which should be caught as invalid. The larger invalid space at the beginning, the lower risk of null pointers, or random integers casted to pointers, will be valid.
The same applies to kernels. They should not be a address 0, nor at the top of linear address space (since this allows negative integers to be casted to valid pointers in the kernel).
The same applies to kernels. They should not be a address 0, nor at the top of linear address space (since this allows negative integers to be casted to valid pointers in the kernel).
Re: Higher half kernels
The more relocation information you have to process for a given program, the longer it takes to load and start. Compare:rdos wrote:Executable formats for 32 and 64 bits all have relocation information,
- load program and jump to it
vs.
- load program
- process relocations for each executable section, process PLT entries
- process relocations for each data section, process GOT relocations
- jump to it
Process of relocation is usually linear with the size of program (has to patch every address) and touches a lot of memory pages (usually the entire executable space of the program), thus trashing the caches and being even less effective (vs. not doing that).
Learn to read.
Re: Higher half kernels
Agree. For this reason I set the first 4KB as absent, and map the first following few MB as kernel-access only (for process specific information block), and the application starts at 16MB.rdos wrote:The reason why a user program should not execute at address 0 is that this is the address of null-pointers, which should be caught as invalid. The larger invalid space at the beginning, the lower risk of null pointers, or random integers casted to pointers, will be valid.
Re: Higher half kernels
However consider a typical scenario that an application consist of a base executable and a dozen of shared libraries.dozniak wrote:The more relocation information you have to process for a given program, the longer it takes to load and start.
The added time might not be as worst as you expect since all shared libraries require relocation on both cases.
Furthermore if you are doing address space randomization, you need to do relocations anyway.
Re: Higher half kernels
If you use own libraries you can set different predefined base addresses for them to prevent its overlapping. Besides, in many projects the size of base executable module is larger than the size of all used shared libraries.
If you have seen bad English in my words, tell me what's wrong, please.
Re: Higher half kernels
First, you can do demand-loading and relocation at the same time. Second, you can bind the executable at a non-zero address, and avoid relocation that way. In x86-64, I let the linker locate the executable far above 4G, and then I mark the entire first 4G as kernel-only.dozniak wrote:The more relocation information you have to process for a given program, the longer it takes to load and start. Compare:rdos wrote:Executable formats for 32 and 64 bits all have relocation information,
- load program and jump to it
vs.
- load program
- process relocations for each executable section, process PLT entries
- process relocations for each data section, process GOT relocations
- jump to it
Process of relocation is usually linear with the size of program (has to patch every address) and touches a lot of memory pages (usually the entire executable space of the program), thus trashing the caches and being even less effective (vs. not doing that).
Re: Higher half kernels
Let's check a few application on linux:egos wrote:If you use own libraries you can set different predefined base addresses for them to prevent its overlapping. Besides, in many projects the size of base executable module is larger than the size of all used shared libraries.
Code: Select all
$ ldd /bin/ls
linux-vdso.so.1 => (0x00007fff77dff000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f3979a6c000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f3979864000)
libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007f397965b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f397929c000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f3979098000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3979ca2000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f3978e7a000)
libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007f3978c75000)
$ ldd /bin/sh
linux-vdso.so.1 => (0x00007fff5bfff000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f633e3ac000)
/lib64/ld-linux-x86-64.so.2 (0x00007f633e782000)
$ ldd /bin/nano
linux-vdso.so.1 => (0x00007fff62ba2000)
libncursesw.so.5 => /lib/x86_64-linux-gnu/libncursesw.so.5 (0x00007f34d286f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f34d24b0000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f34d22ab000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f34d2084000)
/lib64/ld-linux-x86-64.so.2 (0x00007f34d2ab3000)
Now, if you count the relocations entries, you may note that:
1. for normal application, you only need to do relocation for global objects (GOT). The PLT entry only exist if you has exported function on the base executable. The work for relocation is insignificant and however not related to the code size.
2. On the contrast, every shared libraries has tons of relocation.
You got my point.