How Linux Init Switches from Kernel to User Mode: Inside kernel_execve
This article explains how the Linux init process (pid 1) transitions from kernel mode to user mode using kernel_execve and the int 0x80 system call, detailing the register changes, assembly flow, and verification experiment that reveal the privilege level switch.
In Linux, the
initprocess (pid = 1) is the first user‑space program created by the kernel after the idle process (pid = 0). It is spawned by
kernel_threadin kernel mode and then execs
/sbin/initin user space.
The kernel can launch user‑space programs from kernel space via two mechanisms:
1. call_usermodehelper 2. kernel_execve
Both ultimately invoke a software interrupt
int $0x80, which triggers the
sys_execvesystem call. The article investigates whether the program executed by this system call runs in kernel mode or user mode, and how the CPU’s
CSregister changes from
__KERNEL_CSto
__USER_CS.
During boot,
start_kernelcalls
rest_init, which creates a kernel thread that runs
kernel_init.
kernel_initeventually calls
run_init_process, whose core operation is
kernel_execve:
The implementation contains inline assembly; the essential instruction is
int $0x80, which places the syscall number
__NR_execvein
AXand the program path in
BX.
The interrupt transfers control to the
system_callassembly routine:
system_callsaves registers, builds a
struct pt_regsstack frame, and finally calls the C function
sys_execvevia the system‑call table:
sys_execve(shown below) delegates to
do_execve, which calls
do_execve_commonto load the ELF binary, locate its entry point, and set up a new user‑space stack.
The ELF loader eventually calls
start_thread, which modifies
regs->csto
__USER_CS(0x33 on x86‑64) and
regs->ipto the program’s entry address:
When the interrupt returns via
iret, the CPU pops the saved
CSand
IPfrom the stack, now containing
__USER_CSand the ELF entry point, so execution resumes in user mode.
To verify this, the author used
call_usermodehelperto run a small program that prints the
CSregister. After inserting a USB drive, the syslog showed:
Mar 10 14:20:23 build-server main: ucs = 0x33
Thus the first kernel process (pid = 1) indeed switches to user mode by changing
CSfrom
__KERNEL_CSto
__USER_CSduring the
iretreturn.
Efficient Ops
This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.