bugsplat( 六 )


963if(!try_to_run_init_process("/sbin/init")||
964!try_to_run_init_process("/etc/init")||
965!try_to_run_init_process("/bin/init")||
966!try_to_run_init_process("/bin/sh"))
967return0;
968
969 panic("No working init found. Try passing init= option to kernel. "
970"See Linux Documentation/init.txt for guidance.");
971}
第932行,kernel_init_freeable函数用于完成init进程的一些其他初始化工作,稍后再来具体看一下此函数 。
第940行,ramdisk_execute_command是一个全局的char指针变量,此变量值为"/init",也就是根目录下的init程序 。ramdisk_execute_command也可以通过uboot传递,在bootargs中使用"rdinit=xxx"即可,xxx为具体的init程序名字 。
第943行,如果存在"/init"程序的话就通过函数run_init_process来运行此程序 。
第956行,如果ramdisk_execute_command为空的话就看execute_command是否为空,反正不管如何一定要在根文件系统中找到一个可运行的init程序 。execute_command的值是通过uboot传递,在bootargs中使用"init=xxxx"就可以了,比如"init=/linuxrc"表示根文件系统中的linuxrc就是要执行的用户空间init程序 。
第963~966行,如果ramdisk_execute_command和execute_command都为空,那么就依次查找"/sbin/init"、"/etc/init"、"/bin/init"和"/bin/sh",这四个相当于备用init程序,如果这四个也不存在,那么Linux启动失败!
第969行,如果以上步骤都没有找到用户空间的init程序,那么就提示错误发生!
最后来简单看一下kernel_init_freeable函数,前面说了,kernel_init会调用此函数来做一些init进程初始化工作 。kernel_init_freeable定义在文件init/main.c中,缩减后的函数内容如下:
示例代码36.2.5.2 kernel_init_freeable函数
973static noinline void __init kernel_init_freeable(void)
974{
975/*
976 * Wait until kthreadd is all set-up.
977 */
978 wait_for_completion(&kthreadd_done);/* 等待kthreadd进程准备就绪 */
......
998
999 smp_init(); /* SMP初始化 */
1000 sched_init_smp(); /* 多核(SMP)调度初始化 */
1001
1002 do_basic_setup();/* 设备初始化都在此函数中完成 */
1003
1004/* Open the /dev/console on the rootfs, this should never fail */
1005if(sys_open((constchar __user *)"/dev/console", O_RDWR,0)<0)
1006 pr_err("Warning: unable to open an initial console.\n");
1007
1008(void) sys_dup(0);
1009(void) sys_dup(0);
1010/*
1011 * check if there is an early userspace init. If yes, let it do
1012 * all the work
1013 */
1014
1015if(!ramdisk_execute_command)
1016 ramdisk_execute_command ="/init";
1017
1018if(sys_access((constchar __user *) ramdisk_execute_command,0)!=0){
1019 ramdisk_execute_command =NULL;
1020 prepare_namespace();
1021}
1022
1023/*
1024 * Ok, we have completed the initial bootup, and
1025 * we\'re essentially up and running. Get rid of the
1026 * initmem segments and start the user-mode stuff..
1027 *
1028 * rootfs is available now, try loading the public keys
1029 * and default modules
1030 */
1031
1032 integrity_load_keys();
1033 load_default_modules();
1034}
第1002行,do_basic_setup函数用于完成Linux下设备驱动初始化工作!非常重要 。do_basic_setup会调用driver_init函数完成Linux下驱动模型子系统的初始化 。
第1005行,打开设备"/dev/console",在Linux中一切皆为文件!因此"/dev/console"也是一个文件,此文件为控制台设备 。每个文件都有一个文件描述符,此处打开的"/dev/console"文件描述符为0,作为标准输入(0) 。
第1008和1009行,sys_dup函数将标准输入(0)的文件描述符复制了2次,一个作为标准输出(1),一个作为标准错误(2) 。这样标准输入、输出、错误都是/dev/console了 。console通过uboot的bootargs环境变量设置,"console=ttymxc0,115200"表示将/dev/ttymxc0设置为console,也就是I.MX6U的串口1 。当然,也可以设置其他的设备为console,比如虚拟控制台tty1,设置tty1为console就可以在LCD屏幕上看到系统的提示信息 。


特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。