Linux--根文件系统移植

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

一、根文件系统简介

Linux 中的根文件系统更像是一个文件夹或者叫做目录 ( 在我看来就是一个文件夹,只不过是特殊的文件夹) ,在这个目录里面会有很多的子目录。根目录下和子目录中会有很多的文件,这些文件是 Linux 运行所必须的,比如库、常用的软件和命令、设备文件、配置文件等等。
根文件系统是 Linux 内核启动以后挂载 (mount) 的第一个文件系统,然后从根文件系统中读取初始化脚本,比如 rcS inittab 等。根文件系统和 Linux 内核是分开的,单独的 Linux 内核是没法正常工作的,必须要搭配根文件系统。如果不提供根文件系统, Linux 内核在启动的时候就会提示内核崩溃(Kernel panic) 的提示。
根文件系统的目录名字为‘ /
cd / //进入根目录
根目录下子目录和文件不少,但是这些都是 Ubuntu 所需要的,其中有很多子目录和文件我们嵌入式 Linux 是用不到的,所以这里就讲解一些常用的子目录:
1 /bin 目录
看到“ bin ”大家应该能想到 bin 文件, bin 文件就是可执行文件。所以此目录下存放着系统需要的可执行文件,一般都是一些命令,比如 ls mv 等命令。此目录下的命令所有的客户都可以使用。
2 /dev 目录
dev device 的缩写,所以此目录下的文件都是和设备有关的,此目录下的文件都是设备文件。在 Linux 下一切皆文件,即使是硬件设备,也是以文件的形式存在的,如/dev/ttymxc0(I.MX6ULL 根目录会有此文件 ) 就表示 I.MX6ULL 的串口 0 ,我们要想通过串口 0发送或者接收数据就要操作文件/dev/ttymxc0 ,通过对文件 /dev/ttymxc0 的读写操作来实现串口0 的数据收发。
3 /etc 目录
此目录下存放着各种配置文件,大家可以进入 Ubuntu etc 目录看一下,里面的配置文件 非常多!但是在嵌入式 Linux 下此目录会很简洁。
4 /lib 目录
lib library 的简称,也就是库的意思,因此此目录下存放着 Linux 所必须的库文件。这些库文件是共享库,命令和用户编写的应用程序要使用这些库文件。
5 /mnt 目录
临时挂载目录,一般是空目录,可以在此目录下创建空的子目录,比如 /mnt/sd /mnt/usb ,这样就可以将 SD 卡或者 U 盘挂载到 /mnt/sd 或者 /mnt/usb 目录中。
6 /proc 目录
此目录一般是空的,当 Linux 系统启动以后会将此目录作为 proc 文件系统的挂载点, proc是个虚拟文件系统,没有实际的存储设备。proc 里面的文件都是临时存在的,一般用来存储系统运行信息文件。
7 /usr 目录
要注意, usr 不是 user 的缩写,而是 Unix Software Resource 的缩写,也就是 Unix 操作系统软件资源目录。这里有个小知识点,那就是 Linux 一般被称为类 Unix 操作系统,苹果的 MacOS也是类 Unix 操作系统。关于 Linux Unix 操作系统的渊源大家可以直接在网上找 Linux 的发 展历史来看。既然是软件资源目录,因此/usr 目录下也存放着很多软件,一般系统安装完成以后此目录占用的空间最多。
8 /var 目录
此目录存放一些可以改变的数据。
9 /sbin 目录
此目录页用户存放一些可执行文件,但是此目录下的文件或者说命令只有管理员才能使用,主要用户系统管理。
10 /sys 目录
系统启动以后此目录作为 sysfs 文件系统的挂载点, sysfs 是一个类似于 proc 文件系统的特殊文件系统,sysfs 也是基于 ram 的文件系统,也就是说它也没有实际的存储设备。此目录是系统设备管理的重要目录,此目录通过一定的组织结构向用户提供详细的内核数据结构信息。
11 /opt
可选的文件、软件存放区,由用户选择将哪些文件或软件放到此目录中。关于 Linux 的根目录就介绍到这里,接下来的构建根文件系统就是研究如何创建上面这些子目录以及子目录中的文件。

二、BusyBox构建文件系统

1)BusyBox简介

BusyBox 是一个集成了大量的 Linux 命令和工具的软件,像 ls mv ifconfig 等命令 BusyBox 都会提供。 BusyBox 就是一个大的工具箱,这个工具箱里面集成了 Linux 的许多工具和命令。一般下载 BusyBox 的源码, 然后配置 BusyBox,选择自己想要的功能,最后编译即可。 BusyBox 可以在其官网下载到,官网地址为: https://busybox.net/ ,官网比较简陋,BusyBox 准备好以后就可以构建根文件系统了。
所以简单来说, 根文件系统里面就是一堆的可执行文件和其他文件组成的。

2)编译BusyBox构建根文件系统

