用busybox做一个简单的文件系统

本文详细介绍如何利用BusyBox创建一个精简的嵌入式Linux文件系统,包括配置、编译BusyBox,以及构建必要的文件结构和配置文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用busybox做一个简单的文件系统

1、下载BusyBox源代码包 http://busybox.net/
2、找个地方解压缩包,例如tar -xjvf busybox-1.00.tar.bz2
3、进入busybox的文件夹,使用make menuconfig进入设置
[attach]244[/attach]
4、在build options中有一些选项要注意
Build BusyBox as a static binary (no shared libs):如果选择了这个选项,那么BusyBox将被静态编译,也就是不需要动态链接库的支持就能运行,但是这样会使编译后文件的体积增大。
Do you want to build BusyBox with a Cross Compiler:如果你的busybox将要运行机器与编译主机的体系结构不同,比如s3c2410是ARM,与我们的X86主机芯片系统结构不一样,那么这个一定要选上,并且在 Cross Compiler prefix中写上交叉编译器的名字,比如ARM用arm-linux-
[attach]245[/attach]
5、在Installation Options中 BusyBox installation prefix就是在编译完后运行make install 时,busybox将被安装的地址。
[attach]246[/attach]
6、其它的选项按照默认选项就行,当然自己也可以看看有没有需要,把其它一些命令加入到编译选项中来
7、完成后保存,然后运行make
8、编译没有问题后运行make install这样编译好的busybox就会自动安装到BusyBox installation prefix中,一般是三个文件夹bin sbin usr和一个文件linuxrc。这样busybox的编译就完成了
9、准备一个空文件夹将BusyBox installation prefix中的东西拷过来,另外再建几个linux需要的文件夹
lib
dev
etc
home
proc
root
tmp
var
mnt
10、在etc文件夹下建一个目录init.d,并且在其中建立一个空文件rcS,在rcS中加上以下内容
#! /bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel

#
#       Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
#
trap ":" INT QUIT TSTP

/bin/mount -t proc none /proc
11、如果你的busybox是静态编译的,那么一个简单的能使用的根文件系统就这样完成了,但是这个文件系统中没有glibc的动态链接库,除了busybox以外的软件,如果对glibc有依赖,但是又没有静态编译的的话就无法运行。但如果所有的软件都用静态编译的话,那这个文件系统将很大。所以一般推荐软件不要使用静态编译,而使用一个库。
12、如果你不是用静态编译的,那么你需要编译好的glibc的动态链接库。在一般的交叉编译器中都带有已经编译好的库,直接拷过来就行了。一般在交叉编译器的lib或arm-linux/lib中

2编译busybox
        2004年10月中旬,busybox的1.00稳定版终于推出了,完整的源代码可以从http://www.busybox.net下载,压缩包大小为1.3 MB左右。将源码解压之后,进入到busybox1.00目录中,运行make menuconfig可以打开它的编译界面。这个界面和Linux内核编译有些接近,如图1所示。
在这个菜单界面中除了可以对最终编译到可执行文件中的命令进行选择外,还有很多其他设置也是非常重要的。下面三个目录是很多人都会感兴趣的:

Build Options --->
Installation Options --->
Login/Password Management Utilities --->

        在Build Options里面有是否使用交叉编译的选项(Do you want to build BusyBox with a Cross Compiler)。如果要对其他平台进行编译就要选择它并设置相应的编译程序前缀。
        在Installation Options里面可以设置安装的路径,即设置为新文件系统的根目录。当然也可以用缺省的 _install目录,安装之后再复制到新文件系统中去。
        在设置Login/Password Management Utilities的时候,为了免去配置glibc的麻烦,最好设置使用busybox自己的password和shadow文件的功能(Use internal password and group functions rather than system functions)。
        busybox提供的命令无疑比较全面,但它的缺省配置还不能构成一个功能比较完备的文件系统。必须要添加的命令有Login/Password Management Utilities里面的getty、login和passwd,这些命令从前是由另外一个软件包tinylogin所提供的。当然,如果不需要一个交互的登录界面,这些命令也可以去掉。通过设定内核参数init=/bin/sh可以在系统启图1busybox的编译配置界面动后直接得到一个shell。
         tlenetd命令是一个远程登录服务程序,把它编译进busybox中会为将来的调试提供很多的方便。当然也可以通过串口终端的方式管理嵌入式设备,但网络登录的方式却更为方便。
        设置完毕后保存、退出,执行make; make install命令,busybox将在未来的根文件系统中建立/usr、/bin、/sbin等目录。从中可以看到,编译好的busybox可执行文件和其他应用命令的符号链接。典型的busybox文件大小在动态链接的情况下是300 KB左右,静态链接为800 KB左右,用它实现的文件系统完全可以控制在1 MB以下。但就目前为止,得到的还不是一个完整可用的文件系统,必须要在这个基础上添加一些必要的文件,让它可以工作。


