zoukankan      html  css  js  c++  java
  • 根文件系统——busybox

    ---恢复内容开始--

    http://blog.csdn.net/zn2857/article/details/52832778-

    1:busybox就是linuxrc文件,首先下载busybox源码

    各个版本busybox的下载地址,下载版本为busybox-1.22.1.tar.bz2

    http://linux.linuxidc.com/index.php?folder=cHViL0J1c3lib3g=

    在linux下用tar -jxvf 来解压busybox

    make distclean

    make menuconfig

    对busybox进行配置:

    Busybox Settings--->
    Build Options--->
    [*]Build BusyBox as a static binary(no shared libs)


    Busybox Library Tuning--->
    [*]vi-style line editing commands
    [*]Fancy shell prompts


    Linux Module Utilities--->
    [ ]Simplified modutils
    [*]insmod
    [*]rmmod
    [*]lsmod
    [*]modprobe
    [*]depmod


    Linux System Utilities--->[*]mdev
    [*]Support /etc/mdev.conf
    [*]Support subdirs/symlinks
    [*]Support regular expressions substitutions when renaming dev
    [*]Support command execution at device addition/removal
    [*]Support loading of firmwares

    按照上面配置对busybox进行配置,

    保存,然后make

    在根目录下面看到busybox则编译成功;

    安装 

    make install之前首先设置安装目录,注意这里千万要注意不能随便安装,安装目录不能是我们ubuntu虚拟机的根目录,因为这样会把我们的虚拟机下的文件覆盖掉

    busybox setting——》

      install setting——》

        在这里设置安装目录,我们设置为上一节设置好的根文件系统的rootfs文件夹下:

     然后make install 

    现在打开/usr/bhc/rootfs/rootfs文件夹下面我们看到以下文件就说明安装成功了

    用ls -l命令我们可以看到bin以及sbin目录下的所有的文件都是bin/busybox的符号链接,以及usr目录下的bin sbin也都是busybox的符号链接;

    实际上是busybox首先运行一些配置文件,进行一些配置,然后进入命令行,解析并执行一系列命令,生成字进程等;

    2:下面把我们制作好的nfs在开发板上做实验:

    这里注意:记得设置uboot中的bootargs参数

    setenv bootargs root=/dev/nfs nfsroot=192.168.1.30:/usr/bhc/rootfs/rootfs ip=192.168.1.11:192.168.1.30:192.168.1.1:255.255.255.0::eth0:off  init=/linuxrc console=ttySAC2,115200 

     这里注意eth0是开发板的网卡,而不是虚拟机的网卡,所以如果你的虚拟机中是ens33的话也要设置为eth0;

    3:配置文件解析

    我们知道linux内核在启动以后,执行了一个init函数,这个函数就是执行的第一应用程序,在这里init函数就是我们编译的linuxrc;

    init始终是第一个进程,其PID始终为1(ps -aux | less),它是系统所有进程的父进程,然后init进行开始执行配置文件/etc/inittab

    下面我们看一下一个简单的inittab文件的内容分析一下格式:

     

    /etc/inittab文件中,每个项的结构都是一样,以冒号:分隔4个字段。

    indentifier:run_level:action:process

    id:它是每个登记项的标识符,用于唯一标识每个登记项,不能重复 

     runlevels:系统的运行级别,表示process的action要在哪个级别下运行,该段中可以定义多个运行级别,各级别之间直接写不用分隔符;如果为空,表示在所有的运行级别运行。Linux的运行级别有:
        0:表示关机
        1:表示单用户模式,在这个模式中,用户登录不需要密码,默认网卡驱动是不被加载,一些服务不能用。
        2:表示多用户模式,NFS服务不开启
        3,表示命令行模式
        4,这个模式保留未用
        5,表示图形用户模式
        6,表示重启系统 
     
      action:表示对应登记项的process在一定条件下所要执行的动作。
        具体动作有:
        respawn:当process终止后马上启动一个新的
        wait:当进入指定的runlevels后process才会启动一次,并且到离开这个runlevels终止
        initdefault:设定默认的运行级别,即我们开机之后默认进入的运行级别,不能是0,6,你懂的
        sysinit:系统初始化,只有系统开机或重新启动的时候,这个process才会被执行一次
        powerwait:当init接收到电源失败信号的时候执行相应的process,并且如果init有进程在运行,会等待这个进程完成之后,再执行相应的process
        powerfail:当init接收到电源失败信号的时候执行相应的process,并且如果init有进程在运行,不会等待这个进程完成,它会直接执行相应的process
        powerokwait:电源已经故障,但是在等待执行对应操作的时候突然来电了就执行对应的process
        powerfailnow:当电源故障并且init被通知UPS电源已经快耗尽执行相对应的process
        ctrlaltdel:当用户按下ctrl+alt+del这个组合键的时候执行对应的process
        boot:只有在引导过程中,才执行该进程,但不等待该进程的结束;当该进程死亡时,也不重新启动该进程
        bootwait:只有在引导过程中,才执行该进程,并等待进程的结束;当该进程死亡时,也不重新启动该进程
        off:如果process正在运行,那么就发出一个警告信号,等待20秒后,再通过杀死信号强行终止该process。如果process并不存在那么就忽略该登记项
        once:启动相应的进程,但不等待该进程结束便继续处理/etc/inittab文件中的下一个登记项;当该进程死亡时,init也不重新启动该进程

      process:表示启动哪个程序或脚本或执行哪个命令等

    #first:run the system script file
    ::sysinit:/etc/init.d/rcS
    ::askfirst:-/bin/sh
    ::ctrlaltdel:-/sbin/reboot
    #umount all filesystem
    ::shutdown:/bin/umount -a -r
    #restart init process
    ::restart:/sbin/init

    对上面这段inittab进行分析:

    #表示注释,

    id与runlevel都为空 

    ::sysinit:/etc/init.d/rcs 这段表示只有在开机或者重启的情况下执行 /etc/init.d/rcs这个脚本,一会看一下这个脚本都做了些什么;

    ::askfirst:-/bin/sh 这句其实是用来执行命令行的,但是action为askfirst,askfirst的作用就是先进行提示,按下回撤在进入控制台;

    我们把askfirst修改为respawn就不会再有这个提示了;

    实验结果是没有这个提示,直接进入了命令行下面;

    ::ctrlaltdel:-/sbin/reboot 按下 ctrl+alt+del执行/sbin/reboot重启

    ::shutdown:/bin/umount -a -r 关机时执行 取消挂载

    ::restart:/sbin/init重启的时候执行 ,其实就是执行linuxrc即busybox

    下面来分析一下/etc/init.d/rcs

    #!/bin/sh
    PATH=/sbin:/bin:/usr/sbin:/usr/bin
    
    runlevel=S
    prevlevel=N
    
    umask 022
    
    export PATH runlevel prevlevel
    
    mount -a
    
    echo /sbin/mdev > /proc/sys/kernel/hotplug
    mdev -s
    
    /bin/hostname -F /etc/sysconfig/HOSTNAME
    
    ifconfig eth0 192.168.1.10

    导出环境变量PATH,设置路径;

    设置runlevel为single模式,单用户模式

    umask 022 是用来设置文件权限

    export导出三个环境变量;

    mount -a 是用来挂载的busybox执行这个命令时/etc/fstab文件,

    # /etc/fstab: static file system information.
    #
    # Use 'vol_id --uuid' to print the universally unique identifier for a
    # device; this may be used with UUID= as a more robust way to name devices
    # that works even if disks are added and removed. See fstab(5).
    #
    #     <file system>     <mount point>     <type>     <options>     <dump>     <pass>
        proc             /proc             proc     defaults     0         0
        sysfs             /sys             sysfs     defaults     0         0
        tmpfs             /var             tmpfs     defaults     0         0
        tmpfs             /tmp             tmpfs     defaults     0         0
        tmpfs             /dev             tmpfs     defaults     0         0

    在挂载这些虚拟文件之前我们首先要在根文件系统文件夹中,创建这些文件夹;

    mdev 是驱动相关;

    ifconfig eth0 192.168.1.11 设置ip地址,这个也可以没有,因为在uboot中bootargs中会传参给kernel设置好IP地址;

    /bin/hostname -F /etc/sysconfig/HOSTNAME 是用来设置主机名的

    设置方法可以在/etcsysconfig目录下创建HOSTNAME这个文件 内容为你要的主机名;

    下面我们来做实验:

    启动开发板-》在uboot中tftp下载kernel下载根文件系统提示:、

    然后更改rcs的权限chmod 777 rcS

    在执行ok 

    cd proc文件下:ls,发现有内容说明挂载成功了;

    hostname测试:设置好文件以后,在命令行下输入hostname 则显示你输入的信息;

    profile文件:linux下profile文件解释可以看http://blog.sina.com.cn/s/blog_4aecb6260100vyz3.html 

    # Ash profile
    # vim: syntax=sh
    
    # No core files by default
    ulimit -S -c 0 > /dev/null 2>&1
    
    USER="`id -un`"
    LOGNAME=$USER
    PS1='[u@h W]# '
    PATH=$PATH
    
    HOSTNAME=`/bin/hostname`
    
    export USER LOGNAME PS1 PATH

    这样我们在/etc/sysconfig/hostname中设置的主机名才会生效;

    接下来我们要设置用户登录,用户名的管理以及密码的管理

    修改inittab文件:

    加入一句

    ::sysinit:/bin/login

    这里我们首先需要设置一下用户名和密码:

    我们首先来看一下/etc/passwd文件: root用户

    之后是root用户的主目录以及所用的脚本;密码在shadow文件下,shadow文件是用来管理密码的,使用的密文来管理的;

     我们直接复制etc/passwd、etc/shadow复制过来;

    把passwd文件中剩下root这一行;

    shadow中剩下root这一行,并且把密文删掉;

    重启以后登录:直接root,然后就可以进入命令行目录离里;可以在这里修改root用户的密码:passwd root命令来修改root用户的登录密码;

    但是会提示 

    su: must be suid to work properly错误

    参考下面这个博客中修改busybox的权限为 7455就可以了 http://blog.csdn.net/water_cow/article/details/7174999

     chmod 7455 busybox

    这个错误时因为我们在登陆的时候没有指定串口,因为我们用的是串口2,

    ls dev可以看到有很多设备,s3c2410_serial2是我们用的串口

    修改inittab文件:

    s3c2410_serial2::sysinit:/bin/login

     用户登录除了/bin/login以外还有一个是/sbin/getty,这两个登陆系统在busybox中是一样的;

    更改inittab文件,

     修改为:

    s3c2410_serial2::sysinit:/sbin/getty -L s3c2410_serial2 115200 vt100

    接下来移植lib库文件:lib库文件在/usr/local/arm/arm-2009q3/arm-none-linux-gnueabi/libc/lib这个目录下面;

     

    cp lib/ /usr/bhc/rootfs/rootfs 把所有库文件复制到rootfs下即可;

    使用命令du -h lib 查看lib库文件的大小;为3.8M

    实际工作时候用arm-linux-strip *so* 去掉符号信息,发现lib库文件大小由3.8M减小到3.0M了;

    下面是开机自启动我们启动init函数以后第一个执行的是rcs文件,直接在rcs中添加要执行的文件即可;

    -------------------------

    下面制作ext2格式的根文件系统,并烧录到iNand中,启动内核并挂载

  • 相关阅读:
    学习笔记 四边形不等式的模型
    题解 AT2230【Water Distribution】
    题解 CF848C 【Goodbye Souvenir】
    第二届全国大学生算法设计与编程挑战赛(春季赛)正式赛题解&比赛回顾
    积性函数相关学习笔记
    【MySQL】数据库备份
    【SpringMVC】SSM的maven依赖
    【SpringMVC】Jackson解决乱码问题配置
    【SpringMVC】DispatcherServlet与中文过滤器配置
    【Spring】学习笔记008--AOP实现方式
  • 原文地址:https://www.cnblogs.com/biaohc/p/6551383.html
Copyright © 2011-2022 走看看