BusyBox 是一个集成了大量日常Linux使用工具,简单的有ls、cat… 复杂的有grep、awk… 这个大工具箱通常被称为Linux工具里的瑞士军刀。作为日常使用的根文件系统,具备BusyBox是其基本组成部分。
因此,本文主要结合BusyBox和根文件系统,介绍Busybox编译流程,并如何构建一个简单的根文件系统,最后制作成可烧录镜像。
文章目录
一、 busybox下载&编译&安装
1.1 下载
点击进入官网下载链接。
1.2 交叉编译
1)配置
make menuconfig
进入配置页面,通常需要配置如内容:
-
Lis添加命令行代码补全功能(选择):
Busybox Settings—>Busybox Library Tuning—> Tab completion -
是否选用静态连接(不选择):
Busybox Settings ----> Build Options ----> Build Busybox as a static binary 一般都设置成动态库编译。 -
是否支持热插拔(选择):
Linux System Utilities -----> mdev
修改配置完成,退出保存,会生成.config文件。
2)交叉编译
- 自行在pc上安装arm gcc编译工具(过程略)
- 假设gcc工具为:aarch64-linux-gnu-gcc,执行编译:
make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm
1.3 安装
指定创建一个空文件夹(/home/rootfs),将编译结果安装到该路径下:
mkdir /home/rootfs
make install CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm CONFIG_PREFIX=/home/rootfs
这里busybox编译出来的各种基础命令(ls,cd,awk等),通过 链接文件形式
安装到/home/rootfs下。文件组成为:
$ tree -L 1
.
├── bin
├── linuxrc -> bin/busybox
├── sbin
└── usr
相比于根文件系统,还有很多文件缺失,下面,我们需要基于此基础添加根文件系统的缺少文件,构建完整一个根文件系统。
二、根文件系统组成
根文件系统,顾名思义是所有文件系统的‘根’,在linux内核启动加载的第一个文件系统,其他的文件系统都会依赖这个文件系统进行挂载等操作。
根文件系统通常有如下文件构成(通常dev、bin、usr、etc等这些目录是必须的)。
根目录(/) 根目录是整个文件系统的顶级目录,所有其他目录和文件都是从根目录开始的。在Linux中,根目录用斜杠(/)表示。
/bin 目录包含一些基本的可执行文件,这些文件是系统启动和运行所必需的。例如,/bin目录包含常用的命令如ls、cp、rm等。
/boot 目录包含启动加载程序(bootloader)的相关文件,包括内核映像文件和引导配置文件。在启动过程中,系统会使用/boot目录下的文件来引导操作系统。
/dev 目录包含设备文件,这些文件用于与系统中的设备进行交互。在Linux中,一切都被视为文件,设备文件用于访问硬件设备,如磁盘、键盘、鼠标等。
/etc 目录包含系统的配置文件。这些配置文件用于设置系统的各种参数和选项,例如网络配置、用户账户配置、服务配置等。/etc目录中的文件对系统的正常运行至关重要。
/home 目录是用户的主目录,每个用户都有一个与其用户名相对应的子目录。用户可以在自己的主目录中存储个人文件和配置。
/lib和/lib64 目录包含共享库文件,这些库文件是应用程序和系统工具所需的共享组件。/lib目录用于32位系统,而/lib64目录用于64位系统。
/media 目录用于挂载可移动设备,如光盘、USB驱动器等。当插入可移动设备时,系统会自动将其挂载到/media目录下的子目录中。
/mnt 目录用于临时挂载其他文件系统或网络共享。管理员可以将其他设备或远程共享挂载到/mnt目录中,以便访问其内容。
/opt 目录用于安装第三方软件包。一些应用程序将其安装在/opt目录下,以便与系统的其他部分分离。
/proc 目录是一个虚拟文件系统,提供有关系统和进程的信息。系统管理员和开发人员可以通过读取/proc目录下的文件来获取关于系统状态、进程信息、硬件配置等的实时数据。
/root 目录是超级用户(root用户)的主目录。与普通用户的主目录(/home)不同,超级用户的主目录位于/root。只有root用户可以访问和操作/root目录。
/sbin 目录包含系统管理员使用的一些系统命令和工具。这些命令和工具通常用于系统管理和维护任务,例如启动和停止服务、网络配置等。
/srv 目录用于存储系统服务提供的数据。例如,Web服务器可以将网站数据存储在/srv目录下。
/tmp 目录用于存储临时文件。该目录中的文件通常在系统重新启动后被删除。应注意定期清理/tmp目录,以确保不会占用过多的磁盘空间。
/usr 目录包含用户的应用程序和文件。这是Linux系统中最大的目录之一,它通常包含共享的可执行文件、库文件、文档、图标等。
/var 目录用于存储可变数据,例如日志文件、缓存文件和临时文件。/var目录中的数据通常在系统运行时会频繁变化。
/run 目录是一个临时文件系统,用于存储在系统引导过程中需要保存的运行时数据。例如,PID文件、锁文件等。
/run/user 目录包含与用户相关的运行时数据。每个用户都有一个与其用户ID相对应的子目录,用于存储用户特定的运行时数据。
/sys 目录是一个虚拟文件系统,用于提供关于系统硬件和设备的信息。它是与/sys目录下的文件进行交互的一种方法。
/srv 目录用于存储系统服务提供的数据。例如,Web服务器可以将网站数据存储在/srv目录下。
三、制作根文件系统
基于busybox编译的出来的目录,还需要手动添加一些文件,构成正常根文件系统结构。
先创建缺少的基础根目录:
cd /home/rootfs
mkdir dev etc lib var proc tmp home root mnt sys
3.1 构建/lib
lib
下的库需要从交叉编译工具里获取,拷贝到根文件系统下,本文采用的工具链为: gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu
cp /home/tools/gcc/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/aarch64-linux-gnu/libc/lib64/* lib/ -a
3.2 构建usr/lib
同样,从工具链里拷贝库到usr/lib
下
cp /home/tools/gcc/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/aarch64-linux-gnu/libc/usr/lib64/*.so* usr/lib/ -a
cp /home/tools/gcc/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/aarch64-linux-gnu/libc/usr/lib64/*.a usr/lib/ -a
3.3 构建/dev
创建console和null节点.
cd ./dev
sudo mknod console c 5 1
sudo mknod null c 1 3
3.4 构建/etc
etc
下主要跟开机的系统启动和配置有关,重点需要添加如下几个文件:
cd etc
mkdir init.d
touch inittab
touch fstab
cd init.d
touch rcS
chmod 777 rcS
initab
: 是linuxrc的配置脚本。内容以“:”分隔的 4 个段组成,格式如下:
<id>:<runlevels>:<action>:<process>
填充内容如下:
#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,也就是关闭交换分区
fstab
: 用于开机后哪些需要自动挂载的操作。文件格式如下:
<file system> <mount point> <type> <options> <dump> <pass>
各选项含义:
<挂载的设备><挂载点><挂载文件系统类型><挂载选项,通常为defaults\n><是否允许备份><磁盘检查设置,为 0 表示不检查。根目录‘/’设置为 1,其他的都不能设置为 1>
填充内容如下:
#<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
其中proc、sysfs、tmpfs是我们常见必须要挂载的3种文件系统,其他根据用户自定义添加。
/etc/init.d/rcS
: 从如上inittab也能看出,这个文件是系统启动脚本。
内容如下:
#!/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
用户也可以自定义完成一些开机程序启动。
至此,简单根文件系统制作完成,下面介绍将这个根文件系统格式化指定格式,做成镜像文件。
四、格式化根文件系统生成镜像
目的是将文件系统格式化成指定类型,以便烧录到指定介质中(不同存储介质对文件系统格式有要求),Linux文件系统格式类型有很多种,不同使用场景,通常有:
(1)传统磁盘文件系统:ext2、ext3、ext4、XFS、Btrfs、JFS、
(2)闪存文件系统:ubifs、JFFS2、YAFFS 等。
(3)网络文件系统:NTFS等
(4)数据库文件系统
(5)特殊用途的文件系统
- swap文件系统:swap
- RAM文件系统:procfs、sysfs、tmpfs、squashfs、debugfs 等。
- 外设文件系统:dev
比较常见的:ext4 用于mmc类型的存储器介质,jffs、yaffs用于flash闪存介质。这里以ext4 格式为例,按如下脚本,如何把根文件系统制作成镜像:
#!/bin/sh
1、先制作一个空的镜像文件rootfs.ext4
rm -f romfs rootfs.ext4 rootfs.img.gz
dd if=/dev/zero of=rootfs.ext4 bs=1M count=32
2、然后把此镜像文件格式化为ext4格式
mkfs.ext4 rootfs.ext4
3、然后把此镜像文件挂载,并把根文件系统复制到挂载目录
mkdir -p romfs #挂载点
sudo mount -o loop rootfs.ext4 romfs
sudo cp -rf rootfs/* romfs #rootfs是上述制作好的根文件系统
4、卸载该镜像文件挂载
sudo umount romfs
5、把rootfs.ext4镜像压缩成压缩文件
gzip --best -c rootfs.ext4 > rootfs.img.gz
如果要将镜像文件烧到某个emmc分区:
dd if=rootfs.img.gz of=/dev/mmcblk0pX
或者,也可以先格式化分区为ext4格式(mkfs.ext4 /dev/mmcblk0pX
),然后将根文件系统内容直接拷贝到分区里。