ARM-Linux移植之(三)——init进程启动流程分析
我们通常使用Busybox来构建根文件系统的必要的应用程序。Busybox通过传入的参数来决定执行何种操作。当init进程启动时,实际上调用的是Busybox的init_main()函数,下面我们来分析这个函数,看init进程究竟是怎样一个流程。我分析的Busybox源码是1.7.0版本的,其他版本会略有不同。部分代码省略我们只看关键性代码。
首先看init_main函数
plain?
- 01.int init_main(int argc, char **argv);
- 02.int init_main(int argc, char **argv)
- 03.{
- 04. ……………………………..
- 05. ……………………………..
- 06. //初始化控制台
- 07. console_init();
- 08. ………………………………
- 09.
- 10. if (argc > 1
- 11. && (!strcmp(argv[1], "single") || !strcmp(argv[1], "-s") || LONE_CHAR(argv[1], '1'))
- 12. ) {
- 13. new_init_action(RESPAWN, bb_default_login_shell, "");
- 14. } else {
- 15. //因为我们启动的init进程没有任何参数,所有argc==1,执行的是这一句
- 16. parse_inittab();
- 17. }
- 18. …………………………………………
- 19. …………………………………………
- 20. run_actions(SYSINIT); //运行inittab配置文件中acthion为SYSINIT的进程
- 21. run_actions(WAIT); //运行inittab配置文件中action为WAIT的进程
- 22.
- 23.
- 24. run_actions(ONCE); //运行inittba配置文件中action为ONCE的进程
- 25. ………………………………………………
- 26. while (1) {
- 27. /*
- 28. 运行inittab配置文件中action为RESPAWN和ASKFIRST的进程,一旦退出则重新启动
- 29. */
- 30. run_actions(RESPAWN);
- 31. run_actions(ASKFIRST);
- 32.
- 33. wpid = wait(NULL);
- 34. while (wpid > 0) {
- 35. a->pid = 0;
- 36. }
- 37. wpid = waitpid(-1, NULL, WNOHANG);
- 38.
- 39. }
- 40.}
parse_inittab实际上对/etc/inittab文件里面的配置进行解释,如果没有,则设置一些默认设置。
我们先来看看这个inittab这个文件里面的配置格式,这个在busybox文件里面的inittab文件里面有说明
<id>:<runlevels>:<action>:<process>
id表示输出输入设备,这个不需要设置,因为/etc/console已经设为标准输入输出了,如不设置,则从控制台输入输出。
runlevels 这个参数完全忽略
action 运行时机,它表示inittab解释后的运行顺序,它有sysinit, respawn, askfirst, wait, once,restart, ctrlaltdel, andshutdown.这个值可选择。
process 就是要启动的进程。
下面来看prase_inittab这个函数
plain?
- 01.static void parse_inittab(void)
- 02.{
- 03.…………………………………………………
- 04.…………………………………………………
- 05.
- 06. /*INITTAB是一个宏 #define INITTAB "/etc/inittab"
- 07. 可以看得出来它打开了/etc/inittab这个文件*/
- 08.
- 09. file = fopen(INITTAB, "r");
- 10.
- 11. //如果没有这个文件,则调用new_init_action进行一些默认的操作
- 12. if (file == NULL) {
- 13. new_init_action(CTRLALTDEL, "reboot", "");
- 14. new_init_action(SHUTDOWN, "umount -a -r", "");
- 15. if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");
- 16. new_init_action(RESTART, "init", "");
- 17. new_init_action(ASKFIRST, bb_default_login_shell, "");
- 18. new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
- 19. new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
- 20. new_init_action(ASKFIRST, bb_default_login_shell, VC_4); new_init_action(SYSINIT, INIT_SCRIPT, "");
- 21.
- 22. return;
- 23. }
- 24. …………………………………………………
- 25.…………………………………………………
- 26. /*果inittab文件里面有内容就将里面的内容一行一行读出来,然后调用new_init_action进行操作*/
- 27. while (fgets(buf, INIT_BUFFS_SIZE, file) != NULL) {
- 28. /* Ok, now process it */
- 29. for (a = actions; a->name != 0; a++) {
- 30. if (strcmp(a->name, action) == 0) {
- 31. if (*id != '\0') {
- 32. if (strncmp(id, "/dev/", 5) == 0)
- 33. id += 5;
- 34. strcpy(tmpConsole, "/dev/");
- 35. safe_strncpy(tmpConsole + 5, id,
- 36. sizeof(tmpConsole) - 5);
- 37. id = tmpConsole;
- 38. }
- 39. new_init_action(a->action, command, id);
- 40. break;
- 41. }
- 42. }
- 43. …………………………………………………
- 44.…………………………………………………
- 45. }
- 46. fclose(file);
- 47.}
这个new_init_action函数,它实际上是将inittab里面的action相同的操作串成一个链表。
下面我们再来分析init_main执行prase_inittab之后执行的操作
可以看出init_main执行prase_initab对inittab文件里面的配置进行解释之后,会先执行运行时机为SYSINIT的进程,让执行WAIT时机的,接着是ONCE的,然后在一个while(1)函数里面运行RESPAWN和ASKFIRST时机的,一旦这两个时机里面的进程被杀死,就会把他们的pid赋为0,然后跳到while(1)函数的开始处又去启动他们。所有说运行时机为RESPAWN和ASKFIRST的进程永远无法杀死,除非reboot或者shutdown。
下面我们来总结一下init进程的启动过程
1.初始化控制台
2.解释inittab
3.执行inittab运行时机为SYSINIT的进程
4.执行inittab运行时机为WAIT的进程
5.执行inittab运行时机为ONCE的进程
6.执行inittab运行时机为RESPAWN和ASKFRIST的进程,有退出的则重新执行。
ARM-Linux移植之(三)——init进程启动流程分析的更多相关文章
- linux根文件系统制作,busybox启动流程分析
分析 busybox-1.1.6 启动流程,并 制作一个小的根文件系统 源码百度云链接:https://pan.baidu.com/s/1tJhwctqj4VB4IpuKCA9m1g 提取码 :l10 ...
- Linux内核分析-使用gdb跟踪调试内核从start_kernel到init进程启动
姓名:江军 ID:fuchen1994 实验日期:2016.3.13 实验指导 使用实验楼的虚拟机打开shell cd LinuxKernel/ qemu -kernel linux-3.18.6/a ...
- 实验三:gdb跟踪调试内核从start_kernel到init进程启动
原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 如果我写的不好或者有误的地方请留言 ...
- Android系统启动流程(一)解析init进程启动过程
整体流程大致如下: 1.init简介 init进程是Android系统中用户空间的第一个进程,作为第一个进程,它被赋予了很多极其重要的工作职责,比如创建zygote(孵化器)和属性服务等.in ...
- Android系统init进程启动及init.rc全解析
转:https://blog.csdn.net/zhonglunshun/article/details/78615980 服务启动机制system/core/init/init.c文件main函数中 ...
- arm linux 移植 x265
背景 本来想着把 x265编译到ffmpeg里面,搞定了x265的编译:但是一直报ERROR: x265 not found using pkg-config这个错误,我按照网上的资料,查看了ffbu ...
- arm linux kernel 从入口到start_kernel 的代码分析
参考资料: <ARM体系结构与编程> <嵌入式Linux应用开发完全手册> Linux_Memory_Address_Mapping http://www.chinaunix. ...
- 鸟哥的linux私房菜——第20章 启动流程、模块管理与loader
20.1 Linux启动流程分析 Linux启动过程: 按下开机电源后计算机硬件主动读取BIOS来加载硬件信息以及硬件系统的自我测试,之后系统会主动读取第一个可启动的设备(由BIOS设置),此时就可以 ...
- (转)Ubuntu init启动流程分析
原文 upstart homepage 现行的Linux distros主流的有两种init方式:一种是广为流传的System V initialization,它来源于Unix并且至今仍被各种Lin ...
随机推荐
- linux rpm 卸载,简单说明
平时Linux卸载文件总是遇到卸载不干净,各种依赖什么的,今天又是搞这玩意,就记录下一个比较常规的方法. 一.查询包括某关键字的软件(这里以卸载openoffice为例) 查询包括office的软件 ...
- 交换机上的trunk,hybrid,access配置和应用(转)
交换机上的trunk,hybrid,access配置和应用 以太网端口的链路类型: Access类型:端口只能属于一个vlan,一般用于连接计算机. Trunk类型:端口可以属于端个vlan,可以接收 ...
- 解析session与cookie
Session和Cookie相关概念 Session和Cookie都是有服务器生成的. Session和Cookie都是键值对形式保存,主要用于存储特定的一些状态值. Session保存在服务器,Co ...
- idea结合git使用(正常项目开发过程中的使用)
1.如何将本地项目代码提交到公司码云上面 1.项目右键 2. 在远处的remotes里面设置你的url
- Redis 命令,键(key),字符串(String),哈希(Hash),列表(List),集合(Set)(二)
Redis 命令 Redis 命令用于在 redis 服务上执行操作. 要在 redis 服务上执行命令需要一个 redis 客户端.Redis 客户端在我们之前下载的的 redis 的安装包中. ...
- LeetCode OJ:Jump Game(跳跃游戏)
Given an array of non-negative integers, you are initially positioned at the first index of the arra ...
- UI- Layer的使用总结(附动画)
#pargma mark - Layer 1. 设置当前视图的背景颜色 self.view.backgroundColor = [UIColor lightGrayColor]; 2. 创建一个视图, ...
- H264提供了哪些帧内预测?
H.264/AVC 提供了四种帧内预测方式:4x4 亮度块的帧内预测(Intra_4x4).16x16 亮度块的帧内预测(Intra_16x16).8x8 色度块的帧内预测(Intra_chroma) ...
- C++纯虚函数实现
纯虚函数就是一个在基类中的虚函数,差别只是在一般的虚函数声明的后面加了"=0",虚函数允许函数通过与函数体之间的联系在运行时才建立,也就是在运行时才决定如何动作,称为运行时的多态性 ...
- 前端之jQuery02
文档操作 重点:创建标签,jQuery里面没有这个方法 内部(子标签) 添加到指定元素内部后面 $(A).append(B): // B作为A的最后一个儿子元素:(把B追加到A) $(A).appen ...