文件系统搭建

目录

  • 没有文件系统启动内核
  • 简介
  • vcode使用小插件
  • BusyBox 构建根文件系统
    • 编译 BusyBox 构建根文件系统
      • 1、修改 Makefile,添加编译器
      • 2、busybox 中文字符支持
      • 3、配置 busybox
      • 4、编译 busybox
  • 向根文件系统库文件
    • 1、向 rootfs 的“/lib”目录添加库文件
    • 2、向 rootfs 的“usr/lib”目录添加库文件
  • 创建其他文件夹
  • 根文件系统初步测试
    • 问题
    • 解决
  • 完善根文件系统
    • 创建/etc/init.d/rcS 文件
    • 创建/etc/fstab 文件
    • 创建/etc/inittab 文件
  • 根文件系统其他功能测试
    • 软件运行测试
    • 创建中文文件
    • 开机自启动测试
    • 外网连接测试
  • 烧写系统
    • OTG烧写
    • Ubuntu下脚本烧写

没有文件系统启动内核

设置环境变量,没有加载文件系统

bootargs=console=ttymxc0,115200

文件系统搭建_第1张图片

简介

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

根文件系统首先是内核启动时所 mount(挂载)的第一个文件系统,内核代码映像文件保存在根文件系统中,而系统引导启动程序会在根文件系统挂载之后从中把一些基本的初始化脚本和服务等加载到内存中去运行。

vcode使用小插件

korofileheader可用于头文件注释署名格式,第二个还有代码补全工具。

win:ctrl+alt+t

文件系统搭建_第2张图片
vscode注释

//注释:ctrl+/
/**/注释:alt+shift+a

通过路径打开文件
文件系统搭建_第3张图片

BusyBox 构建根文件系统

笔者测试 1.29.0 版本

编译 BusyBox 构建根文件系统

1、修改 Makefile,添加编译器

文件系统搭建_第4张图片

文件系统搭建_第5张图片

2、busybox 中文字符支持

当字符大于 0X7F 以后就跳出去了。
如果支持 UNICODE 码的话,当字符大于 0X7F 就直接输出‘?’。
文件系统搭建_第6张图片
文件系统搭建_第7张图片

3、配置 busybox

配置文件:

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

路径

-> Settings

文件系统搭建_第8张图片
文件系统搭建_第9张图片

-> Linux Module Utilities

文件系统搭建_第10张图片

-> Linux System Utilities

文件系统搭建_第11张图片

-> Settings

文件系统搭建_第12张图片
最后记得保存

4、编译 busybox

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

在这里插入图片描述
前面说过 Linux 内核 init 进程最后会查找用户空间的 init 程序,找到以后就会运行这个用户空间的 init 程序,从而切换到用户态。
如果 bootargs 设置 init=/linuxrc,那么 linuxrc 就是可以作为用户空间的 init 程序,所以用户态空间的 init 程序是 busybox 来生成的。
busybox 的工作就完成了,但是此时的根文件系统还不能使用,还需要一些其他的文件,还需要一些库文件。

向根文件系统库文件

1、向 rootfs 的“/lib”目录添加库文件

当然也可以压缩然后解压。

root@ubuntu:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib# 
cp *so* *.a /home/samba/linux/nfs/rootfs/lib/ -d

文件系统搭建_第13张图片

so(是通配符)和.a 文件,这些就是库文件,将此目录下所有的so*和.a 文件都拷贝到 rootfs/lib 目录中。

后面的“-d”表示拷贝符号链接,这里有个比较特殊的库文件:ld-linux-armhf.so.3,此库文件也是个符号链接,相当于Windows 下的快捷方式。

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

文件系统搭建_第14张图片

删除/home/samba/linux/nfs/rootfs/lib/目录下的文件
rm ld-linux-armhf.so.3
进入/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/armlinux-gnueabihf/libc/lib 目录中,重新拷贝 ld-linux-armhf.so.3
cp ld-linux-armhf.so.3 /home/samba/linux/nfs/rootfs/lib/

文件系统搭建_第15张图片

2、向 rootfs 的“usr/lib”目录添加库文件

root@ubuntu:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/lib#
cp *so* *.a /home/samba/linux/nfs/rootfs/usr/lib/ -d

文件系统搭建_第16张图片
在这里插入图片描述

创建其他文件夹

mkdir dev proc mnt sys tmp root

在这里插入图片描述

根文件系统初步测试