3完善文件系统
3.1需要增加的文件
        参考一个正常的Linux系统就会发现,busybox建立的文件系统还缺少很多文件。下面三行命令建立了常见UNIX系统中包含的一些目录,虽然它们不全是必需的,但建立它们更符合标准一些。这些命令都是在新文件系统的根目录中执行的,第三条命令的执行还必须要有root权限。

mkdir mnt root var tmp proc boot etc lib
mkdir /var/{lock,log,mail,run,spool}
chown 0:0R *

如果busybox采用了动态链接的方式编译,还需要把busybox所需要的动态库:libcrypt.so.1、libc.so.6、ldlinux.so.2放到lib目录中。最好按照标准的方式建立相应的文件和链接,可以参考下面的列表:

-rwxrwxrwx 192519ld-2.3.2.so
lrwxrwxrwx 111ld-linux.so.2 -> ld-2.3.2.so
-rwxrwxrwx 1 1190032libc-2.3.2.so
lrwxrwxrwx 113libc.so.6 -> libc-2.3.2.so
-rwxr-xr-x 118348libcrypt-2.3.2.so
lrwxrwxrwx 117libcrypt.so.1 -> libcrypt-2.3.2.so

3.2编写 etc文件夹下的文件
        etc文件夹是许多系统配置文件保存的地方。这些文件非常重要,如果配置错误,就可能影响系统的启动。busybox源代码example/bootfloopy/etc目录中的文件算是一个简单的例子,可以把其中的文件拷贝过来作为基础。(在example/bootfloopy目录中的一些脚本和文档也很值得阅读)
        首先inittab文件是系统启动后所访问的第一个脚本文件,后续启动的文件都由它指定。这个文件的格式和普通微机Linux上的inittab是有区别的,其具体含义可以参考busybox的文档。下面是一个比较简单的例子:

::sysinit:/etc/init.d/rcS
tty0::respawn:/sbin/getty 38400 tty0
tty2::askfirst:/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount ar
::shutdown:/bin/mount / o remount,ro

       其中第一行指定了系统的启动脚本为/etc/init.d/rcS;第二行指定在第一个虚拟终端打开一个登录会话;第三行指定在第三个虚拟终端打开一个无须登录验证的shell;第四行指定了当按下ctrl+alt+del组合键时的执行命令;最后两行指定了关机时执行的操作。
fstab文件定义了文件系统的各个“挂接点”,需要与实际的系统相配合。一个简单的fstab文件如下:proc/procprocdefaults00
/dev/hda1/ext2rw,noauto01
devpts/dev/ptsdevptsdefaults00

其中第三行是为UNIX PTYs准备的,telnetd要用到。
profile文件是终端登录之后首先运行的脚本,这里可以不去管它。我们比较关心的是系统在无人登录的情况下有哪些程序要执行。从inittab文件可以看出系统启动之后要运行/etc/init.d/rcS脚本,需要启动的程序和需要进行的设置都可以写在这里面。一个可能的rcS文件如下:

#! /bin/sh
echo e 'Starting System'
ifconfig lo 127.0.0.1
ifconfig eth0 192.168.0.100
hostname F /etc/hostname
/bin/mount / o remount,rw
/bin/mount /proc
/bin/mount /dev/pts
/usr/sbin/telnetd
dmesg > /var/log/dmesg

为了满足终端登录用户验证的要求,etc目录下还需要有passwd、group和shadow (在编译busybox时如果不选择shadow功能将不需要这个文件)。这些文件至少要包含 root用户的定义,如下所示:

