根文件系统——busybox

时间:2024-03-04 18:00:12

---恢复内容开始--

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中,启动内核并挂载