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. 忘记IBM服务器的登录IP

    问题描述: 一台服务器安装了winserver2003系统,经过漫长的加电启动,能进入到win2003的登录界面,提示ctrl+alt+del登录界面,但是发现键盘失灵了,无法键入ctrl+alt+d ...

  2. java jvm虚拟机类加载过程

    加载 在加载阶段, 虚拟机需要完成以下3件事情:1) 通过一个类的全限定名来获取定义此类的二进制字节流.2) 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构.3) 在内存中生成一个代表这 ...

  3. Vue 变异方法unshift&pop&shift

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 这一次,彻底弄懂 JavaScript 执行机制

    本文转自https://juejin.im/post/59e85eebf265da430d571f89#heading-4 本文的目的就是要保证你彻底弄懂javascript的执行机制,如果读完本文还 ...

  5. FFT/NTT基础题总结

    在学各种数各种反演之前把以前做的$FFT$/$NTT$的题整理一遍 还请数论$dalao$口下留情 T1快速傅立叶之二 题目中要求求出 $c_k=\sum\limits_{i=k}^{n-1}a_i* ...

  6. Spring Boot(十二):LocalDateTime格式化处理

    Java 8之后,日期类的处理建议使用java.time包中对应的LocalDateTime, LocalDate, LocalTime类.(参考Java8新特性) 在Spring Boot中(验证版 ...

  7. docker 通过中间镜像加速部署

    概要 实施 修改前的实施时间 制作编译用的镜像 测试修改后的实施时间 概要 使用 docker 打包镜像的时候, 每次耗费时间最多的就是 docker build 的过程. 特别是对于前端工程的打包, ...

  8. 十、Spring之BeanFactory源码分析(二)

    Spring之BeanFactory源码分析(二) 前言 在前面我们简单的分析了BeanFactory的结构,ListableBeanFactory,HierarchicalBeanFactory,A ...

  9. Elastic 使用索引生命周期管理实现热温冷架构

    Elastic: 使用索引生命周期管理实现热温冷架构 索引生命周期管理 (ILM) 是在 Elasticsearch 6.6(公测版)首次引入并在 6.7 版正式推出的一项功能.ILM 是 Elast ...

  10. jdbc:mysql:/// jdbc连接数据url简写方式

    正常情况下我们写jdbc连接本地mysql数据库的时候通常是这样写 jdbc:mysql:localhost:3306/数据库名 下面就是要提到的简单的方法 jdbc:mysql:///数据库名