格式

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 地址。
<root-dir>:根文件系统。
<nfs-options>:NFS 的其他可选选项,一般不设置。
<client-ip>:客户端 IP 地址。
<gw-ip>:网关地址。
<netmask>:子网掩码。
<hostname>:客户机的名字,一般不设置,此值可以空着。
<device>:设备名,也就是网卡名,一般是 eth0,eth1….,正点原子的 I.MX6U-ALPHA 开发板的 ENET2 为 eth0,ENET1 为 eth1。如果你的电脑只有一个网卡,那么基本只能是 eth0。这里我们使用 ENET2,所以网卡名就是 eth0。
<autoconf>:自动配置,一般不使用,所以设置为 off。
<dns0-ip>:DNS0 服务器 IP 地址,不使用。
<dns1-ip>:DNS1 服务器 IP 地址,不使用。

“proto=tcp”表示使用 TCP 协议,“rw”表示 nfs 挂载的根文件系统为可读可写。
设置 bootargs

setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.108.154:/home/samba/linux/nfs/rootfs,proto=tcp rw ip=192.168.108.66:192.168.108.154:192.168.108.113:
255.255.255.0::eth0:off' 

问题

VFS: Unable to mount root fs via NFS, trying floppy.
VFS: Cannot open root device "nfs" or unknown-block(2,0): error -6
Please append a correct "root=" boot option; here are the available partitions:
0100           65536 ram0  (driver?)
0101           65536 ram1  (driver?)
0102           65536 ram2  (driver?)
0103           65536 ram3  (driver?)
0104           65536 ram4  (driver?)
0105           65536 ram5  (driver?)
0106           65536 ram6  (driver?)
0107           65536 ram7  (driver?)
0108           65536 ram8  (driver?)
0109           65536 ram9  (driver?)
010a           65536 ram10  (driver?)
010b           65536 ram11  (driver?)
010c           65536 ram12  (driver?)
010d           65536 ram13  (driver?)
010e           65536 ram14  (driver?)
010f           65536 ram15  (driver?)
b300         7634944 mmcblk1  driver: mmcblk
  b301          131072 mmcblk1p1 452c2dfe-01
  b302         7493632 mmcblk1p2 452c2dfe-02
b330             512 mmcblk1rpmb  (driver?)
b320            4096 mmcblk1boot1  (driver?)
b310            4096 mmcblk1boot0  (driver?)
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)
---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)
random: nonblocking pool is initialized

手动挂载可以
文件系统搭建_第17张图片

解决

这里是通过该博主方法解决的

以前使用的16.04版本的ubuntu没问题,现在更换了18.04.4版本,开始报错。
从Ubuntu17.04开始,nfs默认只支持协议3和协议4,而kernel中默认支持协议2。

  1. 修改 NFS 配置文件:
sudo gedit /etc/default/nfs-kernel-server
  1. 在末尾添加:
RPCNFSDOPTS="--nfs-version 2,3,4 --debug --syslog"

文件系统搭建_第18张图片
文件系统搭建_第19张图片
无法运行“/etc/init.d/rcS”这个文件,因为这个文件不存在。

完善根文件系统

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

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

Ubuntu 或者其他大型 Linux操作系统中的 rcS 文件,就会发现其非常复杂。而且这么复杂的 rcS 文件也是借助其他工具创建的,比如 buildroot 等

#!/bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
export PATH LD_LIBRARY_PATH 
mount -a 
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

给予/ec/init.d/rcS 可执行权限:

chmod 777 rcS

启动测试
这里的报错是因为rcS写错了,写成这样了。

mount -a  8 mkdir /dev/pts
mount -t devpts devpts /dev/pts
There are filesystem-specific -o flags.
mount: mounting devpts on /dev/pts failed: No such file or directory
/etc/init.d/rcS: line 8: can't create /proc/sys/kernel/hotplug: nonexistent directory
mdev: /sys/dev: No such file or directory

改过来测试
在这里插入图片描述

创建/etc/fstab 文件

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

格式如下:

<file system> <mount point> <type> <options> <dump> <pass>
<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
# 	 	 	 	 	 
proc 		/proc 		proc 	defaults 	0 	0 
tmpfs 		/tmp 		tmpfs 	defaults 	0 	0 
sysfs 		/sys 		sysfs 	defaults 	0 	0

文件系统搭建_第20张图片

创建/etc/inittab 文件

inittab 的详细内容可以参考 busybox 下的文件 examples/inittab。init 程序会读取/etc/inittab这个文件

格式如下:

<id>:<runlevels>:<action>:<process>

文件系统搭建_第21张图片

