busybox源码包官网下载 busybox官网开发者手册
下载完成后,解压得到如下图所示目录:
busybox 与 内核源码、u-boot源码配置类似,也存在默认配置,在configs目录下面,但因为其配置比较简单,一般没采用默认配置.(思考:如何添加自定义的配置到configs目录使其能make xx_defconfig)
$ make help //可以查看make 实现哪些功能
指定ARCH 、CROSS_COMPILE 、SYSROOT
示例:
$ export ARCH = powerpc
$ export CROSS_COMPILE = powerpc-fsl-linux-gnuspe-
若 没设置CROSS_COMPILE变量,则需要在Busybox Settings-->Build Options --> Cross Compiler prefix 填写 编译器的前缀
关于SYSROOT
CONFIG_SYSROOT: |
| |
| If you want to build BusyBox with a cross compiler, then you |
| might also need to specify where /usr/include and /usr/lib |
| will be found. |
| |
| For example, BusyBox can be built against an installed |
| Android NDK, platform version 9, for ARM ABI with |
| |
| CONFIG_SYSROOT=/opt/android-ndk/platforms/android-9/arch-arm |
| |
| Native builds leave this empty. |
| |
| Symbol: SYSROOT [=] |
| Prompt: Path to sysroot |
| Defined at Config.in:632 |
| Location: |
| -> Busybox Settings |
| -> Build Options
若使用交叉编译器不设置此选项,则可能出现如下问题
以上基本配置完成后,make menuconfig 根据需要配置 (一般不用配置)
需要注意的就几个点:
1.BusyBox installation prefix 选项 ,执行make install时安装的目录,默认设置为当前源码目录的_install
2.使用vi风格时 busybox setting->busybox library tuning下的下面两个开关打开。第一个是选择vi风格的命令行。
3. 选中 Build BusyBox as a static binary 可以减少根文件系统空间 ,这样它自身不需使用动态库
4.需要注意Linux Module Utilities 和 Linux System Utilities
执行make
执行make install
设置uboot bootargs启动参数
bootargs=root=/dev/nfs nfsroot=192.168.1.141:/root/rootfs/
ip=192.168.16.88:192.168.16.106:192.168.16.1:255.255.255.0::eth1:off
init=/linuxrc console=ttyS0,115200
此时会因为找不到/etc/init.d/rcS (第一个执行的脚本) 以及终端设备/dev/tty2等设备无法进入命令行
注意时,/etc/inittab是busybox第一个解析的配置文件,当找不到时会使用默认配置,所以当根文件系统缺少/etc/inittab时也不会出现 can't open /etc/inittab的信息。
下面开始一步一步补充根文件系统缺少的文件和目录
1.创建etc目录,新建inittab文件
简单介绍inittab,详细后面博客补充
inittab内容以行为单位,行与行之间没有关联,每行都是一个独立的配置项,每一个配置项表示一个独立的意思
runlevel也是一个shell变量,并且导出为环境变量
runlevel变量的作用:Linux操作系统自从开始启动至启动完毕需要经历几个不同的阶段,这几个阶段就叫做runlevel,同样,当linux操作系统关闭时也要经历另外几个不同的runlevel。设置runlevel,是为了linux系统避免不必要的重启动。
Linux系统有7个运行级别(runlevel)
运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动
运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登陆
运行级别2:多用户状态(没有NFS)
运行级别3:完全的多用户状态(有NFS),登陆后进入控制台命令行模式
运行级别4:系统未使用,保留
运行级别5:X11控制台,登陆后进入图形GUI模式
运行级别6:系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动
S, s Single user mode
runlevel=s,表示将系统设置为单用户模式
上面标红比较常用,需要注意的是:
askfirst,它的含义与respawn相同,只是在运行process前,会打出一句话 "please press Enter to active this console",然后等用户在终端上敲入回车键后才运行process。
sysinit :为init提供初始化命令行的路径 <一般在inittab为si::sysinit:/etc/init.d/rcS 表示执行/etc/int.d目录下rcS脚本>
si 是系统初始化的进程,该字段可以不写,当写si时,实践中出现了can't open /dev/si: No such file or directory,目前还不太清楚与什么有联系
下面为成熟的文件系统中的实现:
respawn:每当相应的进程终止执行便重新启动
wait: 告诉init必须等到相应的进程完成才能继续执行
shutdown:当系统关机时,执行相应的进程
restart:当init重新启动时,执行相应的进程。
once:仅执行相应的进程一次,而且不会等待它完成
ctrlaltdel:当按下Ctrl-Alt-Delete组合键时,执行相应的进程
#first: run the system script file
#控制台在启动之前,执行/etc/init.d/rcS程序
::sysinit:/etc/init.d/rcS
#控制台启动时,执行/bin/sh程序。若没有执行类似登录,则无法出现交互终端
::askfirst:-/bin/sh
#按下ctrl+alt+del,执行/bin/reboot程序
::ctrlaltdel:-/bin/reboot
#关机时,执行/bin/umount程序,并传入两个参数, -a –r
::shutdown:/bin/umount -a -r
#重启,执行/sbin/init程序
::restart:/sbin/init
再次启动根文件系统会出现can't run '/etc/init.d/rcS': No such file or directory
2.创建rcS文文件,且需要加入执行权限
再次启动,可以发现能基本出现交互终端
3.继续深入的验证,思考下面问题
1)如何让串口终端登录 以及登录时密码与账户如何验证的
屏蔽/bin/sh ,加入ttyS0:12345:respawn:/sbin/getty -L 115200 ttyS0
说明:一般情况下上面ttyS0应该只需要写S0,也就是tty的尾缀,但本文完成最终实验时,发现启动时若采用S0还是会出现
can't open /dev/S0: No such file or directory,待分析成熟文件系统中如何实现的
#first: run the system script file
#控制台在启动之前,执行/etc/init.d/rcS程序
::sysinit:/etc/init.d/rcS
#控制台启动时,执行/bin/sh程序。若没有执行类似登录,则无法出现交互终端
#::askfirst:-/bin/sh
ttyS0:12345:respawn:/sbin/getty -L 115200 ttyS0
#按下ctrl+alt+del,执行/bin/reboot程序
::ctrlaltdel:-/bin/reboot
#关机时,执行/bin/umount程序,并传入两个参数, -a –r
::shutdown:/bin/umount -a -r
#重启,执行/sbin/init程序
::restart:/sbin/init
完成上面后,启动时,也会出现can't open /dev/ttyS0: No such file or directory,这是因为系统此时还没有在/dev 创建对应的设备文件
2)创建dev目录后,怎么让dev目录看见对应的设备
现在系统大部分设备节点都是由mdev或者udev根据驱动实现自动创建的,所以只需要让脚本执行mdev或者udev相关的操作即可
此时在/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/hostname
上面分为4个部分:
(a)导出坏境变量
定义PATH变量,后面用export导出,那PATH就变成了环境变量。
PATH环境变量是linux系统内部定义的一个环境变量,含义是操作系统去执行程序时会默认到PATH指定的各个目录下去寻找。如果找不到就认定这个程序不存在,如果找到了就去执行它。将一个可执行程序的目录导出到PATH,可以让我们不带路径来执行这个程序。
rcS文件还没添加,系统启动就有了PATH的值?原因在于busybox自己用代码硬编码为我们导出了一些环境变量,其中就有PATH。
在busybox的init.c的init_main函数中,有以下几行代码,设置了几个环境变量,其中就有PATH。
/* Make sure environs is set to something sane */
putenv((char *) "HOME=/");
putenv((char *) bb_PATH_root_path);
putenv((char *) "SHELL=/bin/sh");
putenv((char *) "USER=root"); /* needed? why? */
在libbb.h中,有定义bb_PAYH_root_path,其实就是/bin /sbin /usr/bin /usr/sbin
extern const char bb_PATH_root_path[] ALIGN1; /* "PATH=/sbin:/usr/sbin:/bin:/usr/bin" */
(b)挂载根文件系统 mount -a
mount命令是用来挂载文件系统的。
mount –a是挂在所有的应该被挂载的文件系统,在busybox中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).
#
#
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/udev 需要挂载 tmpfs - /dev proc-/proc sysyfs - /sys 不然都无法成功创建设备
编辑完/etc/fstab后,还需手动创建proc sys dev 目录
下面为没挂载tmpfs到/dev时,出现的问题
(c) mdev
mdev是udev的嵌入式简化版本,udev/mdev是用来配合linux驱动工作的一个应用层的软件,udev/mdev的工作就是配合linux驱动生成相应的/dev目录下的设备文件。
本来,在dev目录下,是空目录。但是当rcS文件中,添加下面两行,配合上面的文件系统挂载,
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
在dev目录下,就会生成很多设备文件。这些设备文件,就是mdev生成的。
配置完成后,串口登录时出现下面输入密码的提示,此时因为没有对应/etc/passwd,则无法登录
关于系统密码登录这块的介绍:
inux的账号验证程序是login,login会接收getty传来的用户名作为用户名参数。
然后login会对用户名进行分析:如果用户名不是root,且存在/etc/nologin文件,
login将输出nologin文件的内容,然后退出。这通常用来系统维护时防止非root用户登录。
只有/etc/securetty中登记了的终端才允许root用户登录,如果不存在这个文件,则root可以
在任何终端上登录。/etc/usertty文件用于对用户作出附加访问限制,如果不存在这个文件,则没有其他限制。
在分析完用户名后,login将搜索/etc/passwd以及/etc/shadow来验证密码以及设置账户的其它信息,
比如:主目录是什么、使用何种shell。如果没有指定主目录,将默认为根目录;如果没有指定shell,
将默认为/bin/bash。
login程序成功后,会向对应的终端在输出最近一次登录的信息(在/var/log/lastlog中有记录)
并检查用户是否有新邮件(在/usr/spool/mail/的对应用户名目录下)。
然后开始设置各种环境变量:
对于bash来说,系统首先寻找/etc/profile脚本文件,并执行它;然后如果用户的主目录中存在.bash_profile文件,
就执行它,在这些文件中又可能调用了其它配置文件,所有的配置文件执行后后,
各种环境变量也设好了,这时会出现大家熟悉的命令行提示符,到此整个启动过程就结束了。
创建/etc/passwd文件,添加下面内容即可
root::0:0:root:/home/root:/bin/sh
当我换成root:x:0:0:root:/home/root:/bin/sh时,登录居然需要密码,后面待验证,感觉和busybox vi编辑模式相关
(d)hostname
hostname是linux中的一个shell命令。命令(hostname xxx)执行后可以用来设置当前系统的主机名为xxx,直接hostname不加参数可以显示当前系统的主机名。
设置了主机名,就可以在命令行中,显示主机名。
没有设置主机名的时候,使用hostname命令,会打印当前的IP地址。
新建/etc/hostname 且写入自定义的hostname
3)如何修改根文件系统的提示符
请参考根文件系统的提示符
/etc/inittab文件详解
busybox根文件系统构建