In x86 protected mode, the CPU is always in one of 4 rings. The Linux kernel only uses 0 and 3:
- 0 for kernel
- 3 for users
This is the most hard and fast definition of kernel vs userland.
Why Linux does not use rings 1 and 2?
The intent by Intel in having rings 1 and 2 is for the OS to put device drivers at that level, so they are privileged, but somewhat separated from the rest of the kernel code.
Rings 1 and 2 are in a way, “mostly” privileged. They can access supervisor pages, but if they attempt to use a privileged instruction, they still GPF like ring 3 would. So it is not a bad place for drivers as Intel planned.
What can each ring do?
- ring 0 can do anything
- ring 3 cannot run several instructions and write to several registers, most notably:
- cannot change its own ring!
- cannot modify the page tables.
- cannot register interrupt handlers.
- cannot do IO instructions like
out, and thus have arbitrary hardware accesses.
What is the point of having multiple rings?
There are two major advantages of separating kernel and userland:
- it is easier to make programs as you are more certain one won’t interfere with the other. E.g., one userland process does not have to worry about overwriting the memory of another program because of paging, nor about putting hardware in an invalid state for another process.
- it is more secure. E.g. file permissions and memory separation could prevent a hacking app from reading your bank data. This supposes, of course, that you trust the kernel.