The kernel is a specific part of operating systems that interact with hardware and run on the CPU’s kernel privilege mode. This only allows trusted software to interact with hardware, i.e., some programs can’t execute certain instructions when not in kernel mode.
There are two main kernel architectures:
- A monolithic kernel runs most/all OS services in kernel mode. This includes virtual memory management, process scheduling, IPC, the filesystem, and device drivers.
- Microkernels try to run the minimum possible amount of services in kernel mode. For instance, virtual memory, process scheduling, and basic IPC should be done in the kernel, but the filesystem, drivers, and more advanced IPC should/can be done in user mode.
- Nanokernels and picokernels aim to move more services into user mode than traditional microkernels. This is an active topic of research.
- Hybrid kernels are somewhere in between both.
Kernel-mode software
A kernel is a long-running process, and writing kernel code is like writing library code (there’s no main function). The kernel lets us load code called modules that is executed on-demand, i.e., when it’s loaded manually, or when there’s new hardware, or accessing a particular file. Since kernels operate on a higher privilege level, this also means kernel code can execute a wide range of powerful instructions.
All code running in kernel mode shares a single virtual address space. KMDs aren’t isolated from other drivers or the OS. If a KMD mistakenly writes to the wrong virtual address, it could compromise data belonging to the OS or another driver. And if a KMD crashes, the entire OS crashes.
Note that not all memory in kernel-mode can be swapped out. There are two regions for dynamically allocated memory:
- The paged pool can be swapped out to a disk file.
- The non-paged pool can never be paged out to a disk file.