4.3 User Space and Kernel Space
Jumping the Fence
Caveat emptor: The notion that code in user space and code in kernel space
execute independently in their little confined regions of memory is somewhat
incorrect. Sure, the kernel's address space is protected, such that an applica¬
tion thread has to pass through the system call gate to access kernel space, but
a thread may start executing in user space then jump to kernel space, via the
SYSENTER instruction (or INT 0x2E), and then transition back to user mode. It's
the same execution path for the entire trip; it has simply acquired entry rights
to the kernel space by executing special system-level machine instructions. A
more realistic way to view the execution context of a machine is to envision a
set of threads soaring through memory, making frequent transitions between
user space and kernel space (see Figure 4.5),
Figure 4.5
By the way, these special instructions (e.g., SYSENTER, INT 0x2E) and the sys¬
tem-level registers and data structures that they use to function are normally
set up by the kernel during system startup. This prevents a user application
from arbitrarily jumping into kernel space and executing privileged code on a
whim. As in any household, it's always a good idea for the adults to estab¬
lish the rules that the children must follow (otherwise, everyone would have
desert first at dinner and no one would eat their vegetables).
User-Space Topography
One way to get an idea of how components are arranged in user space is
to use the !peb kernel debugger extension command. We start by using the
! process extension command to find the linear address of the corresponding
Parti I 133