使用busybox构建完善的linux根文件系统
使用busybox构建完整的根文件系统什么是根文件系统?使用最简单的busybox构建根文件系统1.安装依赖文件2.修改busybox顶层makefile3.添加busybox中文字符的支持4.配置busybox5.编译busybox生成根文件系统6.完善根文件系统1)向 rootfs 的“/lib”目录添加库文件2)向 rootfs 的“usr/lib”目录添加库文件3)创建/etc/init.
使用busybox构建完整的根文件系统
什么是根文件系统?
在uboot引导linux内核启动之后,就需要重一个地方来启动加载初始化脚本,比如 rcS, inittab 等。这个地方就是根文件系统,这个所谓的根文件系统其实和我们win上面的c盘类似,里面有许多开机启动需要的文件,我们的linux内核需要挂载了根文件系统才能正常工作。
如图,在linux使用/来代表根文件系统,里面有很多子目录,这里我来介绍一下各个目录存放什么文件
/bin | bin 文件就是可执行文件。所以此目录下存放着系统需要的可执行文件,一般都是一些命令,比如 ls、 mv 等命令。 |
---|---|
/dev | 此目录下的文件都是和设备有关的,此目录下的文件都是设备文件(如声卡、硬盘、光驱) |
/bin | bin 文件就是可执行文件。所以此目录下存放着系统需要的可执行文件,一般都是一些命令,比如 ls、 mv 等命令。 |
/etc | 此目录下存放着各种配置文件以及linux启动后的执行文件等 |
/lib | lib 是 library 的简称,也就是库的意思,因此此目录下存放着 Linux 所必须的库文件。这些库文件是共享库,命令和用户编写的应用程序要使用这些库文件。 |
/mnt | 临时挂载目录,一般是空目录,可以在此目录下创建空的子目录,比如/mnt/sd、 /mnt/usb,这样就可以将 SD 卡或者 U 盘挂载到/mnt/sd 或者/mnt/usb 目录中。 |
/proc | 当 Linux 系统启动以后会将此目录作为 proc 文件系统的挂载点, proc是个虚拟文件系统,没有实际的存储设备。 proc 里面的文件都是临时存在的,一般用来存储系统运行信息文件。 |
/usr | Unix Software Resource 的缩写 , Linux 一般被称为类 Unix 操作系统,此目录下存放着很多软件,一般系统安装完成以后此目录占用的空间最多。 |
/var | 存放一些可以改变的数据。 |
/sbin | 用户存放一些可执行文件,但是此目录下的文件或者说命令只有管理员才能使用,主要用户系统管理。 |
/sys | 系统启动以后此目录作为 sysfs 文件系统的挂载点, sysfs 是一个类似于 proc 文件系统的特殊文件系统, sysfs 也是基于 ram 的文件系统,也就是说它也没有实际的存储设备。此目录是系统设备管理的重要目录,此目录通过一定的组织结构向用户提供详细的内核数据结构信息。 |
/opt | 可选的文件、软件存放区,由用户选择将哪些文件或软件放到此目录中。 |
使用最简单的busybox构建根文件系统
刚刚介绍了上面的根文件系统,那么多个目录那么多个文件难道要我们一个一个去移植吗?当然不用,这些工作没有必要,这里我介绍一个最简单的busybox去构建一个根文件系统,构建根文件系统出来的非常小,但是麻雀虽小,五脏俱全!足以让我们顺利启动linux系统。
1.安装依赖文件
sudo apt-get install zlib1g-dev unzip gcc g++ aptitude lib32stdc++6-4.8-dbg make build-essential libncurses5 libncurses5-dev u-boot-tools traceroute sudo gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -y
2.修改busybox顶层makefile
164行屏蔽,在165行添加交叉编译器前缀
3.添加busybox中文字符的支持
如果直接编译的话,对于中文字符是不支持的,中文字符会显示为“?”,比如你的中文目录,中文文件都显示为“?”。打开路径/libbb/unicode.c。修改如下所示两处地方
接着打开文件 busybox-1.33.1/libbb/unicode.c.修改如下两处。
4.配置busybox
①、 defconfig,缺省配置,也就是默认配置选项。
②、 allyesconfig,全选配置,也就是选中 busybox 的所有功能。
③、 allnoconfig,最小配置。
我们一般使用默认配置即可,因此使用如下命令先使用默认配置来配置一下 busybox:make defconfig
然后打开图形化界面配置make menuconfig
Location:
-> Settings
-> Build static binary (no shared libs)
Location:
-> Linux Module Utilities
-> Simplified modutils
如上路径都不要选中因为采用静态编译的话 DNS 会出问题!无法进行域名解析。
Location:
-> Settings
-> vi-style line editing commands
Location:
-> Linux System Utilities
-> mdev (16 kb) //确保下面的全部选中,默认都是选中的
Location:
-> Settings
-> Support Unicode //选中
-> Check $LC_ALL, $LC_CTYPE and $LANG environment variables //选中
如上路径选中
5.编译busybox生成根文件系统
执行如下命令编译
make
make install
默认生成在busybox目录下的_install文件夹中,拷贝_install下所有文件到我们的nfs工作区新建的rootf文件夹中
sudo cp -rf ./* /home/gg/workdir/rootf
6.完善根文件系统
首先创建完整根文件系统具有的各个目录:
mkdir dev etc lib var proc tmp home root mnt sys
1)向 rootfs 的“/lib”目录添加库文件
Linux 中的应用程序一般都是需要动态库的, 当然也可以编译成静态的,但是静态的可执行文件会很大。如果编译为动态的话就需要动态库,所以我们需要向根文件系统中添加动态库。
在这里,我们把交叉编译器中的所有lib库复制到我们的根文件系统中(不做裁剪,高手自便)
进入交叉编译器的目录arm-linuxgnueabihf/libc/lib中,此目录下有很多的so(*是通配符)和.a 文件,这些就是库文件,将此目录下所有的 so 和.a文件都拷贝到 rootfs/lib 目录中
cp *so* *.a /home/gg/workdir/rootfs/lib/ -d
后面的“-d”表示拷贝符号链接,里有个比较特殊的库文件: rootfs/lib 中的 ld-linux-armhf.so.3需要我们执行如下命令将他变为非链接文件
rm ld-linux-armhf.so.3#删除之后进入/armlinux-gnueabihf/libc/lib 目录中再执行下面的命令
cp ld-linux-armhf.so.3 /home/gg/workdir/rootfs/lib/
还需要进入arm-linux-gnueabihf/lib继续复制库文件
cp *so* *.a /home/gg/workdir/rootfs/lib/ -d
rootfs/lib 目录的库文件就这些了。
2)向 rootfs 的“usr/lib”目录添加库文件
将交叉编译器中arm-linux-gnueabihf/libc/usr/lib目录下的so 和.a 库文件都拷贝到 rootfs/usr/lib 目录中
cp *so* *.a /home/gg/workdir/rootfs/usr/lib/ -d
至此,根文件系统的库文件就全部添加好了
lib和usr/lib这两个文件的大小分别为57MB和67MB,加起来就是57+67=124MB。
3)创建/etc/init.d/rcS 文件
rcS 是个 shell 脚本, Linux 内核启动以后需要启动一些服务,而 rcS 就是规定启动哪些文件的脚本文件。在 rootfs 中创建/etc/init.d/rcS 文件,然后在 rcS 中输入如下所示内容:
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
export PATH LD_LIBRARY_PATH
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
第 1 行,表示这是一个 shell 脚本。
第 3 行, PATH 环境变量保存着可执行文件可能存在的目录,这样我们在执行一些命令或者可执行文件的时候就不会提示找不到文件这样的错误。
第 4 行, LD_LIBRARY_PATH 环境变量保存着库文件所在的目录。
第 5 行,使用 export 来导出上面这些环境变量,相当于声明一些“全局变量”。
第 7 行,使用 mount 命令来挂载所有的文件系统,这些文件系统由文件/etc/fstab 来指定,所以我们一会还要创建/etc/fstab 文件。
第 8 和 9 行,创建目录/dev/pts,然后将 devpts 挂载到/dev/pts 目录中。
第 11 和 12 行,使用 mdev 来管理热插拔设备,通过这两行, Linux 内核就可以在/dev 目录下自动创建设备节点。关于 mdev 的详细内容可以参考 busybox 中的 docs/mdev.txt 文档。
这是最精简的rcS文件,在大型系统中的复杂rsC是由buildroot 等软件自动生成的
使用如下命令给予/ec/init.d/rcS 可执行权限:chmod 777 rcS
4)创建/etc/fstab 文件
在 rootfs 中创建/etc/fstab 文件, fstab 在 Linux 开机以后自动配置哪些需要自动挂载的分区,格式如下:
//<file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
/*<file system>:要挂载的特殊的设备,也可以是块设备,比如/dev/sda 等等。
<mount point>:挂载点。
<type>:文件系统类型,比如 ext2、 ext3、 proc、 romfs、 tmpfs 等等。
<options>:挂载选项,在 Ubuntu 中输入“man mount”命令可以查看具体的选项。一般使用 defaults,也就是默认选项, defaults 包含了 rw、 suid、 dev、 exec、 auto、 nouser 和 async。
<dump>:为 1 的话表示允许备份,为 0 不备份,一般不备份,因此设置为 0。
<pass>:磁盘检查设置,为 0 表示不检查。根目录‘/’设置为 1,其他的都不能设置为 1,其他的分区从 2 开始。一般不在 fstab 中挂载根目录,因此这里一般设置为 0。*/
将上面未注释的部分填入fstab即可
5)创建/etc/inittab 文件
linux内核开启后init 程序会读取/etc/inittab这个文件, inittab 由若干条指令组成。
格式为:<id>:<runlevels>:<action>:<process>
id | 每个指令的标识符,不能重复。但是对于 busybox 的 init 来说, 有着特殊意义。对于 busybox 而言用来指定启动进程的控制 tty,一般我们将串口或者 LCD 屏幕设置为控制 tty |
---|---|
runlevels | 对 busybox 来说此项完全没用,所以空着。 |
process | 具体的动作,比如程序、脚本或命令等。 |
action | 动作,用于指定可能用到的动作。 busybox 支持的动作如图 |
每条指令的结构都是一样的,由以“:”分隔的 4 个段组成(下图中::表示前方两个参数为空,所以:连在一起)
#etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
/*第 2 行,系统启动以后运行/etc/init.d/rcS 这个脚本文件。
第 3 行,将 console 作为控制台终端,也就是 ttymxc0。
第 4 行,重启的话运行/sbin/init。
第 5 行,按下 ctrl+alt+del 组合键的话就运行/sbin/reboot,看来 ctrl+alt+del 组合键用于重启系统。
第 6 行,关机的时候执行/bin/umount,也就是卸载各个文件系统。
第 7 行,关机的时候执行/sbin/swapoff,也就是关闭交换分区。*/
将上面未注释内容写入inittab中。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)