busybox是ls、cp等命令的集合。

执行ls时,实际上是执行了busybox ls

执行cp时,实际上是执行了busybox cp

分析init程序之前,再让我们回想一下我们的目标:u-boot启动内核,内核启动应用程序,内核是怎样启动应用程序呢,内核启动了init进程,位于/sbin/init中。我们最终的目的是启动客户程序,也就是说假如你是做手机的,希望启动一个手机的程序,假如是做监控的,那么就启动一个监控的程序的。客户各有不同,但都使用了linux系统,那么怎样加以区分呢?

init程序中应该有这样的内容:

读取配置文件,指定后面要执行的应用程序;

解析配置文件;

根据配置文件,执行用户的程序;

busybox ->init_main

      parse_inittab();

        file = fopen(INITTAB, "r");//#define INITTAB      "/etc/inittab"   打开配置文件/etc/inittab

        new_init_action(a->action, command, id);  a.创建一个init_action的结构,并填充;

                             b.将init_action这个结构放入init_action_list链表中;

      run_actions(SYSINIT);

      static void run_actions(int action)

      {
        struct init_action *a, *tmp;       

        waitfor(a, 0);  执行应用程序,等待它执行完毕

          run(a);  创建process子进程

          wpid = waitpid(runpid, &status, 0);  等待它结束
        delete_init_action(a);  在init_action_list链表中删除a  
      }

      run_actions(WAIT)

      static void run_actions(int action)

      {
        struct init_action *a, *tmp;       

        waitfor(a, 0);  执行应用程序,等待它执行完毕

          run(a);  创建process子进程

          wpid = waitpid(runpid, &status, 0);  等待它结束
        delete_init_action(a);  在init_action_list链表中删除a  
      }

      run_actions(ONCE)  

          run(a);  创建process子进程

          delete_init_action(a); 不会等待结束,就在init_action_list链表中删除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);
          }

        wpid = wait(NULL);//等待子进程退出

        while (wpid > 0) {

          a->pid = 0;  //退出后,就设置pid等于0

        }

      }

在/etc/inittab文件控制下,init进程的行为总结如下:

a.在系统启动前期,init进程首先启动<action>为sysinit、wait、once的三类子进程;

b.在系统正常运行期间,init进程首先启动<action>为respawn、askfirst的两类子进程,并监视它们,发现某个子进程退出时重新启动它

c.在系统退出时,执行<action>为shutdown、restart、ctrlaltdel的三类子进程(之一或全部)

最小的根文件系统:

/dev/console     /dev/null在busybox  init程序中,还会检查这个设备是否可以打开,如果不能打开则使用/dev/null

init来源于busybox

/etc/inittab

配置文件中指定的应用程序

c库

                              

假设没有配置文件,从默认的new_init_action中退出配置文件:

#inittab的格式:

#<id>:<runlevels>:<action>:<process>

#id=>/dev/id,最终用作终端。stdin、stdout、stderr

#runlevels:完全可以忽略    <runlevels>: The runlevels field is completely ignored

#action:执行时机

<action>:  sysinit, respawn, askfirst, wait, once,
                restart, ctrlaltdel, and shutdown.

#process:应用程序或脚本

/* Reboot on Ctrl-Alt-Del */
new_init_action(CTRLALTDEL, "reboot", "");

推出          ::CTRLALTDEL:reboot

/* Umount all filesystems on halt/reboot */
new_init_action(SHUTDOWN, "umount -a -r", "");

推出         ::SHUTDOWN:umount -a -r

/* Prepare to restart init when a HUP is received */
new_init_action(RESTART, "init", "");

推出:     ::RESTART:init
/* Askfirst shell on tty1-4 */
new_init_action(ASKFIRST, bb_default_login_shell, "");
new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
new_init_action(ASKFIRST, bb_default_login_shell, VC_4);

依次推出  ::askfirst:-/bin/sh

      /dev/tty2::askfirst:-/bin/sh

      /dev/tty3::askfirst:-/bin/sh

      /dev/tty4::askfirst:-/bin/sh
/* sysinit */
new_init_action(SYSINIT, INIT_SCRIPT, "");

#define INIT_SCRIPT  "/etc/init.d/rcS"

推出    ::sysinit:/etc/init.d/rcS

以new_init_action(ASKFIRST, bb_default_login_shell, VC_2);为例进行分析:

#define LIBBB_DEFAULT_LOGIN_SHELL      "-/bin/sh"  ,

# define VC_2 "/dev/tty2"因此new_init_action(ASKFIRST, bb_default_login_shell, VC_2)变为

new_init_action(ASKFIRST, "-/bin/sh" , "/dev/tty2")

static void new_init_action(int action, const char *command, const char *cons)这个函数里面有个结构体init_action ,看一下这个结构体中的成员:

struct init_action {
struct init_action *next;
int action;  执行时机
pid_t pid;   
char command[INIT_BUFFS_SIZE];应用程序或脚本
char terminal[CONSOLE_NAME_SIZE];终端
};

因此可以推断new_init_action这个函数做了这几件事:

a.创建一个init_action的结构,并填充;

