到init_post函数为止,内核的初始化已经基本结束,接着会产生用户进程
/* This is a non __init function. Force it to be noinline otherwise gcc
* makes it inline to init() and it becomes part of init.text section
*/
static noinline int init_post(void)
{
/* need to finish all async __init code before freeing the memory */
async_synchronize_full();
/*所有的初始化函数都已经被调用,舍弃内存的__init_begin至__init_end(包括.init.setup
.initcall.init等section之间的数据。所有使用__init标记过的函数和使用__initdata标记过的
数据,在free_initmem函数执行后,都不能使用,它们曾经获得的内存现在可以重新用于
其他目的*/
free_initmem();
mark_rodata_ro();
system_state = SYSTEM_RUNNING;
numa_default_policy();
current->signal->flags |= SIGNAL_UNKILLABLE;
if (ramdisk_execute_command) {
run_init_process(ramdisk_execute_command);
printk(KERN_WARNING "Failed to execute %s\n",
ramdisk_execute_command);
}
/*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are
* trying to recover a really broken machine.
*/
if (execute_command) {
run_init_process(execute_command);
printk(KERN_WARNING "Failed to execute %s. Attempting "
"defaults...\n", execute_command);
}
/*接下来的几行会在几个地方查找init,按照可能性由高到低的顺序依次是:/sbin/init,
这个是init标准的位置;/etc/init和/bin/init,两个可能的位置。如果在这3个地方都没
有发现init,也就无法到它的同名者了,系统可能就此崩溃。*/
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
/*试图建立一个交互的shell(/bin/sh)来代替,希望root用户可以修复这种错误并重新启动
机器*/
run_init_process("/bin/sh");
/*由于某些原因,init甚至不能创建shell。当前面所有的情况都失败时,调用panic。这样
内核就会试图同步磁盘,确保其状态一致,如果超过了内核选项中定义的时间,它也可能
会重新启动机器*/
panic("No init found. Try passing init= option to kernel. "
"See Linux Documentation/init.txt for guidance.");
}