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. day64_10_8 vue的导入

    一.简介 vue是一个渐进式的js框架.具体介绍查看官网: https://cn.vuejs.org 在vue框架中,有两个文件,当在开发阶段时使用完整版vue,因为有报错信息,而在上市阶段可以使用m ...

  2. 【day05】php

    一.时间日期函数库 1.安装:时间日期函数库PHPCORE组成部分 2.  (1)date_default_timezone_set(string $timezone)          设置时区  ...

  3. ASP.NET开发实战——(十三)ASP.NET MVC 与数据库之EF实体类与数据库结构

    大家都知道在关系型数据库中每张表的每个字段都会有自己的属性,如:数据类型.长度.是否为空.主外键.索引以及表与表之间的关系.但对于C#编写的类来说,它的属性只有一个数据类型和类与类之间的关系,但是在M ...

  4. json去除value值的前后空格

    /** * @Title: JsonStrTrim * @author : jsw * @date : 2012-12-7 * @time : 上午09:19:18 * @Description: 传 ...

  5. Python之爬虫-校花网

    Python之爬虫-校花网 #!/usr/bin/env python # -*- coding:utf-8 -*- import re import requests # 拿到校花网主页的内容 re ...

  6. OI回忆录——梦开始的地方

    前言 谨以此文,纪念和整理我在OI之路上的奔波历程. 或许,等到或早或晚都要来临的退役真正来临时,再写回忆录,就晚了,那么,趁现在,自信还在,青春犹存,整理一下我慢慢的OI路吧. 我真正开始接触OI是 ...

  7. torch_13_自定义数据集实战

    1.将图片的路径和标签写入csv文件并实现读取 # 创建一个文件,包含image,存放方式:label pokemeon\\mew\\0001.jpg,0 def load_csv(self,file ...

  8. 【前端知识体系-JS相关】对移动端和Hybrid开发的理解?

    1.hybrid是什么,为何使用hybrid呢? 概念: hybrid就是前端和客户端的混合开发 需要前端开发人员和客户端开发人员配合完成 某些环节也可能会涉及到server端 大前端:网页.APP. ...

  9. 简述vue props和非props的2个特性

    props的2个特性 ①:父组件通过属性的方式传值(比如下面截图中的content)给子组件,content不会显示在DOM节点中                       ②:父组件向子组件传递值 ...

  10. Python sorted 函数

    Python sorted 函数 sorted 可以对所有可迭代的对象进行排序操作,sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作.从新排序列表. sorted 语法: ...