一般我们在 Linux 驱动开发的时候都是通过 nfs 挂载根文件系统的,当产品最终上市开卖的时候才会将根文件系统烧写到 EMMC 或者 NAND 中,所以先要开启nfs功能,保证nfs服务能正常使用。

在nfs服务器目录中创建一个名为rootfs的子目录,用来存放我们的根文件系统。

busybox-1.29.0.tar.bz2发送到Ubuntu中的合适位置(我存放在 /home/xxpcb/myTest/imx6ull/dts)并解压:

tar -vxjf busybox-1.29.0.tar.bz2 

解压后的文件如下:

1 、修改Makefile添加编译器

注:这一步可以不修改,这里修改Makefile的目的是为了在编译时,可以不用在指定编译器的架构,从而可以缩短手动输入指令的长度。

如果坚持要修改Makefile,就是修改如下的地方,指定编译器与架构(本篇进行实验时没有修改)。

2、BusyBox中文支持

如果默认直接编译 busybox 的话,在使用 SecureCRT 的时候中文字符是显示不正常的,中文字 符会显示为“? ”,比如你的中文目录,中文文件都显示为“ ? ”。不知道从哪个版本开始 busybox中的 shell 命令对中文输入即显示做了限制,即使内核支持中文但在 shell 下也依然无法正确显示。
所以我们需要修改 busybox 源码,取消 busybox 对中文显示的限制。

打开文件busybox-1.29.0/libbb/printable_string.c,找到函数printable_string,把某些程序注释掉,修改后的函数内容如下:

主要就是禁止字符大于0X7F以后 break 和输出‘?’

接着打开文件busybox-1.29.0/libbb/unicode.c,修改如下内容:

3、配置 busybox

有以下几种配置选项:

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

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

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- defconfig 

busybox也支持图形化配置,通过图形化配置我们可以进一步选择自己想要的功能,输入如下命令打开图形化配置界面:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

  • (1) 设置Settings -> Build static binary (no shared libs)

选项“Build static binary (no shared libs)”用来决定是静态编译busybox 还是动态编译,静态编译的话就不需要库文件,但是编译出来的BusyBox会很大。动态编译的话要求根文件系统中有库文件,但是编译出来的 BusyBox会小很多。这里我们不能采用静态编译,因为采用静态编译的话 DNS 会出问题!无法进行域名解析

  • (2) 设置Settings -> vi-style line editing commands

这个要勾选,通过按键“y”实现勾选,使得方括号内出现星号

  • (3) 配置Linux Module Utilities -> Simplified modutils

默认会选中“Simplified modutils” ,这里我们要取消勾选! 使用键盘上的“n”键取消方括号中的星号。

  • (4) 配置Linux System Utilities -> mdev (16 kb)

确保下面的全部选中,默认都是选中

  • (5) 设置Settings -> Support Unicode

要将默认没有勾选的Check $LC_ALL选中

最后按两下ESC退出设置,并选择YES保存

4、 编译busybox构建根文件系统

输入如下指令进行编译:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- install CONFIG_PREFIX=/home/xxpcb/myTest/nfs/rootfs

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

rootfs目录下有bin、sbin和usr三个目录,以及linuxrc文件。Linux内核linit进程最后会查找用户空间的init程序,找到以后就会运行这个用户空间的init程序,从而切换到用户态。如果bootargs设置init=/linuxrc,那么linuxrc就是可以作为用户空间的init程序。

5、根文件系统添加lib库

Linux 中的应用程序一般都是需要动态库的,当然你也可以编译成静态的,但是静态的可执行文件会很大。如果编译为动态的话就需要动态库,所以我们需要向根文件系统中添加动态库。
5.1 向rootfs/lib中添加

上面的busybox使用的是动态库编译,所以还需要向根文件系统中添加动态库

先在rootfs中创建一个名为“lib”的文件夹。lib库文件从交叉编译器中获取,之前搭建交叉编译环境的时候将交叉编译器存放到了“/usr/local/arm/”目录中,进入对应的目录:

cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib 

此目录下有很多的so和.a 文件,这些就是库文件,将此目录下所有的so和.a文件都拷贝到 rootfs/lib 目录中:

cp *so* *.a /home/xxpcb/myTest/nfs/rootfs/lib/ -d 

后面的“-d”表示拷贝符号链接,这里有个比较特殊的库文件:ld-linux-armhf.so.3,此库文件也是个符号链接,相当于 Windows 下的快捷方式。会链接到库 ld-2.19-2014.08-1-git.so 上,输入命令如下指令查看此文件详细信息:

ls ld-linux-armhf.so.3 -l

ld-linux-armhf.so.3 后面有个“->” ,表示其是个软连接文件,链接到文件ld-2.19-2014.08-1-git.so,因为其是一个“快捷方式” ,因此大小只有 24B。但是,ld-linux-armhf.so.3不能作为符号链接,否则的话在根文件系统中执行程序无法执行!所以我们需要重新复制ld-linux- armhf.so.3,替换掉这个软链接。

先删除这个软连接文件:

rm ld-linux-armhf.so.3