passwd:
root:x:0:0:root:/root:/bin/sh
group:
root:x:0:
shadow:
root::12179:0:99999:7:::

其中,如果shadow (对于不支持shadow的系统则是passwd )文件的第一个冒号和第二个冒号之间没有内容,表示这个用户登录不需要密码。如果需要设定密码或者增加新的登录用户,就可以参考开发主机上的相应文件,或者在目标系统启动之后用passwd命令和adduser命令完成。
        最后还可以给目标机起一个名字,在/etc目录下建立文件hostname,将起好的名字写到里面。前面介绍的启动脚本rcS,通过hostname命令把文件的内容设置为机器名。


4测试新的文件系统
        文件系统的安装随着应用环境的不同差别比较大。在嵌入式环境中,一般只要通过特殊的打包工具将文件系统打包,并烧录到非易失性存储器中就可以了。例如,对于JFFS2类型的文件系统就可以用mkfs.jffs2命令生成文件系统的映像。
        文件系统安装之后重新启动目标设备,应该就可以使用新建立的文件系统了。如果系统启动失败,则可以通过内核消息查找错误的原因。如果错误信息提示不能正确挂载文件系统,问题可能出在启动引导装载程序(bootloader)上。文件系统比较容易出问题的是用户的验证和动态链接库的加载。最简单的检测办法是把busybox编译为静态链接并设置内核参数init=/bin/sh来躲开对用户登录的验证。


首先将下载的 busybox-1.1.3-tar.bz2 解压到一个目录中,然后在里面运行以下的命令,对源代码进行配置:

[root@redhat9 busybox-1.1.3]# make menuconfig

相信有过编译内核经验的人对这个界面应该很熟悉,在这个莱单里可以对 BusyBox 的编译方式进行选择,例如是静态编译还是动态编译,是使用 glibc 还是 uClibc 等;也可以选择你所需要的 applet。

如果你的操作系统是 Red Hat Linux 9.0 那么有两个问题你需要注意一下:

不要选择使用 Support NSA Security Enhanced Linux;
如果选择了 Linux Ext2 FS Progs 下的任何一个 applet,那么就必须更新你的 make,make-3.81 可以是一个选择。

完成配置后,接下来就容易了:

[root@redhat9 busybox-1.1.3]# make dep
[root@redhat9 busybox-1.1.3]# make
[root@redhat9 busybox-1.1.3]# make install

正常编译完成后,在当前源代码目录下会生成一个 _install 子目录,里面包含编译好的 busybox 和一些指向它的符号连接。

 

3 使用说明
调用 BusyBox 中的 applet 有三种方法(以 ls 命令为例):

给 busybox 带参数 busybox ls
硬连接 ln busybox ls
ls 
符号连接 ln -s busybox ls
ls 

第三种是最常用的方法,因为在 _install 目录中就已经做好了全部的符号连接。

有了 busybox 及其符号连接之后,还需要做一些附加工作才能将 BusyBox 作为操作系统使用:

基本目录:除了 _install 中已经有的 bin sbin 两个目录外,还需要建立以下目录,注意 tmp 的权限为 777,root 权限为 750

dev
dev/pts
dev/shm
etc
etc/init.d
lib
proc
tmp
var
root

设备文件:可以从你正在使用的系统中直接复制,至少需要

/dev/console
/dev/fd
/dev/fd0
/dev/fd0H1440
/dev/hd?
/dev/hd??
/dev/kmem
/dev/null
/dev/zero
/dev/tty
/dev/tty?

共享库支持:如果你的 busybox 为动态编译,则需要

/lib/libc.so.6

不论是动态编译还是静态,如果要做 DNS 解析,就一定需要

/lib/libnss_dns.so.2
/lib/libnss_files.so.2
/lib/libresolv.so.2
/etc/resolv.conf

resolv.conf 根据具体环境修改。同时,只要使用了共享库,就需要

/lib/ld-linux.so.2
/sbin/ldconfig
/etc/ld.so.conf

ld.so.conf 根据具体环境修改。注意:我这里给出的共享库文件名可能只是符号连接,一定要同时拷贝原始文件。另外,如果你使用的是 uClibc,那么请参考相应文档。


