I read that there are two modes called “kernel mode” and “user mode” to handle execution of processes. (Understanding the Linux Kernel, 3rd Edition.) Is that a hardware switch (kernel/user) that is controlled by Linux, or software feature provided by the Linux kernel?
Kernel mode and user mode are a hardware feature, specifically a feature of the processor. Processors designed for mid-to-high-end systems (PC, feature phone, smartphone, all but the simplest network appliances, …) include this feature. Kernel mode can go by different names: supervisor mode, privileged mode, etc. On x86 (the processor type in PCs), it is called “ring 0”, and user mode is called “ring 3”.
The processor has a bit of storage in a register that indicates whether it is in kernel mode or user mode. (This can be more than one bit on processors that have more than two such modes.) Some operations can only be carried out while in kernel mode, in particular changing the virtual memory configuration by modifying the registers that control the MMU. Furthermore, there are only very few ways to switch from user mode to kernel mode, and they all require jumping to addresses controlled by the kernel code. This allows the code running in kernel mode to control the memory that code running in user mode can access.
Unix-like operating systems (and most other operating systems with process isolation) are divided in two parts:
- The kernel runs in kernel mode. The kernel can do everything.
- Processes run in user mode. Processes can't access hardware and can't access the memory of other processes (except as explicitly shared).
The operating system thus leverages the hardware features (privileged mode, MMU) to enforce isolation between processes.
Microkernel-based operating systems have a finer-grained architecture, with less code running in kernel mode.
When user mode code needs to perform actions that it can't do directly (such as access a file, access a peripheral, communicate with another process, …), it makes a system call: a jump into a predefined place in kernel code.
When a hardware peripheral needs to request attention from the CPU, it switches the CPU to kernel mode and jumps to a predefined place in kernel code. This is called an interrupt.
"Linux" proper is only the kernel. When we talk about "Linux" as an operating system, it is a conflation of the kernel and all of the other software that is distributed with it in a Linux distribution.
The switch between user and kernel mode happens when you make a system call, which is any of the functions documented in manual section 2. That is, if you say something like
man 2 open and get a result, or
man creat and see that there is a
(2) suffix on the page title, you're looking at a system call, which means it's handled by the kernel.
When the system call returns to the user code that called it, it returns that process to user mode.
The Linux kernel uses hardware features to enforce the distinction between kernel and user mode on most processors that it runs on. The Intel protection ring scheme is one way to do this. There are exceptions, such as µCLinux, which runs on small processors without an MMU, which may also lack protection rings. Very old versions of Unix also ran without kernel/user protection.
When we talk about "user mode code," we are talking about code that mostly runs in user space, though pretty much any program is going to contain some system calls, and so will spend some of its time waiting on the kernel, which always runs in kernel mode.