• 【转】嵌入式Linux文件系统启动脚本及分析


    原文网址:http://www.linuxidc.com/Linux/2011-03/33728.htm

    在内核初始化完成后,嵌入式linux 文件系统的启动过程主要包含以下几个步骤:

    1. 执行/sbin/init 文件

    2. 执行/etc/inittab 文件

    3. 执行/etc/init.d/rcS 文件

    4. 执行挂载文件系统脚本

    5. 执行内核模块脚本

    6. 执行网络初始化脚本

    7. 执行应用程序启动等脚本,如qtopia 的启动

    系统启动流程图:

    1. 内核启动init

    内核启动的最后一步就是启动init 进程,init 进程是由内核启动的第一个(也是唯一一个和)用户进程(进程ID 为1 ),它根据配置文件决定启动哪些程序,比如某些脚本, 启动shell ,运行用户指定的程序等,,那么init 进程又是怎么启动的呢---是由内核调用/sbin/init 文件而启动的,那有人就有人想知道内核是如何找到需要执行的init 文件呢。下面看一下内核代码中init/main.c ,如下所示:

    static int noinline init_post(void)

    {

    free_initmem(); /* 释放初始化内存*/

    unlock_kernel();

    mark_rodate_ro();

    system_state=SYSTEM_RUNNING;

    numa_default_policy();

    /* 打开控制设备hanle=0=>stdin*/

    if(sys_open((const char __user*) “/dev/console”, O_RDWR,0)<0)

    printk(KERN_WARNING “Waring :unable to open an initial console. ”);

    /* 复制控制台设备到handle 1,2=>stout,stderr*/

    (void)sys_dup(0);

    (void)sys_dup(0);

    /* 尝试执行ramdisk_execute_command 指定的程序*/

    if(ramdisk_execute_command) {

    run_init_process(ramdisk_execute_command);

    printk(KERN_WARNING “Failed to execute %s ”,ramdisk_execute_command);

    }

    /* 尝试执行execute_command 指定的程序*/

    if(execute_command) {

    run_init_process(execute_command);

    printk(KERN_WARNING “Failed to execute %s ”,execute_command);

    }

    /* 依次尝试执行四个外部程序*/

    run_init_process(“/sbin/init”);

    run_init_process(“/etc/init”);

    run_init_process(“/bin/init”);

    run_init_process(“/bin/sh”);

    panic(“No init found . Try passing init=option to kernel.”);

    内核启动init 进程的过程如下:

    先打开控制台设备/dev/console ,并复制了两个handle, 这样stdout,stdin,stderr 都指向/dev/console, 这样就打开了标准设备输入,输出,标准错误设备,然后执行几个外部程序。由ramdisk_execute_command指定的外部程序,即在u-boot启动时设置的内核启动参数"init=XXX"指定的

    程序由execute_command指定的外部程序,即内核启动参数“init=XXX”指定的程序

    /sbin/init

    /etc/init

    /bin/init

    /bin/sh

    这几个程序中任何一个加载成功就进入了用户态,内核启动就宣告结束。而启动的init也就是系统启动后的第一个进程。但如果以上都没有,则linux打印panic("No init found. Try passing init = option to kernel.")

    2. 执行/etc/inittab 文件

    当init 启动成功后,需要做的就是分析/etc/inittab 文件并执行它。对于inittab文件,如果使用busybox的init文件,inittab文件内容与传统的是有区别的:

    传统的init:主要应用于PC环境,支持运行级别

    busybox的inittab:由于主要用于嵌入式,所以没有运行级别的概念。

    (1)传统init对应inittab文件:

    # 设置默认运行级别为5

    id:5:initdefault:

    # 系统开机需要运行的第一个脚本

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

    # 运行级

    #0 挂起系统,6 重新引导,1 单用户模式,2-5多用户模式

    I0:0:wait:/etc/init.d/rc 0

    I1:1:wait:/etc/init.d/rc 1

    I2:2:wait:/etc/init.d/rc 2

    I3:3:wait:/etc/init.d/rc 3

    I4:4:wait:/etc/init.d/rc 4

    I5:5:wait:/etc/init.d/rc 5

    I6:6:wait:/etc/init.d/rc 6

    # 登录系统

    S:2345:respawn:/etc/init.d/login 115200 ttyS2

    (2)busybox的init对应的inittab文件:

    # /etc/inittab

    # 系统开机需要运行的第一个脚本

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

    # 自动作为root账户登录

    ::respawn:-/bin/login -f root

    # 系统关机运行的脚本

    ::shutdown:/etc/init.d/rcK

    # 系统重新启动运行程序或脚本

    ::restart:/sbin/init

    # 启动shell 以/dev/ttySAC0 作为控制台

    ttySAC0::askfirst:-/bin/sh

    # 按下ctrl+alt+del 之后执行的程序,不过在串口控制台中无法输入ctrl+alt+del 组合键

    ::ctrlaltdel:/sbin/reboot

    # 重启关机前执行的程序

    ::shutdown:/bin/umount -a -r

    3. 执行/etc/init.d/rcS 文件

    执行/etc/init.d/rcS文件时在inittab文件中做的,第二步已经看到了。在此,我们以busybox的init的无运行级别方式来说明。

    #!/bin/sh

    #运行执行/etc/init.d目录中以S开头的文件

    for s in /etc/init.d/S*;do

      if [ -x $s]; then

        $s start

      fi

    done

    目前执行脚本大概有:

    /etc/init.d/S00mountvirtfs

    /etc/init.d/S05hotplut

    ......

    这是一个脚本文件,可以在里面添加想自动运行的命令。内容如下:

    #! /bin/sh

    PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:

    runlevel=S

    prevlevel=N

    umask 022

    export PATH runlevel prevlevel

    # 网络配置脚本

    . /etc/init.d/network.sh

    # load zlg_fs

    insmod /bin/zlg_fs.ko

    insmod /bin/zlg_ffs.ko

    mknod /dev/zlg_fsa b 125 0

    mknod /dev/zlg_fsa1 b 125 1

    mknod /dev/zlg_fsa2 b 125 2

    mount -t vfat /dev/zlg_fsa /usr

    mount -a

    4. 执行/etc/fstab( 挂载文件系统脚本)

    在文件 /etc/init.d/rcS 中执行 mount –a 时,就会按照文件 /etc/fstab 内容挂载相应的文件系统 .

    #device mount-point type options dump fsck order

    none /proc proc defaults 0 0

    none /dev/pts devpts mode=0622 0 0

    tmpfs /dev/shm tmpfs defaults 0 0

    (1)device : 要挂接的设备,如 /dev/hda2

    mount-point: 挂接点

    type: 文件系统类型,如 pro,jffs2,nfs

    options: 挂接参数,以逗号隔开

    dump 和 fsck order :用来决定控制 dump,fsck 程序的行为。

    5. 接着就会执行一些内核模块和网络俄配置脚本,最后执行应用程序启动等脚本,如 qtopia 的启动。

  • 相关阅读:
    Django之Admin
    反射功能:***attr
    python单例模式
    三元表达式,推导式,生成器表达式
    jquery的each()
    Django篇之F,Q
    Django的思维导图
    Models_Class 有choice,如何显示其中文
    Java并发机制(1)--线程状态与方法(转)
    Java并发机制(2)--synchronized与Lock
  • 原文地址:https://www.cnblogs.com/wi100sh/p/4206343.html
Copyright © 2020-2023  润新知