嵌入式Linux之根文件系统简介和移植

这是 Linux 移植的最后一步,根文件系统构建好以后就意味着我们已经拥有了一个完整的、可以运行的最小系统。以后我们就在这个最小系统上编写、测试 Linux 驱动,移植一些第三方组件,逐步的完善这个最小系统。最终得到一个功能完善、驱动齐全、相对完善的操作系统。

什么是根文件系统 

根文件系统一般也叫做 rootfs,那么什么叫根文件系统?

一文搞懂嵌入式uboot、kernel、文件系统的关系_boot0和uboot还有内核之间的关系-CSDN博客

Linux 中的根文件系统更像是一个文件夹或者叫做目录(在我看来就是一个文件夹,只不过是特殊的文件夹),在这个目录里面会有很多的子目录。根目录下和子目录中会有很多的文件,这些文件是 Linux 运行所必须的,比如库、常用的软件和命令、设备文件、配置文件等等。 其实,就是linux中的根目录/的意思。

根文件系统是 Linux 内核启动以后挂载(mount)的第一个文件系统,然后从根文件系统中读取初始化脚本,比如 rcSinittab 等。根文件系统和 Linux 内核是分开的,单独的 Linux 内核是没法正常工作的,必须要搭配根文件系统。如果不提供根文件系统,Linux 内核在启动的时候就会提示内核崩溃(Kernel panic)的提示。

根文件系统的这个“根”字就说明了这个文件系统的重要性,它是其他文件系统的根,没有这个“根”,其他的文件系统或者软件就别想工作。比如我们常用的 lsmvifconfig 等命令其实就是一个个小软件,只是这些软件没有图形界面,而且需要输入命令来运行。这些小软件就保存在根文件系统中,这些小软件是怎么来的呢?这个就是我们要学习这部分的目的,教大家来构建自己的根文件系统,这个根文件系统是满足 Linux 运行的最小根文件系统,后续我们可以根据自己的实际工作需求不断的去填充这个最小根文件系统,最终使其成为一个相对完善的根文件系统。

在构建根文件系统之前,我们先来看一下根文件系统里面大概都有些什么内容,以 Ubuntu为例,根文件系统的目录名字为‘/’,没看错就是一个斜杠,所以输入如下命令就可以进入根目录中:

cd / //进入根目录

进入根目录以后输入“ls”命令查看根目录下的内容都有哪些,结果如图 38.1.1 所示:

38.1.1 中根目录下子目录和文件不少,但是这些都是 Ubuntu 所需要的,其中有很多子目录和文件我们嵌入式 Linux 是用不到的。

Linux 的根目录就介绍到这里,接下来的构建根文件系统就是研究如何创建上面的一些关键子目录以及子目录中的文件。

BusyBox 构建根文件系统

BusyBox 简介

上一小节说了,根文件系统里面就是一堆的可执行文件和其他文件组成的?难道我们得一

个一个的从网上去下载这些文件?显然这是不现实的!那么有没有人或者组织专门干这个事呢?

他们负责“收集”这些文件,然后将其打包,像我们这样的开发者可以直接拿来用。答案是有的,它就叫做 BusyBox!其名字分为“Busy”和“Box”,也就是忙碌的盒子。盒子是用来放东西的,忙碌的是因为它要提供根文件系统所需的文件,所以忙碌。BusyBox 是一个集成了大量的 Linux 命令和工具的软件,像 ls、mv、ifconfig 等命令 BusyBox 都会提供。BusyBox 就是一个大的工具箱,这个工具箱里面集成了 Linux 的许多工具和命令。一般下载 BusyBox 的源码,然后配置 BusyBox,选择自己想要的功能,最后编译即可。

具体参看正点原子开发手册。

BusyBox 准备好以后就可以构建根文件系统了。

一般我们在 Linux 驱动开发的时候都是通过 nfs(NFS就是Network File System的缩写,它最大的功能就是可以通过网络,让不同的机器、不同的操作系统可以共享彼此的文件。) 挂载根文件系统的,当产品最终上市开卖的时候才会将根文件系统烧写到 EMMC 或者 NAND 中。

具体参看正点原子开发手册。

配置 busybox

根我们编译 Uboot、Linux kernel 一样,我们要先对 busybox 进行默认的配置,有以下几种 配置选项:

  • defconfig,缺省配置,也就是默认配置选项。
  • allyesconfig,全选配置,也就是选中 busybox 的所有功能。
  • allnoconfig,最小配置。

我们一般使用默认配置即可,因此使用如下命令先使用默认配置来配置一下 busybox

make defconfig

编译 busybox

配置好 busybox 以后就可以编译了,我们可以指定编译结果的存放目录,我们肯定要将编 译结果存放到前面创建的 rootfs 目录中,输入如下命令:

make

make install CONFIG_PREFIX=/home/zuozhongkai/linux/nfs/rootfs

