Fundamentals 10 min read

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.

Efficient Ops
Efficient Ops
Efficient Ops
How Linux Init Switches from Kernel to User Mode: Inside kernel_execve

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_call

saves 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.

Linuxsystem callinit processkernel_execveprivilege transition
Efficient Ops
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.