文章目录
一、Linux文件系统简介
一个完整的嵌入式Linux系统,包含uboot,Linux内核,根文件系统三个部分。其启动顺序为,在系统刚一上电的时候,先执行uboot,由uboot引导内核,内核启动成功之后挂载根文件系统。根文件系统挂载成功以后,嵌入式Linux系统就启动成功了。在开发板上看到的现象是:用户可以在串口控制台上输入命令与Linux系统进行交互。
嵌入式Linux系统构成图:
1. 什么是文件系统
可以将文件系统在字面上分为俩部分来理解,一部分是文件,一
部分是系统。那文件系统是不是可以理解成是组织和管理文件的一个系统呢。所以有了文件系统以后,就可以轻松的操作存储在存储介质的文件。比如删除一个文件,新增一个文件等。文件系统的格式(类型)有多种,如 fat32 ext2 ext3 ntfs 等。
2. 文件系统目录介绍
Linux 文件系统中一般由如下的几个目录构成。这些目录用于不同的功能。
1. /bin 目录
- 该目录下主要是存放Linux命令,这些可以被root和普通用户所使用,/bin目录下常用的命令有:cat chgrp chmod cp ls sh kill mount umount mkdir 等。
2. /sbin 目录
- 该目录下存放的是系统命令,只有系统管理员(俗称最高权限的root)能够使用的命令,除此之外系统命令还可以存放在/usr/sbin,/usr/local/sbin 目录下。
- /sbin 目录下常用的命令有:shutdown reboot fdisk fsck init 等。
3. /dev 目录
- 该目录下存放的是设备接口的文件,设备文件是Linux中特有的文件类型,在Linux系统下,一切皆文件。所以以文件的方式访问各种设备,即通过读写某个设备文件操作某个具体硬件。
- 比如通过“/dev/ttySAC0”文件可以操作串口0等。
4. /etc 目录
- 该目录下存放着系统主要的配置文件
5. /lib 目录
- Lib 是 library 的简称,也就是库的意思,因此此目录下存放着Linux所必须的库文件。
6. /home 目录
- 系统默认的用户文件夹,它是可选的,对于每个普通用户,在/home 目录下都有一个以用户名命名的子目录,里面存放用户相关的配置文件。
7. /root 目录
- 系统管理员(root)的主文件夹,即是根用户的目录,与此对应,普通用户的目录是 /home 下的某个子目录。
8. /usr 目录
- usr 是unix shared resources(共享资源)的缩写,用来存放用户的应用程序和文件。
9. /var 目录
- var 是variable(变量)的缩写,/var 目录中存放可变的数据,如日志文件。
10. /proc 目录
- 这是一个空目录,常作为 proc 文件系统的挂接点
11. /mnt 目录
- 用于临时挂载某个文件系统的挂接点,通常是空目录,也可以在里面创建一引起空的子目录,
- 比如/mnt/cdram /mnt/hda1 。用来临时挂载光盘、移动存储设备等。
12. /tmp 目录
- 用于存放临时文件,通常是空目录,一些需要生成临时文件的程序用到的/tmp 目录下。
3. 什么是根文件系统
根文件系统也是文件系统,但是为什么多了一个根字呢?
因为在Linux系统上没有盘符这个概念,是使用一个类似大树一样的结构来组织和管理的。这颗大树的最底端就叫做根,然后每个目录都是这个树干上的子目录。
Linux 系统上是用“/”来表示根,一般也叫做根目录。在根目录下有非常多的特定目录。
这些由特定目录挂载(mount)在根目录下。那这些挂载在根目录下由特定目录构成的文件构建系统就叫做文件系统。
所以根文件系统就是一个挂载在Linux根目录下的,有特定目录组成的文件系统。如下图所示:
4. 根文件系统制作工具
最简单的根文件系统一般使用 busybox 工具制作。除此之外,还可以使用 buildroot 工具和 yocto 工具构建根文件系统。当然也可以直接使用发行版 Linux 系统,如 Ubuntu 系统,Debian 系统。这些文件系统之间的界限没有很明确的界定。
以下大致列出一些根文件系统的特点,如下图所示:
5. 常见文件系统
5.1 Buildroot
Buildroot 是 Linux 平台上一个开源的嵌入式 Linux 系统自动构建框架。整个 Buildroot 是由 Makefile 脚本和 Kconfig 配置文件构成的。你可以通过 Buildroot 配置编译出一个完整的可以直接烧写到机器上运行的 Linux 系统软件。
Buildroot 优势:
- 通过源码构建,有很大的灵活性
- 方便的交叉编译环境,可以进行快速构建
- 方便各系统组件配置及定制开发
5.2 Yocto
Yocto 和 Buildroot 一样, 是一套构建嵌入式系统的工具,但是两者的风格完全不同。
Yocto project 是通过一个个单独的包(meta)来维护,比如有的包负责核心,有的包负责外围。有的包用于跑 AllwinnerTechnology / Rockchip 的芯片,有的包用于安装上 Qt。
Yocto 的优缺点:
- 支持的架构多:ARMMIPSPPC和其他架构。
- 通过QEMU完全支持各种设备仿真
- 灵活性:公司以多种不同的方式使用 Yocto 项目。一个示例是创建内部 Linux 发行版,作为公司可以跨多个产品组使用的代码库。通过自定义和分层,项目组可以利用基础 Linux 发行版创建适合其产品需求的分发。
5.3 Ubuntu
Ubuntu 是一个流行的 Linux 发行版,是基于 Debian 的 unstable 版本加强而来,以“最好的 Linux 桌面系统”而闻名,近些年 Ubuntu 也推出了 Ubuntu Enterprise Linux, 在企业 Linux 应用市场占有率也有较大提高。
- 优点:技术支持较好,用户界面友好,硬件的兼容性好,采用基于Deb的ATP包管理系统。
- 缺点:技术支持和更新服务是需要付费的, 服务器软件生态系统的规模和活力方面稍弱。
5.4 Debian
Debian GNU / Linux 是一款是由GPL 和其他自由软件许可协议授权的自由软件组成的 Linux 操作系统,由 Debian Project 组织维护。以其坚守 Unix 和自由软件的精神,以及其给予用户的众多选择而闻名。
- 优点:Debian 是极为精简而稳定的 Linux 发行版,有着干净的作业环境,采用基于 Deb 的 ATP 包管理系统。
- 缺点:不提供专门技术支持,不包含封闭源代码软件;发行周期过长,稳定版本中软件过时。中文支持不是很完善。
二、使用Busybox制作根文件系统
1. 编译 busybox
tar xjf busybox-1.31.1.tar.bz2
cd busybox-1.31.1/
vi Makefile : CROSS_COMPILE ?= arm-buildroot-linux-gnueabihf
make menuconfig
make
make CONFIG_PREFIX=tmp install
cd tmp/
ls
图形化配置:选择默认配置或按需修改
配置完进行编译:
编译完成后安装到 tmp 目录:
复制内核和设备树:
$ cd ~/create_my_fs/busybox-1.31.1/tmp/
$ mkdir boot
$ cp ~/100ask_imx6ull-sdk/Linux-4.9.88/arch/arm/boot/zImage boot/
$ cp ~/100ask_imx6ull-sdk/Linux-4.9.88/arch/arm/boot/dts/100ask_imx6ull-14x14.dtb boot/
2. 复制lib
确定lib目录在哪:
echo "void main(){}" | arm-buildroot-linux-gnueabihf-gcc -E -v -
确定需要哪些库:
arm-buildroot-linux-gnueabihf-readelf -d bin/busybox | grep NEEDED
从上面库路径中找到需要的库:
查看库链接的情况:
复制到新创建的 lib 文件:
复制动态连接器:
3. 制作启动脚本
sudo mknod console c 5 1
sudo mknod null c 1 3
4. 制作镜像文件
4.1 下载 genimage
git clone https://gitee.com/dongbaohua/genimage.git
cd genimage/
./autogen.sh
sudo apt install libconfuse-dev
./configure
make
sudo make install
解释:
-
从 Gitee 代码托管平台下载 genimage 工具的源代码到本地
-
切换到 genimage 源码目录
-
生成配置脚本
-
安装 genimage 的必需依赖库 libconfuse
-
检查系统环境(编译器、依赖库是否齐全),生成适配当前系统的 Makefile
- –prefix=/usr/local(按需添加):指定安装路径(默认 /usr/local/bin)
-
根据 Makefile 编译源码,生成可执行文件 genimage
-
将编译好的 genimage 安装到系统路径(如 /usr/local/bin)
4.2 genimage用法
genimage.cfg文件配置:
image emmc.img {
hdimage { // Generates DOS partition images.
}
partition rootfs-1 {
partition-type = 0xC
bootable = "yes"
image = "boot.vfat" // 这个分区里直接写入映像文件boot.vfat
size = 10M // 分区大小为10M
}
partition rootfs-2 {
partition-type = 0x83
bootable = "yes"
image = "myrootfs.ext4" // 这个分区里直接写入映像文件myrootfs.ext4
size = 1000M // 分区大小为100M
}
}
image boot.vfat {
vfat { // 制作vfat格式的映像文件
files = { "u-boot-dtb.imx" } // 内容来自inputpath指定的目录里的u-boot-dtb.imx
}
size = 10M // 生成的镜像文件大小
}
image myrootfs.ext4 {
ext4 {} // 制作ext4格式的映像文件
name = "root"
size = 100M // 生成的镜像文件大小
mountpoint = "/" // 内容来自"rootpath"/{mountpoint}即 "rootpath"/
}
制作镜像文件的命令
sudo genimage \
--rootpath "/home/book/myimage/busybox-1.31.1/tmp" \
--tmppath "/home/book/myimage/mytmp" \
--inputpath "/home/book/myimage/input" \
--outputpath "/home/book/myimage/output" \
--config "genimage.cfg"
- 指定根文件系统目录
- 指定临时工作目录,用于存放中间文件
- 指定输入文件目录(如 U-Boot 镜像、内核镜像、设备树文件等)
- 指定输出目录,生成的镜像文件(如 emmc.img)会保存至此
在outpu目录先生成了emmc.img:
我们可以把生成的 emmc.img 烧写到开发板启动:
5. 完善文件系统
5.1 添加 /etc/inittab
/etc/inittab文件中字段的意义:
仿照Busybox的examples/inittab文件,创建一个inittab文件:
修改文件:
5.2 添加 /etc/fstab
内容如下,表示执行“mount -a”命令后将挂接proc、tmpfs文件系统:
# device mount-point type options dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sys /sys sysfs defaults 0 0
devtmpfs /dev devtmpfs defaults 0 0
添加 proc,tmp,sys,dev 目录:
5.3 添加 /etc/init.d/rcS
这是一个脚本文件,可以在里面添加想自动执行命令。以下命令挂载/etc/fstab指定的文件系统:
#!/bin/sh
mount -a
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
- 指定脚本解释器为 /bin/sh
- 挂载 /etc/fstab 文件中定义的所有文件系统
- 设置内核的热插拔事件处理程序为 mdev
- 使用mdev来管理热插拔设备,Linux内核就可以在/dev目录下自动创建设备节点
- 在系统启动时扫描 /sys 目录,静态初始化设备节点
5.4 添加 /etc/mdev.conf
在 etc 目录下,新建 mdev.conf 文件,因为我们在 rcS 文件里面配置了热拔插功能,但是还需要 mdev.conf 配合,mdev.conf 文件是U盘 sd卡的热拔插文件。
# /etc/mdev.conf 示例1: U盘自动加载
sda[1-9]+ 0:0 777 * if [ $ACTION = "add" ]; then mount /dev/$MDEV /mnt;
else umount /mnt; fi
# /etc/mdev.conf 示例2: U盘自动加载
sda[1-9]+ 0:0 777 * /bin/add_remove_udisk.sh
# /bin/add_remove_udisk.sh
#!/bin/sh
if [ $ACTION = "add" ];
then
mount /dev/$MDEV /mnt;
else
umount /mnt;
fi
重新执行命令构建镜像:
sudo genimage \
--rootpath "/home/book/myimage/busybox-1.31.1/tmp" \
--tmppath "/home/book/myimage/mytmp" \
--inputpath "/home/book/myimage/input" \
--outputpath "/home/book/myimage/output" \
--config "genimage.cfg"
然后将新生成的 emmc.img 烧写到开发板启动即可观察现象。