COFIG_PREFIX指 定 编 译 结 果 的 存 放 目 录 , 比 如 我 存 放 到

“/home/zuozhongkai/linux/nfs/rootfs”目录中,等待编译完成

编译完成以后会在 busybox 的所有工具和文件就会被安装到 rootfs 目录中,rootfs 目录内容如图 38.2.2.9 所示:

从图 38.2.2.9 可以看出,rootfs 目录下有 binsbin usr 这三个目录,以及 linuxrc 这个文件。前面说过 Linux 内核 init 进程最后会查找用户空间的 init 程序,找到以后就会运行这个用户空间的 init 程序,从而切换到用户态。如果 bootargs 设置 init=/linuxrc,那么 linuxrc 就是可以作为用户空间的 init 程序,所以用户态空间的 init 程序是 busybox 来生成的。

busybox 的工作就完成了,但是此时的根文件系统还不能使用,还需要一些其他的文件,我

们继续来完善 rootfs

更多参看正点原子开发手册。

rcS 是个 shell 脚本,Linux 内核启动以后需要启动一些服务,而 rcS 就是规定启动哪些文件的脚本文件。

开机自启动测试

在 38.5.1 小节测试 hello 软件的时候都是等 Linux 启动进入根文件系统以后手动输入命令“./hello”来完成的。我们一般做好产品以后都是需要开机自动启动相应的软件,本节我们就hello 这个软件为例,讲解一下如何实现开机自启动。前面我们说过了,进入根文件系统的时候会运行/etc/init.d/rcS 这个 shell 脚本,因此我们可以在这个脚本里面添加自启动相关内容。添加完成以后的/etc/init.d/rcS 文件内容如下:

示例代码 38.5.3.1 rcS 文件代码
1 #!/bin/sh
2 PATH=/sbin:/bin:/usr/sbin:/usr/bin
3 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
4 runlevel=S
5 umask 022
6 export PATH LD_LIBRARY_PATH runlevel
7 
8 mount -a
9 mkdir /dev/pts
10 mount -t devpts devpts /dev/pts
11
12 echo /sbin/mdev > /proc/sys/kernel/hotplug
13 mdev -s
14
15 #开机自启动
16 cd /drivers
17 ./hello &
18 cd /

16 行,进入 drivers 目录,因为要启动的软件存放在 drivers 目录下。

17 行,以后台方式执行 hello 这个软件。

18 行,退出 drivers 目录,进入到根目录下。

自启动代码添加完成以后就可以重启开发板

补充 

动态库和静态库

参考

详解Linux下静态库/动态库的生成和使用(含代码示例和操作流程)&&动态库和静态库的区别_生成静态库的过程及作用-CSDN博客

更多待补充。

Initramfs

是内核启动但还未访问真正的根文件系统之前用到的一个临时的根文件系统

Initramfs 原理和实践 - wipan - 博客园 (cnblogs.com)

initrd和initramfs实操 - 小满的博客 - 博客园 (cnblogs.com)

initrd

linux 发行版必须适应各种不同的硬件架构,将所有的驱动编译进内核是不现实的,根文件系统可能保存到各种存储设备上包括scsi、sata,u-disk等等,但是又必须先加载他们的驱动才能加载根文件系统。

为了解决这一矛盾,于是出现了基于ramdisk的initrd( bootloader initialized RAM disk )。Initrd是一个被压缩过的小型根目录,这个目录中包含了启动阶段中必须的驱动模块,可执行文件和启动脚本。当系统启动的时候,bootloader会把initrd文件读到内存中,然后把initrd文件在内存中的起始地址和大小传递给内核。内核在启动初始化过程中会解压缩initrd文件,然后将解压后的initrd挂载为根目录,然后执行根目录中的/linuxrc脚本。

initrd 的英文含义是 boot loader iniTIalized RAM disk,就是由 boot loader 初始化的内存盘。在 linux内核启动前, boot loader 会将存储介质中的 initrd 文件加载到内存,内核启动时会在访问真正的文件系统前先访问该内存中的 initrd 文件系统。

initramfs

在linux2.5中出现了initramfs,它的作用和initrd类似,只是和内核编译成一个文件(该initramfs是经过gzip压缩后的cpio格式的数据文件),该cpio格式的文件被链接进了内核中特殊的数据段.init.ramfs上,其中全局变量__initramfs_start 和 __initramfs_end分别指向这个数据段的起始地址和结束地址。内核启动时会对.init.ramfs段中的数据进行解压,然后使用它作为临时的根文件系统。

源码自带资料

不管是UBOOT还是kernel或者根文件系统等等,一般都会自带一些说明,可以在源码里找一找,比如README.txt文档;然后就是documents;除了文档,还会有一些程序的examples、demo、quickstart等等;也可能会自带一些模块驱动drivers;总之,多看看源码。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值