6.3 启动shell环境
init_post函数来自同一个文件的814行:
811/* This is a non __init function. Force it to be noinline otherwise gcc 812 * makes it inline to init() and it becomes part of init.text section 813 */ 814static noinline int init_post(void) 815 __releases(kernel_lock) 816{ 817 /* need to finish all async __init code before freeing the memory */ 818 async_synchronize_full(); 819 free_initmem(); 820 unlock_kernel(); 821 mark_rodata_ro(); 822 system_state = SYSTEM_RUNNING; 823 numa_default_policy(); 824 825 826 current->signal->flags |= SIGNAL_UNKILLABLE; 827 828 if (ramdisk_execute_command) { 829 run_init_process(ramdisk_execute_command); 830 printk(KERN_WARNING "Failed to execute %s/n", 831 ramdisk_execute_command); 832 } 833 834 /* 835 * We try each of these until one succeeds. 836 * 837 * The Bourne shell can be used instead of init if we are 838 * trying to recover a really broken machine. 839 */ 840 if (execute_command) { 841 run_init_process(execute_command); 842 printk(KERN_WARNING "Failed to execute %s. Attempting " 843 "defaults.../n", execute_command); 844 } 845 run_init_process("/sbin/init"); 846 run_init_process("/etc/init"); 847 run_init_process("/bin/init"); 848 run_init_process("/bin/sh"); 849 850 panic("No init found. Try passing init= option to kernel. " 851 "See Linux Documentation/init.txt for guidance."); 852} |
819行,这就是上面说到的那个释放init代码的函数了,它显然不能是__init打头:
void free_initmem(void)
{
free_init_pages("unused kernel memory",
(unsigned long)(&__init_begin),
(unsigned long)(&__init_end));
}
这个函数基本上就是执行init了,失败就panic了。顺便说一句,/dev/console最后被012描述符引用,也就是所有没有reopen的进程的标准输入输出和出错。
到此,内核启动过程就完成了,init根据根文件系统的配置在初始化用户态的进程,启动系统。我们的疯狂内核,也就到此告一段落了。