内核启动第一个程序
来源:互联网 发布:手机蜂窝数据打不开 编辑:程序博客网 时间:2024/05/21 09:45
从kernel_init()函数我们知道,init_post是最后执行的一个函数,我们来分析这个函数:
static int noinline init_post(void){ free_initmem(); unlock_kernel(); mark_rodata_ro(); system_state = SYSTEM_RUNNING; numa_default_policy(); /* 首先打开终端设备 */ if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) printk(KERN_WARNING "Warning: unable to open an initial console.\n"); /* 然后复制两个,共三个,分别是stdin,stdout,stderr */ (void) sys_dup(0); (void) sys_dup(0); 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. */ /* 执行命令行传入的int=xxxx程序, 如果没有就接着向下执行,如果成功则会一直运行不会向下执行。 */ if (execute_command) { run_init_process(execute_command); printk(KERN_WARNING "Failed to execute %s. Attempting " "defaults...\n", execute_command); } /* 如果上面没有成功,则向下执行 */ run_init_process("/sbin/init"); run_init_process("/etc/init"); run_init_process("/bin/init"); run_init_process("/bin/sh"); panic("No init found. Try passing init= option to kernel.");}从上面可以看出如果执行命令里没有 init=xxx 的参数,那么就会依次向下执行
run_init_process("/sbin/init");......
因为我们的执行命令里没有init=xxx参数,所以 init 就是我们的第一个进程。
但是如果我们执行下面的命令:
ls -l /sbin/initlrwxrwxrwx 1 messageb messageb 14 Dec 21 2012 /sbin/init -> ../bin/busybox
我们发现第一个程序是链接到busybox的,也就是说启动是busybox程序,所以我们要分析busybox源码里的init.c源码。
打开 busybox 源码中的 init.c文件,分析int.c 是怎么解析 /etc/inittab 文件以及执行程序的:
init_main parse_inittab file = fopen(INITTAB, "r"); //打开配置文件 new_init_action //创建init_action结构,并加入init_action_list链表 run_actions(SYSINIT); waitfor(a, 0); //执行应用程序,等待它执行完毕 run(a); //创建process子进程 waitpid //等待它结束 delete_init_action(a); //从init_action_list链表中删掉 run_actions(WAIT); waitfor(a, 0); //执行应用程序,等待它执行完毕 run(a); //创建process子进程 waitpid //等待它结束 delete_init_action(a); //从init_action_list链表中删掉 run_actions(ONCE); run(a); //不等待了,运行完后直接结束 delete_init_action(a); while (1) { run_actions(RESPAWN); if (a->pid == 0) { a->pid = run(a); } run_actions(ASKFIRST); if (a->pid == 0) { a->pid = run(a); 打印: "\nPlease press Enter to activate this console. "; 等待回车 } wpid = wait(NULL); //等待子进程退出 while (wpid > 0) { a->pid = 0; } }
当然在busybox/example下,我们可以查到 inittab的格式说明:
# Format for each entry: <id>:<runlevels>:<action>:<process>id --> /dev/it 用于终端:stdin, stdout,stderr
runlevels : 忽略
action :执行时机
process : 应用程序或脚本
这样第一个进程 init 就运行起来了。
- 内核启动第一个程序
- 内核启动第一个应用程序
- 第一个内核测试程序
- android 启动第一个程序
- linux内核如何启动第一个进程
- linux内核如何启动第一个进程
- 第一个内核模块程序编译
- 第一个Apk程序的启动
- 内核怎样启动第一个应用程序--韦东山教程学习
- 内核驱动的第一个程序——hello world
- 第一个内核驱动
- 第一个内核模块
- Android入门之第一个程序编写与启动
- 构造根文件系统之启动第一个程序
- 编写第一个内核模块
- 第一个Linux内核驱动程序
- 内核编译第一个错误
- 第一个helloworld内核模块
- CSS3 结构性伪类选择器
- ctags和Tlist
- JQuery使用Ajax同步提交数据
- 让百姓看得起病仍是医疗改革的首要问题
- Android的恢复模式
- 内核启动第一个程序
- 银行系统1.1
- [Android]破解android安卓apk软件所需的工具
- ubuntu下安装SSH服务
- Cpulimit
- kruscal 和 prim模板
- usb host驱动程序崩溃的问题
- JBPM学习(1):搭建JBPM4.4开发环境
- 【2013微软校招面试题】将链表的奇偶位交换,不能使用交换链表中的值这种做法。