点击上方“嵌入式应用研究院”,选择“置顶/星标公众号”

干货福利,第一时间送达!

来源|CSDN-止于至善656

整理&排版|嵌入式应用研究院

1.根文件系统布局

嵌入式Linux根文件系统布局,建议还是根据FHS标准来安排,事实上大多数嵌入式Linux都是这样做的。并且,嵌入式系统可能并不须要桌面/服务器那样庞大系统的全部目录,可以酌情对系统进行精简,以简化Linux的使用。如嵌入式Linux文件系统中一般不会放置内核源码,因此存的常不会放置内核源码,因此存的常不会放置内核源码,因此储存源码的/usr/src目录是何必要的,甚至连头文件也不须要,即/usr/include目录也毋须要;并且/bin、/dev、/etc、/lib、/proc、/sbin、/usr几个目录是不可或缺的。

所以,容许嵌入式Linux对系统目录结构进行精简,以适应具体用场合的需求,一个典型的嵌入式Linux根文件系统目录如下所示:

镜像制作系统u盘_linux系统镜像制作_镜像制作系统盘

要建立一个可用的Linux根文件系统,须要的二补码和库都不少,完全从零开始也是不现实的,推荐参考其它现有可用的文件系统,在原基础上按需更改;或则使用文件系统制做工具如BusyBox来实现文件系统的生成。

2.使用BusyBox生成二补码工具2.1.获取BusyBox源码

Busybox的官方源码下载路径为:。这儿以下载busybox-1.29.3.tar.bz2为例。

2.2.配置BusyBox

解压源码,步入根目录

<pre style=”box-sizing: border-box;font-size: 16px;font-family: SFMono-Regular, Consolas, “Liberation Mono”, Menlo, Courier, monospace;margin-top: 10px;margin-bottom: 10px;overflow: auto;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;color: rgb(0, 0, 0);text-align: left;background-color: rgb(255, 255, 255);”>$ tar jxvf busybox-1.29.3.tar.bz2
cd busybox-1.29.3/

首先,执行:

$ make menuconfig

步入图形化配置界面:

linux系统镜像制作_镜像制作系统u盘_镜像制作系统盘

2.2.1.选择编译静态库

步入Settings—>使用空格键选择编译静态库

--- Build Options                                             
[*] Build static binary (no shared libs)  

如图:

镜像制作系统u盘_镜像制作系统盘_linux系统镜像制作

2.2.2.选择交叉编译工具链

在Settings—>设置项下,填写交叉编译工具链前缀

linux系统镜像制作_镜像制作系统盘_镜像制作系统u盘

2-2-3.选择安装目录

在Settings—>设置项下,找到

--- Installation Options ("make install" behavior) 
    What kind of applet links to install (as soft-links)  --->  
(./_install) Destination path for 'make install' (NEW)  

默认为当前目录下目录,这儿我使用默认_install目录:

镜像制作系统盘_linux系统镜像制作_镜像制作系统u盘

2-2-4.编译安装

退出保存后,执行编译make,大约几分钟后编译完成,执行makeinstall,很快还会安装完成:

linux系统镜像制作_镜像制作系统盘_镜像制作系统u盘

入_install目录,查看生成的文件

新建一个目录用来储存制做的根文件系统,可以命名为rootfs。将借助BusyBox生成的二补码文件及目录,即_install目录下的所有文件及目录复制到rootfs目录下。

3.建立根文件系统

使用BusyBox编译后,仅有bin、sbin、usr这3个目录和软链接linuxrc,目录里都是二补码命令工具,这还不足以构成一个可用的根文件系统,必须进行其它建立工作,能够建立一个可用的根文件系统。

3-1.建立目录结构

按照典型嵌入式Linux根文件系统目录,在rootfs目录中创建其他目录

$ mkdir dev etc lib proc sys tmp var

3-2.添加C运行库文件

库文件可直接从交叉工具链获取,通常在工具链的libc/lib/目录下。我这儿是在ubuntu下安装的Linaro的交叉工具链:

镜像制作系统盘_镜像制作系统u盘_linux系统镜像制作

