其他分享
首页 > 其他分享> > 根文件系统构建

根文件系统构建

作者:互联网

简介

根文件系统
根文件系统其实就是将一些Linux系统所必须的文件放在一起,就是我们平时使用的目录。

busybox构建根文件系统

根文件系统又那么多目录、文件,如果我们手动去构建根文件系统,肯定是非常麻烦,所以就有了构建根文件系统的工具。

常见的根文件系统构建工具有:busybox、buildroot、yocto。

busybox没有后面两种那么全自动,可以让我们理解到构建的过程,更适于学习。buildroot 和yocto比较稳定、成熟适用于产品。

为了方便调试将构建出的根文件系统放在虚拟机目录nfs下,使用nfs网络挂载的方式来挂载根文件系统。

busybox官网 我们需要从官网下载源码。

修改交叉编译器

打开顶层Makefile,修改ARCH、CROSS_COMPILE(绝对路径),改成我们自己的交叉编译器

修改支持中文

busybox构建的根文件系统默认不支持中文,我们需要修改几个文件。

busybox-1.29.0/libbb/printable_string.c 找到printable_string 函数:

1.将以下2行注释:
if (c >= 0x7f)		
	break;

2.将
if (c < ' ' || c >= 0x7f)
改为:                       
if (c < ' ')

busybox-1.29.0/libbb/unicode.c 找到 unicode_conv_to_printable2 函数:

1.将
*d++ = (c >= ' ' && c < 0x7f) ? c : '?';
改成:
*d++ = (c >= ' ') ? c : '?';

2.将
if (c < ' ' || c >= 0x7f)
改成:
if (c < ' ')

反正将一切与c 0x7f 有关的都改一下,最后需要用图形界面使用unicode。

配置busybox

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

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

我们选择默认配置 make defconfig。

除此之外还有配置图形界面(细节看原子文档)。

然后

make 
make install CONFIG_PREFIX=安装路径

完成后会在安装目录会产生以下文件:大多是一些命令(动态编译,缺少库文件),busybox中包含许多Linux命令。
在这里插入图片描述
Linuxxrc 用户空间的初始化程序,内核init 进程最终会找到用户层的init程序并运行,从而切换到用户层。如果 bootargs 设置 init=/linuxrc,那么 linuxrc 就是可以作为用户空间的 init 程序,所以用户态空间的 init 程序是 busybox 来生成的。

但是目前只有命令程序,缺少库文件是没有办法执行的。

移植需要的动态库

在我们的根文件系统根目录下创建lib文件夹存放库文件:

mkdir lib

库从哪里来? 为了方便直接从交叉编译器的lib目录下拷贝,该目录有许多库文件。
我的交叉编译器lib路径:
/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib

拷贝所有的动态库、静态库:

cp *so* *.a /home/zjh/IMX6ULL/linux/nfs/rootfs/lib  -d		#-d表示拷贝符号链接

其中ld-linux-armhf.so.3 是一个软链接, 我们删除重新拷贝。

更多看正点原子文档。

拷贝完成后文件夹的大小。
在这里插入图片描述
在根文件系统中创建其他文件夹,如 dev、proc、mnt、sys、tmp 和 root 等。

启动测试

构建完成,启动测试。

需要修改bootargs变量,在Linux内核 Documentation/filesystems/nfs/nfsroot.txt 文档有讲解修改的方法。

格式如下:

root=/dev/nfs nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>] ip=<client-ip>:<server-ip>:<gwip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip

:服务器 IP 地址,也就是存放根文件系统主机的 IP 地址,那就是 Ubuntu 的 IP地址,比如我的 Ubuntu 主机 IP 地址为 192.168.1.250。
:根文件系统的存放路径,比如我的就是/home/zuozhongkai/linux/nfs/rootfs。
:NFS 的其他可选选项,一般不设置。
:客户端 IP 地址,也就是我们开发板的 IP 地址,Linux 内核启动以后就会使用此 IP 地址来配置开发板。此地址一定要和 Ubuntu 主机在同一个网段内,并且没有被其他的设备使用,在 Ubuntu 中使用 ping 命令 ping 一下就知道要设置的 IP 地址有没有被使用,如果不能ping 通就说明没有被使用,那么就可以设置为开发板的 IP 地址,比如我就可以设置为192.168.1.251。
:服务器 IP 地址,前面已经说了。
:网关地址,我的就是 192.168.1.1。
:子网掩码,我的就是 255.255.255.0。
:客户机的名字,一般不设置,此值可以空着。
:设备名,也就是网卡名,一般是 eth0,eth1….,正点原子的 I.MX6U-ALPHA 开
发板的 ENET2 为 eth0,ENET1 为 eth1。如果你的电脑只有一个网卡,那么基本只能是 eth0。
这里我们使用 ENET2,所以网卡名就是 eth0。
:自动配置,一般不使用,所以设置为 off。
:DNS0 服务器 IP 地址,不使用。
:DNS1 服务器 IP 地址,不使用。

setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.2.9:/home/zjh/IMX6ULL/linux/nfs/rootfs,proto=tcp rw ip=192.168.2.10:192.168.2.9:192.168.2.1:255.255.255.0::eth0:off'		#设置bootargs
savenv   #保存环境变量

完善根文件系统

创建创建/etc/init.d/rcS 文件

成功启动后提示了缺少rcS文件的错误:
在这里插入图片描述

rcS 是个 shell 脚本,Linux 内核启动以后需要启动一些服务,而 rcS 就是规定启动哪些文件(应该是包括可执行程序和脚本文件)的脚本文件。

创建/etc/init.d/rcS,写入如下内容:

1 #!/bin/sh
2 
3 PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH			
4 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
5 export PATH LD_LIBRARY_PATH						
6 
7 mount -a
8 mkdir /dev/pts
9 mount -t devpts devpts /dev/pts
10
11 echo /sbin/mdev > /proc/sys/kernel/hotplug
12 mdev -s

PATH: 决定了可执行文件的搜索路径。
LD_LIBRARY_PATH: 库文件的搜索路径。
export: 用于导出上面这些环境变量,相当于声明一些“全局变量”。
mount -a: a是all 的意思,表示挂载所有文件系统。这些文件系统由 /etc/fstab 文件决定,一会创建 /etc/fstab 文件。

第 8 和 9 行,创建目录/dev/pts,然后将 devpts 挂载到/dev/pts 目录中。
第 11 和 12 行,使用 mdev 来管理热插拔设备,通过这两行,Linux 内核就可以在/dev 目录下自动创建设备节点。 关于 mdev 的详细内容可以参考 busybox 中的 docs/mdev.txt 文档。

创建好文件/etc/init.d/rcS 以后一定要给其可执行权限!

这只是我们自己构建的小系统的rcS文件,极其精简。像ubuntu这些大系统rcS内容很复杂,并且是用工具构建的,例如buildroot。

创建/etc/fstab 文件

接着提示了/etc/fstab的错误:
在这里插入图片描述

在 rootfs 中创建/etc/fstab 文件,fstab 在 Linux 开机以后自动配置哪些需要自动挂载的分区,格式如下:

file system: 要挂载的特殊的设备,也可以是块设备,比如/dev/sda 等等。
mount point: 挂载点。
**type:**文件系统类型,比如 ext2、ext3、proc、romfs、tmpfs 等等。
options: 挂载选项,在 Ubuntu 中输入“man mount”命令可以查看具体的选项。一般使用 defaults,也就是默认选项,defaults 包含了 rw、suid、 dev、 exec、 auto、 nouser 和 async。
dump: 为 1 的话表示允许备份,为 0 不备份,一般不备份,因此设置为 0。
pass: 磁盘检查设置,为 0 表示不检查。根目录‘/’设置为 1,其他的都不能设置为 1,其他的分区从 2 开始。一般不在 fstab 中挂载根目录,因此这里一般设置为 0。

