How is the init process started in the Linux kernel?
The kernel calls "init" as one of the very last things it does during kernel initialization. The function kernel_init()
in init/main.c has the logic.
You will notice that the kernel tries four different combinations of init, and expects one of them to succeed. You will also notice that you can override what the kernel executes on startup by feeding the kernel command line parameter "init". So, you can say, for example, init=/bin/mystartup on the kernel command line and start your own custom application instead of the default /sbin/init. Notice also that on most modern systems, even embedded systems, /sbin/init is a soft link that points to the real executable.
To more generally answer your question, study this source file (main.c) you can see virtually all of the details of Linux kernel initialization, after the low-level assembly stuff and platform initialization, which, beyond the educational value, you shouldn't have to touch nor care about much.
The main mechanism is to call do_execve()
with fixed arguments of argv_init
and envp_init
. The elf file is parsed and initial program counter (PC) is set as per the file. All memory management (mm) pages are mapped to the disks backing store. The code is set to run. On the initial PC fetch when it is scheduled, a page fault is generated which reads the first code page into memory. This is the same as any other execve()
call.
Related videos on Youtube
Sandeep Tayal
Updated on September 19, 2022Comments
-
Sandeep Tayal over 1 year
I am trying to understand the init process in the linux kernel which is the first process and is statically initialized with the INIT_TASK macro.
161 #define INIT_TASK(tsk) \ 162 { \ 163 .state = 0, \ 164 .stack = &init_thread_info, \ 165 .usage = ATOMIC_INIT(2), \ 166 .flags = PF_KTHREAD, \ 167 .prio = MAX_PRIO-20, \ 168 .static_prio = MAX_PRIO-20, \ 169 .normal_prio = MAX_PRIO-20, \ 170 .policy = SCHED_NORMAL, \ 171 .cpus_allowed = CPU_MASK_ALL, \ 172 .nr_cpus_allowed= NR_CPUS, \ 173 .mm = NULL, \ 174 .active_mm = &init_mm, \ 175 .se = { \ 176 .group_node = LIST_HEAD_INIT(tsk.se.group_node), \ 177 }, \ 178 .rt = { \ 179 .run_list = LIST_HEAD_INIT(tsk.rt.run_list), \ 180 .time_slice = RR_TIMESLICE, \ 181 }, \ 182 .tasks = LIST_HEAD_INIT(tsk.tasks), \ 183 INIT_PUSHABLE_TASKS(tsk) \ 184 INIT_CGROUP_SCHED(tsk) \ 185 .ptraced = LIST_HEAD_INIT(tsk.ptraced), \ 186 .ptrace_entry = LIST_HEAD_INIT(tsk.ptrace_entry), \ 187 .real_parent = &tsk, \ 188 .parent = &tsk, \ 189 .children = LIST_HEAD_INIT(tsk.children), \ 190 .sibling = LIST_HEAD_INIT(tsk.sibling), \ 191 .group_leader = &tsk, \ 192 RCU_POINTER_INITIALIZER(real_cred, &init_cred), \ 193 RCU_POINTER_INITIALIZER(cred, &init_cred), \ 194 .comm = INIT_TASK_COMM, \ 195 .thread = INIT_THREAD, \ 196 .fs = &init_fs, \ 197 .files = &init_files, \ 198 .signal = &init_signals, \ 199 .sighand = &init_sighand, \ 200 .nsproxy = &init_nsproxy, \ 201 .pending = { \ 202 .list = LIST_HEAD_INIT(tsk.pending.list), \ 203 .signal = {{0}}}, \ 204 .blocked = {{0}}, \ 205 .alloc_lock = __SPIN_LOCK_UNLOCKED(tsk.alloc_lock), \ 206 .journal_info = NULL, \ 207 .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ 208 .pi_lock = __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock), \ 209 .timer_slack_ns = 50000, /* 50 usec default slack */ \ 210 .pids = { \ 211 [PIDTYPE_PID] = INIT_PID_LINK(PIDTYPE_PID), \ 212 [PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID), \ 213 [PIDTYPE_SID] = INIT_PID_LINK(PIDTYPE_SID), \ 214 }, \ 215 .thread_group = LIST_HEAD_INIT(tsk.thread_group), \ 216 INIT_IDS \ 217 INIT_PERF_EVENTS(tsk) \ 218 INIT_TRACE_IRQFLAGS \ 219 INIT_LOCKDEP \ 220 INIT_FTRACE_GRAPH \ 221 INIT_TRACE_RECURSION \ 222 INIT_TASK_RCU_PREEMPT(tsk) \ 223 INIT_CPUSET_SEQ \ 224 INIT_VTIME(tsk) \ 225 }
But I am not able to figure out
how it will be executed?
Where it is scheduled and
which lines of code in the linux kernel start executing immediately when we say we have scheduled this init_task task? Is there any function which it calls?
-
Sandeep Tayal over 10 yearsThanks Challinan for your answer. very nice explanation. I am more looking towards which instructions or which lines of code init actually executes.I know it is statically allocated and this structure as initialized by INIT_TASK is pushed to execution by scheduler.
-
artless noise over 10 years@SandeepTayal What exactly is not clear? The init tasks code path is the same as any
execve()
program call; the kernel useddo_execve()
directly which is the end-point of anexecve()
syscall. -
Sridhar Sarnobat about 2 years
init -> ../bin/busybox
(buildroot based on Ubuntu) or/sbin/init -> /lib/systemd/systemd
(my "real" Ubuntu installation)