The init Process
When start_kernel forks out the
init thread (implemented by the
init function in
init/main.c), it is still running in kernel mode,
and so is the init thread. When all
initializations described earlier are complete, the thread drops the
kernel lock and prepares to execute the user-space
init process. The file being executed
resides in /sbin/init,
/etc/init, or /bin/init. If
none of those are found, /bin/sh is run as a
recovery measure in case the real init got
lost or corrupted. As an alternative, the user can specify on the
kernel command line which file the init
thread should execute.
The procedure to enter user space is simple. The code opens
/dev/console as standard input by calling the
open system call and connects the console to
stdout and stderr by calling
dup; it finally calls execve
to execute the user-space program.
The thread is able to invoke system calls while running in kernel mode
because init/main.c has declared
__KERNEL_SYSCALLS__ before
including <asm/unistd.h>. The header defines
special code that allows kernel code to invoke a limited number of
system calls just as if it were running in user space. More
information about kernel system calls can be found in
http://www.linux.it/kerneldocs/ksys.
The final call to execve finalizes the transition to user space. There is no magic involved in this transition. As with any execve call in Unix, this one replaces the memory maps of the current process with new memory maps defined by the binary file ...