根文件系统流程分析

我们知道内核启动后就要挂载根文件系统再执行应用程序,下面来分析一下根文件系统的流程,和所需要的东西。

内核挂接根文件系统后,怎么样启动第一个应用程序呢?内核分析得到 执行 static int __init kernel_init(void * unused) 分析这个函数
    kernel_init(void * unused)

    开始一堆初始化后。。。。打开一个设备

  先打开一个设备 /dev/console 就是串口0终端,后面两个 sys_dup(0); 复制两个设备,三个设备是指标准输入 标准输出 标准错误 指从那输入 从那输出,

  对于其它的设备 这个console 可能是键盘 LCD等   接下来调用 static noinline int init_post(void)

  init_post(void)

  

  如果定义了 execute_commadn 就会调用 run_init_process(execute_commadn); execute_commadn 是命令行参数 init=/linuxrc 如果有定义就会执行。

未定义就往下执行 一但执行 run_init_process 后,如果不出错或退出,就会一直在这个函数内执行,不会返回了。我们分析 run_init_process 这个函数就能知道,他需要那些内容

分析busybox源码来进一步分析 在busybox源码下找到 我们的init程序 里面会有init.c 里面有init_main(init argc,char **argv); 从这里开始分析

  init_main(init argc,char **argv)

    一些设置和初始化后

  上面 run_init_process 我们没有传进参数 所以执行else分支 parse_inittab 解析配置

  static void parse_inittab(void)  

    parser_t *parser = config_open2("/etc/inittab", fopen_for_read);      //打开  /etc/inittab  配置文件一般都放在 /etc 目录下

如果配置文件不存在 就会执行 new_init_action 这个函数就是创建黙认的配置文件 下面来分析配置文件 

在busybox 里inittab的说明 去查看一下 得到格式是

Format for each entry: <id>:<runlevels>:<action>:<process>

<id>      :  /dev/id    用于终端

<runlevels>    :   完全可以忽略

<action>    :  执行时机

<process>   :  就用程序或脚本

分析 static void new_init_action(uint8_t action_type, const char *command, const char *cons)

  创建struct init_action *a, **nextp; 结构体 填充 用传入的参数填充 init_action有下面的成员

struct init_action {
struct init_action *next;
pid_t pid;
uint8_t action_type;
char terminal[CONSOLE_NAME_SIZE];
char command[1];
};

  nextp = &init_action_list;   链表

  如果有配置文件 就解析它,如果没有就新建一个,我们用代码反推出一个配置文件,

<id>:<runlevels>:<action>:<process>      格式

/* No inittab file - set up some default behavior */
/* Sysinit */
new_init_action(SYSINIT, INIT_SCRIPT, "");    # define INIT_SCRIPT  "/etc/init.d/rcS"

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

/* Askfirst shell on tty1-4 */
new_init_action(ASKFIRST, bb_default_login_shell, "");  const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL; #define LIBBB_DEFAULT_LOGIN_SHELL  "-/bin/sh"

::askfirst:-/bin/sh
//TODO: VC_1 instead of ""? "" is console -> ctty problems -> angry users
new_init_action(ASKFIRST, bb_default_login_shell, VC_2);

/dev/tty2::askfirst:-/bin/sh
new_init_action(ASKFIRST, bb_default_login_shell, VC_3);

/dev/tty3::askfirst:-/bin/sh
new_init_action(ASKFIRST, bb_default_login_shell, VC_4);

/dev/tty4::askfirst:-/bin/sh
/* 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
/* Swapoff on halt/reboot */
new_init_action(SHUTDOWN, "swapoff -a", "");

::shutdown:swapoff -a
/* Restart init when a QUIT is received */
new_init_action(RESTART, "init", "");

::restart:init
return;

得到配置文件如下:

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

::askfirst:-/bin/sh

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

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

/dev/tty4::askfirst:-/bin/sh

::ctrlaltdel:reboot

::shutdown:umount -a -r

::shutdown:swapoff -a

::restart:init

解析配置文件后面就是执行 如下

run_actions 执行某一类程序 根据参数

sysinit wait ctrlaltdel shutdown 这些类 等待执行完毕 然后杀掉,

once 这类不等待执行完毕

respawn askfirst 重复执行,通过PID来决定何时执行。这两个区别就是 askfirst 需要在启动时 输入回车才会接着运行,如果想直接运行 就在配置里设置为 respawn

通过上面的分析,得到以下信息,

1:/dev/console

2:busybox

3:配置文件/etc/inittab

4:C库 就用程序是C库实现的

5:配置文件里指定的应用程序

6:补充 /dev/null 当ID为空时,就定位到这个设备

猜你喜欢

转载自www.cnblogs.com/x2i0e19linux/p/11697408.html
今日推荐