配置文件:至少需要下表文件:

/etc/protocols
/etc/services 这两文件可以直接从当前系统中复制
/etc/host 去掉不必要条目,但最少要保留“127.0.0.1 localhost”
/etc/passwd
/etc/shadow  去掉多余的用户信息,保留root和系统用户名,注意修改 shadow 之前要先给它可写权限
/etc/fstab 去掉多余的 mount 点,但至少保留以下条目:

/dev/hda1 / ext2 defaults 1 1
none /dev/pts devpts gid=5,mode=620 0 0
none /proc proc defaults 0 0
none /dev/shm tmpfs defaults 0 0

注意第一行,这里指定将 /dev/hda1 作为根目录 /,你可以根据自己的实际需求更改
 
/etc/mtab mount 点信息,让它为空
/etc/resolv.conf 配置 DNS 解析,这里给出一个例子:

nameserver 202.103.0.117
search localdomai
 
/etc/ld.so.conf 包含共享库的目录列表,可以为空
etc/inittab 不要使用标准的 inittab,因为它和 BusyBox 的 init 不兼容。在 BusyBox 源代码目录中有一个 inittab 的样本,可以在它的基础之上修改。可修改的项目有:登录方式,启动脚本 rcS 的位置,指定关机脚本等。可以不使用这个文件
etc/init.d/rcS 这是 BusyBox 系统特有的启动脚本。BusyBox 使用的 init 是没有运行级别之分的,默认情况下,它在启动之后,会先调用 /etc/init.d/rcS,然后等待登录。所以我们可以在这个脚本中做一些初始化工作。这里给出一个简单的例子,注意要给它可执行权限:

#!/bin/sh


/bin/mount /proc
/bin/mount -o remount,rw /
/bin/mount -a

ifconfig lo 127.0.0.1 broadcast 127.255.255.255 netmask 255.0.0.0
ifconfig lo up
route add -net 127.0.0.0 netmask 255.0.0.0 dev lo
 
etc/busybox.conf 设置 user ID,如果在编译 BusyBox 时没有选择“Support for SUID/SGID handling”,则可以不使用这个文件。在设置 busybox.conf 的同时,还要给 bin/busybox 加上“s”属性,下面是 busybox.conf 的一个例子:

# /etc/busybox.conf

[SUID]
su = sx- root.500

将上述所有的东西,包括 busybox 及其符号连接、基本目录、设备文件、配置文件以及可能需要的共享库及相关文件等等,全部按其应有的位置做到一个目录(如 _install)中备用,接下来是做成 initrd 还是微型的 Linux 启动盘,甚至是用于嵌入式系统中,就看各自的需求了。