b.将init_action这个结构放入init_action_list链表中;

构建根文件系统之init进程分析的更多相关文章

  1. 根文件系统之init

    title: 根文件系统之init tag: arm date: 2018-11-12 18:53:23 --- 引入 在Kernel源码分析中,了解到init_post是在挂载根文件系统之后执行应用 ...

  2. linux2.6.30.4内核移植(5)——构建根文件系统(yaffs文件系统格式的镜像)

    一.首先编译并安装BusyBox 这里使用的交叉编译器还是3.4.5. 注意:编译内核.编译BusyBox以及编译文件系统中的所有应用程序的交叉编译器要使用同一个版本. 1.获取BusyBox源码 下 ...

  3. Busybox构建根文件系统和制作Ramdisk

      定制根文件系统的方法很多,最常用的是使用BusyBox来构建定制根文件系统.它集成压缩了Linux的许多工具和命令,可以使用户迅速方便地建立一套相对完整.功能丰富的文件系统,其中包括大量常用的应用 ...

  4. 使用busybox构建根文件系统

    当我们在Qemu上运行起来自己编译的内核之后,需要使用busybox构建一个文件系统,将此文件系统挂载上去就可以使用busybox提供的各种命令了. 1.编译安装busybox 源码下载地址:http ...

  5. android init进程分析 init脚本解析和处理

    (懒人近期想起我还有csdn好久没打理了.这个android init躺在我的草稿箱中快5年了.略微改改发出来吧) RC文件格式 rc文件是linux中常见的启动载入阶段运行的文件.rc是run co ...

  6. 韦东山笔记之用busybox构建根文件系统

    1 百度搜索busybox进入busybox官网(https://busybox.net/)作者:恒久力行 QQ:624668529  点击左侧DownloadSource下载最新稳定版的busybo ...

  7. android init进程分析 ueventd

    转自:http://blog.csdn.net/freshui/article/details/2132299 (懒人最近想起我还有csdn好久没打理了,这个Android init躺在我的草稿箱中快 ...

  8. 构建根文件系统之busybox

    配置busybox 首先将busybox的压缩包放入服务器进行解压缩: busybox集合了几百个命令,在一般的系统中并不需要全部使用.可以通过配置busybox来选择这些命令.定制某些命令的功能(选 ...

  9. 第4阶段——制作根文件系统之编译配置安装busybox(3)

    在上一节分析出制作一个最小的根文件系统至少需要: (1)/dev/console(终端控制台, 提供标准输入.标准输出以及标准错误) /dev/null  (为空的话就是/dev/null, 所有写到 ...

随机推荐

  1. springboot中的照片上传工具类

    public class UploadImgUtils { private static String savePath = ""; /** * 上传照片工具类 * * @para ...

  2. mongodb数据库的存储问题

    MongoDB在Windows中默认的数据库目录是c:\data.如果在没有该目录的情况下,直接运行mongod.exe,就会报如下错误(并没有把mongodb设置为服务,所以通过命令行的形式启动,注 ...

  3. 用arthas查看JVM已加载的类及方法信息

    1.sc:“Search-Class” 的简写,这个命令能搜索出所有已经加载到 JVM 中的 Class 信息,这个命令支持的参数有 [d].[E].[f] 和 [x:]. [d] 输出当前类的详细信 ...

  4. 记录错误or日记(更新中)

    前言: 从2018.8-17开始记录 本篇随笔记录做题时的小错误(大多数),考试总结(懒得总结了),做过的每个题的错误 2019.12.7 傻逼学校,给我三个小时假期给你们做题挣工资 2019.11. ...

  5. 第四组 团队Git现场编程实战

    组员职责分工 组员 分工 林涛(组长) 分配任务.整理数据.写博客 童圣滔 UI界面制作 林红莲 UI界面制作 潘雨佳 测评出福州最受欢迎的商圈 于瀚翔 测评出福州最受欢迎的商圈 覃鸿浩 测评出福州人 ...

  6. Gradle java使用

    安装 去gradle官网下载然后解压,把bin路径添加到PATH变量即可 查看版本号 gradle -v 生成gradle项目 在新建/已有项目目录下初始化项目 gradle init 配置仓库源 编 ...

  7. Allure+pytest 生成测试报告

    简介: python 主流自动化测试报告插件有三个:HTMLTestRunner.BeautifulReport 和 Allure.HTMLTestRunner是一个比较古老的报告模板,界面也不是很好 ...

  8. python asyncio run_until_complete

    import asyncio def callback(loop, i): print("success time {} {}".format(i, loop.time())) a ...

  9. Oracle 原生驱动带来的精度问题的分析与解决

    问题 Oracle 官方提供了 dotnet core 驱动,但我们在使用中遇到了精度问题. 复现 以下代码运行数学运算 1/3,无论是 OracleCommand.ExecuteScalar() 还 ...

  10. [CrackMe]160个CrackMe之001

    吾爱破解专题汇总:[反汇编练习]160个CrackME索引目录1~160建议收藏备用 一.Serial/Name 之 暴力破解 1. 熟悉界面:很常规的一个界面,输入完账号密码之后会进行验证.  2. ...