库文件是在/usr/arm-linux-gnueabihf/lib/目录下,拷贝动态链接库文件(.so文件)到新制做的根文件系统根目录下/lib目录里:

$ cp -a  /usr/arm-linux-gnueabihf/lib/*so* ./lib/

这儿只是拷贝动态链接库。通常开发程序使用动态编译须要板子上动态库的支持能够运行,所以拷贝动态库。而静态库通常在静态编译的时侯用到,因为交叉编译的工作放到了PC上所以板子上不须要静态库linux系统镜像制作,所以没有必要拷贝,这样还可以减少根文件系统的容积。

linux系统镜像制作_镜像制作系统u盘_镜像制作系统盘

通常使用gcc编译后的可执行文件、目标文件和动态库都带有调试信息和符号信息,这种在调试的时侯用到,而且却减小了文件的大小。一般在PC上调试,或则调试时使用这种带有调试信息和符号信息的库文件,程序发布后使用去除那些信息的库文件,可以大大缩小根文件系统的容积。这儿我们除去这些信息,方式是使用strip工具:

$ arm-linux-gnueabihf-strip ./*

3-3.添加初始化配置脚本

初始化配置脚本置于在/etc目录下,用于系统启动所需的初始化配置脚本。BusyBox提供了一些初始化范例脚本,在examples/bootfloppy/etc/目录下。将这种配置文件复制到”目录下。将这种配置文件复制到”目录下。将这种配置文件复制到新制做的根文件系统etc目录下

cp -a ../busybox/busybox-1.29.3/examples/bootfloppy/etc/* etc/

添加后如图所示:

3-3-1.更改/etc/inittab文件

/etc/inittab文件是init进程解析的配置文件,通过这个配置文件决定执行那个进程,何时执行。将文件更改为:

# 系统启动时
::sysinit:/etc/init.d/rcS

# 系统启动按下Enter键时
::askfirst:-/bin/sh

# 按下Ctrl+Alt+Del键时
::ctrlaltdel:/sbin/reboot

# 系统关机时
::shutdown:/sbin/swapoff -a
::shutdown:/bin/umount -a -r

# 系统重启时
::restart:/sbin/init

以上内容定义了系统启动时,死机时,重启时,按下Ctrl+Alt+Del键时执行的进程。

3-3-2.更改/etc/init.d/rcS文件

#! /bin/sh

# 挂载 /etc/fstab 中定义的所有文件系统
/bin/mount -a

# 挂载虚拟的devpts文件系统用于用于伪终端设备
/bin/mkdir -p /dev/pts
/bin/mount -t devpts devpts /dev/pts

# 使用mdev动态管理u盘和鼠标等热插拔设备
/bin/echo /sbin/mdev > /proc/sys/kernel/hotplug

# 扫描并创建节点
/sbin/mdev -s

3-3-3.更改/etc/fstab文件

/etc/fstab文件储存的是文件系统信息。在系统启动后执行/etc/init.d/rcS文件里/bin/mount-a命令时linux vi,手动挂载那些文件系统。内容如下:

#                          
proc                  /proc          proc     defaults       0         0
sysfs                 /sys           sysfs    defaults       0         0
tmpfs                 /tmp           tmpfs    defaults       0         0
tmpfs                 /dev           tmpfs    defaults       0         0

注:这儿我们挂载的文件系统有三个proc、sysfs和tmpfs,在内核中proc和sysfs默认都支持,而tmpfs是没有支持的,我们须要添加tmpfs的支持。

3-3-4.更改/etc/profile文件

/etc/profile文件作用是设置环境变量,每位用户登入时就会运行它。将文件内容更改为:

# 主机名
export HOSTNAME=zyz

# 用户名
export USER=root

# 用户目录
export HOME=/root

# 终端默认提示符
export PS1="[$USER@$HOSTNAME:$PWD]# "    

# 环境变量
export PATH=/bin:/sbin:/usr/bin:/usr/sbin

# 动态库路径
export LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH

由于指定了root用户的家目录为/root,所以须要创建该目录,否则执行cd~时会失败

$ mkdir root

登入系统后疗效为:

...
Please press Enter to activate this console.
[root@zyz:/]#
[root@zyz:/]# cd ~
[root@zyz:/root]#
[root@zyz:/root]# echo $PATH
/bin:/sbin:/usr/bin:/usr/sbin

至此,根文件系统就基本建立好了。

4.制做根文件系统镜像4-1.根文件系统类型

假如文件系统早已布局完成,则可以发到目标中了。一般会制做一个镜像之后通过某种形式固化到目标系统中,具体采用哪些样的形发布须要依照资源状况、内核情况和系统需求等方面进行裁决:

(1)硬件方面,起码须要考虑寻址储介质的类型和大小如Flash是NORFlash还是NANDFlash,RAM的大小等。

(2)内核方面,则需考虑所剪裁后的支持什么文件系统采用中最合适linux系统介绍,能满足性、速度等要求。

(3)系统需求方面,要考虑运行速率、是否可写压缩等诱因。常见的可用于根文件系统类型有ramdisk、cramfs、jffs2、yaffs/yaffs2和ubifs等,各种型的特点如表所列。

镜像制作系统u盘_linux系统镜像制作_镜像制作系统盘

虽然文件系统固件以某一种文件系统的镜像发布,并且整个文件系统实际上还是并存多种逻辑文件系统的。比如,一个系统根文件系统以ubifs挂载,而且/dev目录却是以tmpfs挂载的、/sys目录挂载的是sysfs文件系统。现今,虽然ubifs是一种趋势。

linux系统镜像制作_镜像制作系统u盘_镜像制作系统盘

4-2.制做UBIFS根文件系统镜像

Linux下制做UBIFS的命令有两个,mkfs.ubifs和ubinize。mkfs.ubifs,将一个目录制作为UBIFS文件系统。使用范例:

$ mkfs.ubifs -m 2048 -e 128KiB -c 4096 -r ./rootfs -o rootfs.ubifs

其中:

-r, -d, --root=DIR       build file system from directory DIR(目录)
-m, --min-io-size=SIZE   minimum I/O unit size(最小输入输出单元大小)
-e, --leb-size=SIZE      logical erase block size(逻辑擦除块大小)
-c, --max-leb-cnt=COUNT  maximum logical erase block count(最大逻辑擦除块数目)
-o, --output=FILE        output to FILE(输出文件)

所以制做ubifs镜像文件linux系统镜像制作,须要晓得3个关键参数,即最小输入输出单元大小,逻辑擦除块大小,最大逻辑擦除块数量,其中最大逻辑擦除块数量可由Flash分区大小和逻辑擦除块大小估算下来,这种信息可以通过u-boot命令查看:

=> mtdparts default
=> ubi part rootfs

ubinize,将mkfs.ubifs制做的UBIFS文件系统制做成富含卷标的可以直接烧录在Flash上的镜像。使用范例:

$ ubinize -m 2048 -p 128KiB ubinize.cfg -o rootfs_ubifs.img

其中:

-o, --output=     output file name(输出文件)
-p, --peb-size=       size of the physical eraseblock of the flash(物理擦除块大小)
                             this UBI image is created for in bytes,
                             kilobytes (KiB), or megabytes (MiB)
                             (mandatory parameter)
-m, --min-io-size=    minimum input/output unit size of the flash
                             in bytes

这儿须要两个参数化学擦除块大小和最小输入输出单元大小。ubinize.cfg是配置文件,内容如下:

[ubifs]
mode=ubi
image=rootfs.ubifs
vol_id=0
vol_size=1024MiB
vol_type=dynamic
vol_name=rootfs
vol_flags=autoresize

说明:

[ubifs]
mode=ubi
image=rootfs.ubifs       # mkfs.ubi生成的源镜像 
vol_id=0                 # 卷号
vol_size=1024MiB         # 卷大小,一般要设置的比分区大,防止有坏块
vol_type=dynamic         # 卷类型,动态卷
vol_name=rootfs          # 卷名,rootfs
vol_flags=autoresize     # 自动大小

往期精彩

认为本次分享的文章对您有帮助,随手点[在看]并转发分享,也是对我的支持。

Tagged:
Author

这篇优质的内容由TA贡献而来

刘遄

《Linux就该这么学》书籍作者,RHCA认证架构师,教育学(计算机专业硕士)。

发表回复