Question

I'm reading through Mickens' OS notes, and I came across the following depiction of a virtual address space. enter image description here

I conceptually understand "user mode" of a process' virtual address space. It contains program instructions, stack, heap, static data, etc.

But what about 'kernel mode'? I always thought of kernel instructions as elsewhere... I thought of kernel as a separate process. And when a system call happens that kernel process gets loaded and a handler gets executed.

  • Is this incorrect? Part of the kernel is co-located with the process? Which part?
Was it helpful?

Solution

And when a system call happens that kernel process gets loaded and a handler gets executed.

This would be extremely slow as a process context switch would be required to make a kernel call and another one when the kernel call returns. Please consider that even a simple operation like printing "Hello World" to the screen using printf() in C requires at least one (quite often more than one) kernel call.

To speed things up, the kernel is mapped into the virtual address space of every process. A kernel call is basically just a jump to a function in the kernel address space, which is almost as fast as calling a normal function in your code; this way no context switch is required at all.

It is a bit slower as a normal function call because the kernel code runs on a different privilege level than the user space code and when calling a kernel function a privilege level increase has to take place (hence the function is called using the SYSCALL instructions instead of the CALL instruction on x86 CPUs). Alternatively a software interrupt can be used for that purpose but interrupt handling is much slower, so modern systems don't use interrupts anymore for this purpose unless the CPU has nothing else available. Please see typical implementations on system call for details.

So the kernel is similar to a dynamic shared library that is implicitly loaded for all applications and available in address space, with the exception, that it has a global state across all applications. The downside is that less virtual address space is available for user space processes. This is one reason why 64 bit CPUs make sense as with 64 bit pointers, the virtual address space is enormous and losing a bit for the kernel is totally irrelevant in that case.

Another advantage is that the kernel can also easily access the memory of user space code that made the call as that memory is within the same virtual address space of the code that handles the system call. When you perform a kernel call that requires the kernel to access user space memory, this memory doesn't have to be copied between processes or use some implicit shared memory mechanism, instead the call just passes a pointer along and the kernel directly reads the data from the address the pointer references.

Licensed under: CC-BY-SA with attribution
scroll top