然后重新进入到 /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm- linux-gnueabihf/libc/lib 目录中,重新拷贝ld-linux-armhf.so.3,命令如下:

cp ld-linux-armhf.so.3 /home/xxpcb/myTest/nfs/rootfs/lib/

拷贝完成以后再到 rootfs/lib 目录下查看ld-linux-armhf.so.3文件详细信息,此时ld-linux-armhf.so.3 已经不是软连接了,而是实实在在的一个库文件,而且文件大小为 724392B。

继续进入如下目录中:

cd /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/lib

此目录下也有很多的的so和.a 库文件,我们将其也拷贝到 rootfs/lib 目录中,命令如下:

cp *so* *.a /home/xxpcb/myTest/nfs/rootfs/lib/ -d 

rootfs/lib 目录的库文件就这些了,完成以后的rootfs/lib目录如图:

5.2 向rootfs/usr/lib中添加

rootfs/usr目录下创建一个名为lib的目录, 将如下目录中的库文件拷贝到rootfs/usr/lib目录下:

/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/lib

将此目录下的so和.a 库文件都拷贝到rootfs/usr/lib目录中:

cp *so* *.a /home/xxpcb/myTest/nfs/rootfs/usr/lib/ -d

完成以后的rootfs/usr/lib目录为:

至此,根文件系统的库文件就全部添加好了,可以在rootfs目录下使用“du”命令来查看一下/lib和/usr/lib 这两个目录的大小:

du ./lib ./usr/lib/ -sh  

6、创建其他文件夹

在根文件系统中创建其他文件夹,如 dev、proc、mnt、sys、tmp 和 root 等,创建完后的效果:

三、根文件系统初步测试

bootargs环境变量设置

使用NFS挂载的方式来测试上面创建好的根文件系统rootfs。

uboot里面的bootargs环境变量会设置root的值,需要将root的值改为NFS挂载,设置格式如为:

root=/dev/nfs nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>] ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip> 
  • <server-ip>:服务器IP,存放根文件系统的Ubuntu的IP地址,比如我的192.168.5.105。
  • <root-dir> :根文件系统的存放路径,比如我的就是/home/xxpcb/myTest/nfs/rootfs。
  • <nfs-options>:NFS 的其他可选选项,一般不设置。
  • <client-ip> :客户端IP ,开发板的IP地址,Linux内核启动以后就会使用此IP地址来配置开发板。我的为92.168.5.102。
  • <gw-ip> :网关地址,我的就是 192.168.5.1。
  • <netmask>:子网掩码,我的就是 255.255.255.0。
  • <hostname>:客户机的名字,一般不设置,此值可以空着。
  • <device> :设备名,也就是网卡名,一般是 eth0,eth1….,正点原子与野火的开发板均为ENET2为eth0,ENET1为eth1。这里我们使用ENET2,所以网卡名就是 eth0。
  • <autoconf> :自动配置,一般不使用,所以设置为 off。
  • <dns0-ip>:DNS0 服务器 IP 地址,不使用。
  • <dns1-ip> :DNS1 服务器 IP 地址,不使用。

根据上面的格式bootargs环境变量的root值如下:

root=/dev/nfs nfsroot=192.168.5.105:/home/xxpcb/myTest/nfs/rootfs,proto=tcp rw ip=192.168.5.102:192.168.5.105:192.168.5.1:255.255.255.0::eth1:off

启动开发板,串口连接开发板,进入uboot命令行模式,然后设置bootargs环境变量,命令如下:

setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.5.105:/home/xxpcb/myTest/nfs/rootfs,proto=tcp rw ip=192.168.5.102:192.168.5.105:192.168.5.1:255.255.255.0::eth1:off' 
saveenv  

设置好以后使用“boot”命令启动Linux内核

Linux内核的启动还是按照上一篇介绍的,使用tftp将zImage和设备树传输到开发板中运行

这里注意一下,因为此次测试,将zImage和dtb文件移入了tftp目录中的nxp文件夹中,所以传输指令需要修改一下:

setenv bootcmd 'tftp 80800000 nxp/zImage; tftp 83000000 nxp/imx6ull-myboard.dtb; bootz 80800000 - 83000000' 
saveenv

然后就可以使用boot命令来进行tftp传输了。

四、完善根文件系统

4.1 创建 /etc/init.d/rcS 文件
rcS 是个 shell 脚本, Linux 内核启动以后需要启动一些服务,而 rcS 就是规定启动哪些文件的脚本文件。
4.2 创建 /etc/fstab 文件
rootfs 中创建 /etc/fstab 文件, fstab Linux 开机以后自动配置哪些需要自动挂载的分区
4.3 创建 /etc/inittab 文件
inittab 的详细内容可以参考 busybox 下的文件 examples/inittab init 程序会读取 /etc/inittab这个文件,inittab 由若干条指令组成。每条指令的结构都是一样的,由以“ : ”分隔的 4 个段组成

资料参考:i.MX6ULL嵌入式Linux开发4-根文件系统构建 - 知乎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值