按照上述格式,在 fstab 文件中输入如下内容:

1 #<file system> <mount point> <type> <options> <dump> <pass>
2 proc /proc proc defaults 0 0
3 tmpfs /tmp tmpfs defaults 0 0
4 sysfs /sys sysfs defaults 0 0

创建/etc/inittab 文件

完成后重启系统,没有报错,但是还需要创建一个 /etc/inittab 文件。

inittab 的详细内容可以参考 busybox 下的文件 examples/inittab。init 程序会读取/etc/inittab这个文件,inittab 由若干条指令组成。 每条指令的结构都是一样的,由以“:”分隔的 4 个段组成,格式如下:

:::

id: 每个指令的标识符,不能重复。但是对于 busybox 的 init 来说,有着特殊意义。对于 busybox 而言用来指定启动进程的控制 tty一般我们将串口或者 LCD 屏幕设置为控制 tty 。
runlevels: 对 busybox 来说此项完全没用,所以空着。
action: 动作,用于指定可能用到的动作。busybox 支持的动作如下表所示:
在这里插入图片描述
process: 具体的动作,比如程序、脚本或命令等。

busybox中的/etc/inittab 文件内容如下:

1 #/etc/inittab
2 ::sysinit:/etc/init.d/rcS
3 console::askfirst:-/bin/sh
4 ::restart:/sbin/init
5 ::ctrlaltdel:/sbin/reboot
6 ::shutdown:/bin/umount -a -r
7 ::shutdown:/sbin/swapoff -a

sysinit: 系统启动时执行/etc/init.d/rcS 脚本。
console: 指定console 为控制tty,也就是 ttymxc0 。
restart: 重启的话运行 /sbin/init 。
ctrlaltdel: 按下 ctrl+alt+del 组合键的话就运行/sbin/reboot,看来 ctrl+alt+del 组合键用于重启系统。
shutdown: 关机的时候执行/bin/umount,也就是卸载各个文件系统。
shutdown: 关机的时候执行/sbin/swapoff,也就是关闭交换分区。

创建完成,重启开发板即可。

接下来就要对根文件系统进行其他的测试,比如是我们自己编写的软件运行收费正常、是否支持软件开机自启动、中文支持是否正常以及能不能链接等。

根文件系统其他功能测试

软件运行测试

写一个可执行程序,交叉编译看看能否正常运行,例如hello world。

中文字符测试

1、设置 SecureCRT 使用 UTF-8 编码

因为 Linux 使用的编码格式为 UTF-8,因此要先设置 SecureCRT 的编码格式。

2、创建中文路径、文件

创建中文路径、文件,中文内容都正常显示。

开机自启动测试

通常我们执行可执行程序都是手动执行,但是一个产品可能需要开机自动执行,那么可以通过修改/etc/init.d/rcS 来完成自启动。

前面我们说过了,进入根文件系统的时候会运行/etc/init.d/rcS 这个 shell 脚本,因此我们可以在这个脚本里面添加自启动相关内容。添加
完成以后的/etc/init.d/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 #开机自启动hello world		
16 cd /drivers
17 ./hello &
18 cd /

通常并不直接修改 rcS 脚本,而是通过它来调动另一个脚本。

互联网测试

ping www.baidu.com
如果提示域名解析失败,那么添加 /etc/resolv.conf 文件,内容如下:

1 nameserver 114.114.114.114
2 nameserver 192.168.1.1

nameserver 表示这是个域名服务器,设置了两个域名服务器地址:114.114.114.114 和 192.168.1.1,大家也可以改为其他的域名服务器试试。如果使用“udhcpc”命令自动获取 IP 地址,“udhcpc”命令会修改 nameserver 的值,一般是将其设置为对应的网关地址。

常用的DNS服务器: 114.114.114.114

标签:busybox,文件,文件系统,rcS,etc,init,构建
来源: https://blog.csdn.net/weixin_48006170/article/details/115264195