<id>:每个指令的标识符,不能重复。但是对于 busybox 的 init 来说,<id>有着特殊意义。
对于 busybox 而言<id>用来指定启动进程的控制 tty,一般我们将串口或者 LCD 屏幕设置为控
制 tty。
<runlevels>:对 busybox 来说此项完全没用,所以空着。
<action>:动作,用于指定<process>可能用到的动作。
<process>:具体的动作,比如程序、脚本或命令等
#etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r ::shutdown:/sbin/swapoff -a
#第 2 行,系统启动以后运行/etc/init.d/rcS 这个脚本文件。
#第 3 行,将 console 作为控制台终端,也就是 ttymxc0。 
#第 4 行,重启的话运行/sbin/init。 
#第 5 行,按下 ctrl+alt+del 组合键的话就运行/sbin/reboot,看来 ctrl+alt+del 组合键用于重启系统。
#第 6 行,关机的时候执行/bin/umount,也就是卸载各个文件系统。
#第 7 行,关机的时候执行/sbin/swapoff,也就是关闭交换分区。

至此!根文件系统要创建的文件就已经
全部完成了

根文件系统其他功能测试

软件运行测试

root@ubuntu:/home/samba/linux/nfs/rootfs/test# ls
hello  hello.c
root@ubuntu:/home/samba/linux/nfs/rootfs/test# file hello
hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.31, BuildID[sha1]=7dd1bde89e09327b11ad95e22e72f9bfafd8aecb, with debug_info, not stripped

文件系统搭建_第22张图片

创建中文文件

在vi编辑中是没有显示中文的。但cat有
文件系统搭建_第23张图片

文件系统搭建_第24张图片

开机自启动测试

hello 这个软件为例,实现开机自启动。进入根文件系统的时候会运行/etc/init.d/rcS 这个 shell 脚本。

#!/bin/sh

PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib

runlevel=S
umask 022
export PATH LD_LIBRARY_PATH runlevel

mount -a 
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

#开机自启动
cd /drivers
./hello &
cd /

启动测试
文件系统搭建_第25张图片

外网连接测试

文件系统搭建_第26张图片

个“bad address”,也就是地址不对,之所以出现这个错误提示是因为 www.baidu.com的地址解析失败了,并没有解析出其对应的 IP 地址。我们需要配置域名解析服务器的 IP地址,一般域名解析地址可以设置为所处网络的网关地址,比如 192.168.1.1。也可以设置为 114.114.114.114,这个是运营商的域名解析服务器地址。

新建文件/etc/resolv.conf

nameserver 114.114.114.114
nameserver 192.168.1.1

文件系统搭建_第27张图片
OK,大功告成,我们可以把uboot,kernel,rootfs保存起来,然后烧写到开发板进行驱动的学习。

烧写系统

OTG烧写

文件系统搭建_第28张图片
文件系统搭建_第29张图片
文件系统搭建_第30张图片
文件系统搭建_第31张图片
切换emmc启动

Ubuntu下脚本烧写

先把整个files文件移植到虚拟机,注意这里得用正点原子官方出厂的文件。文件系统搭建_第32张图片

格式化卡,和给脚本权限。

root@ubuntu:/home/samba/files# ls -l
总用量 40
drwxr-xr-x 2 root root 4096 41 18:35 boot
drwxr-xr-x 2 root root 4096 41 18:37 filesystem
-rwxrwxrwx 1 root root 6781 85  2021 imx6mkemmcboot.sh
-rwxrwxrwx 1 root root 5360 85  2021 imx6mknandboot.sh
-rwxrwxrwx 1 root root 7697 1124 16:20 imx6mksdboot.sh
drwxr-xr-x 2 root root 4096 41 18:35 modules
-rwxr--r-- 1 root root 2639 85  2021 README.txt

开始烧写sd卡

./imx6mksdboot.sh  -device /dev/sdc -flash emmc -ddrsize 512

文件系统搭建_第33张图片

三个分区,还有uboot没有出现,如果文件系统分区没有出现请拔插sd卡。
在这里插入图片描述
文件系统搭建_第34张图片

sd卡启动
fdisk -l文件系统搭建_第35张图片

./imx6mkemmcboot.sh -device /dev/mmcblk1 -ddrsize 512

这个是6ull自己烧所以比较慢。
文件系统搭建_第36张图片
切换emmc启动。
设置一下环境变量

在这里插入图片描述
这里内核设备数没问题,但文件系统好像还是有问题
在这里插入图片描述
这里采用nfs挂载启动一下
这里设置网络环境变量文件系统搭建_第37张图片

文件系统搭建_第38张图片

你可能感兴趣的:(linux系统篇,linux,bash,stm32)