<think>好的,用户现在想了解如何使用BusyBox创建一个文件系统。我需要先回顾之前的对话历史。之前用户遇到了编译BusyBox时的错误,涉及内核头文件版本的问题,我给出了解决方案。现在用户的问题转向如何创建根文件系统,这可能是在解决编译问题之后的下一个步骤。 首先,用户可能是嵌入式系统开发者或正在学习Linux系统构建,他们需要构建一个最小化的根文件系统,用于嵌入式设备或测试环境。用户的真实需求可能不仅仅是步骤,还包括理解每个步骤的作用,以及如何验证文件系统的正确性。 我需要确保回答结构清晰,分步骤讲解,同时覆盖必要的目录结构、配置文件、权限设置等。还要注意用户可能对某些步骤不熟悉,比如交叉编译或设备节点的创建,需要详细说明。 可能需要注意的要点包括: 1. 准备工作:交叉编译工具链、内核模块、BusyBox的编译配置。 2. 目录结构的创建,遵循FHS标准。 3. 安装BusyBox到目标目录,创建必要的符号链接。 4. 配置关键的系统文件如inittab、fstab、passwd等。 5. 设置权限,特别是/dev和/proc等特殊目录。 6. 测试和打包文件系统,可能使用chroot或QEMU测试。 需要检查是否遗漏了某些关键步骤,比如动态库的拷贝,或者如何处理静态编译的情况。同时,用户可能需要了解如何配置启动脚本,比如rcS文件,以及如何设置环境变量。 另外,用户可能对如何交叉编译BusyBox有疑问,特别是如果目标平台与宿主机架构不同,需要指定正确的交叉编译选项。此外,可能还需要说明如何生成initramfs或者如何制作可引导的镜像文件。 最后,应该给出验证方法,比如使用QEMU启动测试,或者打包成镜像文件并用虚拟机加载。同时提醒用户注意权限问题,避免因权限不当导致的启动失败。</think>使用BusyBox创建根文件系统是嵌入式Linux开发的常见需求,以下是详细操作指南: --- ### **一、准备工作** ```bash # 创建基础目录结构(需root权限) mkdir rootfs && cd rootfs mkdir -pv bin dev etc home lib mnt opt proc root run sbin sys tmp usr var mkdir -p usr/bin usr/sbin usr/lib usr/include ``` --- ### **二、编译BusyBox** 1. **获取源码**(以v1.36.1为例): ```bash wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2 tar -xf busybox-1.36.1.tar.bz2 && cd busybox-1.36.1 ``` 2. **配置编译选项**: ```bash make menuconfig ``` 关键配置: ``` -> Settings -> Build static binary (no shared libs) [根据需求选择] -> Linux System Utilities -> Support mounting /dev [*] -> Support mounting /proc [*] -> Coreutils -> cpio [*] ``` 3. **交叉编译示例**(ARM架构): ```bash make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- install ``` --- ### **三、安装到根文件系统** 1. **复制二进制文件**: ```bash # 假设当前在busybox源码目录 make CONFIG_PREFIX=../rootfs install ``` 2. **验证安装**: ```bash ls ../rootfs/bin/busybox # 应显示二进制文件 ``` --- ### **四、配置关键系统文件 1. **/etc/inittab**(基础配置): ```bash echo "::sysinit:/etc/init.d/rcS ::respawn:/sbin/getty -L ttyS0 115200 vt100 ::ctrlaltdel:/sbin/reboot" > ../rootfs/etc/inittab ``` 2. **/etc/fstab**(文件系统挂载): ```bash cat << EOF > ../rootfs/etc/fstab proc /proc proc defaults 0 0 tmpfs /tmp tmpfs defaults 0 0 EOF ``` 3. **初始化脚本**: ```bash mkdir -p ../rootfs/etc/init.d echo "#!/bin/sh mount -a echo 'Hello from BusyBox'" > ../rootfs/etc/init.d/rcS chmod +x ../rootfs/etc/init.d/rcS ``` --- ### **五、添加必要设备节点** ```bash sudo mknod ../rootfs/dev/console c 5 1 sudo mknod ../rootfs/dev/null c 1 3 sudo chmod 666 ../rootfs/dev/null ``` --- ### **六、补充依赖库(动态编译时)** ```bash # 以ARM架构为例 cp /usr/arm-linux-gnueabihf/lib/libc.so.6 ../rootfs/lib/ cp /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3 ../rootfs/lib/ ``` --- ### **七、测试文件系统** 1. **使用QEMU测试**: ```bash qemu-system-arm -M versatilepb -kernel zImage -dtb versatile-pb.dtb \ -initrd rootfs.cpio -append "root=/dev/ram0 console=ttyAMA0" ``` 2. **打包成CPIO格式**: ```bash cd rootfs find . | cpio -H newc -ov --owner root:root > ../rootfs.cpio ``` --- ### **常见问题处理** 1. **权限问题**: ```bash chown -R root:root rootfs chmod 4755 rootfs/bin/busybox ``` 2. **缺少动态库**: ```bash # 使用ldd检查依赖 arm-linux-gnueabihf-ldd rootfs/bin/busybox ``` --- ### **扩展功能建议** ```bash # 添加基础工具 mkdir rootfs/usr/share/udhcpc cp examples/udhcp/simple.script rootfs/usr/share/udhcpc/default.script ``` 通过以上步骤,您将获得一个约3-5MB的最小根文件系统,可通过`initramfs`或直接挂载到嵌入式设备使用。建议根据实际需求添加`/etc/passwd`, `/etc/group`等配置文件以完善系统功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值