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 init process (pid = 1) is the first user‑space program created by the kernel after the idle process (pid = 0). It is spawned by kernel_thread in kernel mode and then execs /sbin/init in 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_execve system call. The article investigates whether the program executed by this system call runs in kernel mode or user mode, and how the CPU’s CS register changes from __KERNEL_CS to __USER_CS.
During boot, start_kernel calls rest_init, which creates a kernel thread that runs kernel_init. kernel_init eventually 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_execve in AX and the program path in BX.
The interrupt transfers control to the system_call assembly routine:
system_callsaves registers, builds a struct pt_regs stack frame, and finally calls the C function sys_execve via the system‑call table:
sys_execve(shown below) delegates to do_execve, which calls do_execve_common to 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->cs to __USER_CS (0x33 on x86‑64) and regs->ip to the program’s entry address:
When the interrupt returns via iret, the CPU pops the saved CS and IP from the stack, now containing __USER_CS and the ELF entry point, so execution resumes in user mode.
To verify this, the author used call_usermodehelper to run a small program that prints the CS register. 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 CS from __KERNEL_CS to __USER_CS during the iret return.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
