一起分析Linux系统设计思想——04构建根文件系统(三)

在学习资料满天飞的大环境下,知识变得非常零散,体系化的知识并不多,这就导致很多人每天都努力学习到感动自己,最终却收效甚微,甚至放弃学习。我的使命就是过滤掉大量的垃圾信息,将知识体系化,以短平快的方式直达问题本质,把大家从大海捞针的痛苦中解脱出来。

1 制作jffs2根文件系统镜像

1.1 制作jffs2工具

由于jffs2文件系统具有压缩功能,所以制作jffs2工具时需要zlib压缩库。

  1. 安装zlib动态库
# 在ubuntu系统中操作
albert@ubuntu:/work/jffs2 $ tar xzvf zlib-1.2.3.tar.gz #解压缩源码
albert@ubuntu:/work/jffs2/zlib-1.2.3 $ ./configure --shared #配置:需要生成动态库
albert@ubuntu:/work/jffs2/zlib-1.2.3 $ make #编译
albert@ubuntu:/work/jffs2/zlib-1.2.3 $ sudo make install #安装
albert@ubuntu:/work/jffs2/zlib-1.2.3 $ ls /usr/local/lib #查看发现安装成功(libz开头的三个动态库)
libz.so  libz.so.1  libz.so.1.2.3  python2.7  python3.4  site_ruby
  1. 安装jffs2工具
# 在ubuntu系统中操作
albert@ubuntu:/work/jffs2 $ tar xjvf mtd-utils-05.07.23.tar.bz2 #解压缩源码
albert@ubuntu:/work/jffs2/mtd-utils-05.07.23/util $ make #编译
albert@ubuntu:/work/jffs2/mtd-utils-05.07.23/util $ sudo make install #安装
albert@ubuntu:/work/jffs2/mtd-utils-05.07.23/util $ mkfs<按tab> #查看发现安装成功(mkfs.jffs2)
mkfs          mkfs.cramfs   mkfs.ext3     mkfs.ext4dev  mkfs.jffs     mkfs.minix    mkfs.ntfs     
mkfs.bfs      mkfs.ext2     mkfs.ext4     mkfs.fat      mkfs.jffs2    mkfs.msdos    mkfs.vfat  

1.2 制作jffs2根文件系统镜像

在上两篇中我们已经准备好了根文件系统的内容,下面只需要使用mkfs.jffs2工具制作成镜像即可。

# 在ubuntu系统中操作
albert@ubuntu:/work/nfsroot $ mkfs.jffs2<然后回车> #这样可以查看该工具的使用说明(各个参数的含义)。
...
albert@ubuntu:/work/nfsroot $ mkfs.jffs2 -d minifs -o minifs.jffs2 -s 2048 -e 128KiB -n #制作镜像
albert@ubuntu:/work/nfsroot $ ls -al #制作镜像成功,发现minifs.jffs2比minifs.yaffs2的一半还要小
-rw-r--r--  1 albert albert 4128688 Nov  2 22:18 minifs.jffs2
-rw-------  1 albert albert 8872512 Oct 31 23:19 minifs.yaffs2

1.3 配置uboot启动参数

下载我们刚刚制作的minifs.jffs2到嵌入式设备启动后报下述错误:

# S3C2440启动过程中的控制台打印
yaffs: dev is 32505859 name is "mtdblock3"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 31.3, "mtdblock3"
yaffs: auto selecting yaffs2 #这里默认挂载的根文件系统类型是yaffs2
block 649 is bad
block 1335 is bad
block 1991 is bad
VFS: Mounted root (yaffs filesystem). 
Freeing init memory: 140K
Warning: unable to open an initial console. #所以这里找不到/dev/console设备节点文件
Failed to execute /linuxrc.  Attempting defaults... #也找不到/linuxrc文件
Kernel panic - not syncing: No init found.  Try passing init= option to kernel. #init进程初始化失败

产生上述错误主要是内核默认情况下认为根文件系统的类型就是yaffs2。现在我们换成了jffs2,要通过某种方式告诉内核。这种方式就是配置uboot的启动参数。

修改前:bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200。

修改后:bootargs=noinitrd root=/dev/mtdblock3 rootfstype=jffs2 init=/linuxrc console=ttySAC0,115200

修改过程如下:

# 在S3C2440嵌入式设备中修改
# 使用uboot指令修改uboot启动参数
OpenJTAG> set bootargs noinitrd root=/dev/mtdblock3 rootfstype=jffs2 init=/linuxrc console=ttySAC0,115200 #设置启动参数
OpenJTAG> print bootargs #查看设置结果(此时只是修改了内存)
bootargs=noinitrd root=/dev/mtdblock3 rootfstype=jffs2 init=/linuxrc console=ttySAC0,115200
OpenJTAG> saveenv #保存修改结果到nand flash
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done

修改uboot启动参数之后重新启动系统成功。


2 配置nfs根文件系统

接下来,我们搞一个非常有意思的东西——让嵌入式设备直接从你电脑硬盘启动。这样,每次修改完根文件系统的代码或者应用程序代码,编译完直接放到指定目录就可以被嵌入式设备看到了。开发效率杠杠滴!!!

话不多说,我们马上开始。

2.1 保证嵌入式开发板可以ping通电脑

先简单说一下流程。首先要找一根网线连接嵌入式设备和电脑(我使用的是Ubuntu系统,不建议使用windows系统,否则还要装nfs服务器)。在电脑上(如果使用了虚拟机,记得网络访问使用桥接模式)配置一个静态调试IP(比如172.27.45.101),在嵌入式设备上配置同一网段的静态IP(比如172.27.45.250)。然后就能相互ping通了(说起来好轻松啊,鄙视的表情)。

这个过程中可能(或者说一定)会遇到些小问题,如果你装的是windows,在windows中装了一个虚拟机,然后在虚拟机中装的Ubuntu系统,那么恭喜你,你必须要花时间搞清楚两个问题:如何配置桥接模式并指定物理网卡;如何在Ubuntu系统中配置静态IP地址。(由于篇幅问题,这里就不展开了,相信你能搞定滴,实在不行可以留言或私信我~)

另外一个,就是在嵌入式设备上配置静态IP,这个我刚好写过博客,链接如下:

https://blog.csdn.net/weixin_44873133/article/details/105938190

ping通后的效果如下图:


2.2 开启nfs服务器

我们以Ubuntu系统为例说明如何开启nfs服务器。

先说一下nfs是个啥。nfs全拼net file system,所谓网络文件系统和我们接触过的yaffs2、jffs2有什么不同呢?最大的不同就是文件的内容是通过网络加载到内存中的,而flash类型的文件系统是通过读flash加载到内存中的。先理解到这里就可以了,抓住 主要矛盾 ,细节上的差异等研究文件系统实现的时候再 逐步 深入。

所以,开启nfs服务也就很好理解了,就是将nfs程序运行起来,并且指定一个目录允许别人通过网络访问而已。

下面具体操作一下。

  1. 修改/etc/exports配置文件
# 在Ubuntu系统内操作
albert@ubuntu:/etc $ sudo vi exports #注意需要使用root权限
# 在/etc/exports(Unbunt目录)文件中把允许挂载的路径添加进去
/work/nfsroot/minifs *(rw,sync,no_root_squash) #no_root_squash indicate the user has root authority
  1. 重启nfs服务器
# 在Ubuntu系统内操作
albert@ubuntu:/etc/init.d $ sudo ./nfs-kernel-server restart #重启nfs服务器
  1. 检查是否启动成功
# 在Ubuntu系统内操作(自己mount自己)
albert@ubuntu:~ $ sudo mount -t nfs 172.27.45.101:/work/nfsroot/minifs /mnt
albert@ubuntu:~ $ ls /mnt #自己mount自己成功
bin  dev  etc  lib  linuxrc  proc  sbin  sys  test  usr
# 在嵌入式设备终端上操作
/ # mount -t nfs 172.27.45.101:/work/nfsroot/minifs /mnt -o nolock #注意不要使用文件锁,否则会失败
/ # ls /mnt #已经成功mount到宿主机的路径
bin      etc      linuxrc  sbin     test
dev      lib      proc     sys      usr

2.3 配置uboot启动参数

修改前:bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200

修改后:bootargs=noinitrd root=/dev/nfs nfsroot=172.27.45.101:/work/nfsroot/minifs ip=172.27.45.250:172.27.45.101:172.27.45.1:255.255.255.0:albert:eth0:off init=/linuxrc console=ttySAC0,115200

修改过程如下:

# 在S3C2440嵌入式设备中修改
# 使用uboot指令修改uboot启动参数
OpenJTAG> set noinitrd root=/dev/nfs nfsroot=172.27.45.101:/work/nfsroot/minifs ip=172.27.45.250:172.27.45.101:172.27.45.1:255.255.255.0:albert:eth0:off init=/linuxrc console=ttySAC0,115200 #设置启动参数
OpenJTAG> saveenv #保存修改结果到nand flash
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done

下面对参数格式作一个说明(参考内核源码中/Documentation/nfsroot.txt)。

参数项参数格式说明
rootroot=/dev/nfs只是告诉内核使用nfs虚拟文件系统,其实并不存在/dev/nfs。
nfsrootnfsroot=[<server-ip>:]<root-dir>[,<nfs-options>]用来指定nfs服务器ip和根文件系统路径。nfs-options可以省略。
ipip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>主要作用是配置客户端(本地)的网卡和ip。我们是用网线直连,gw-ip填多少无所谓。hostname随便起,也可以空着。device一定要填对,是网卡名。autoconf自动配置选项关闭就可以了。

重新启动嵌入式设备,设备成功挂载nfs根文件系统并启动,如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BTroGOpU-1604419918925)(04%E6%9E%84%E5%BB%BA%E6%A0%B9%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%EF%BC%88%E4%B8%89%EF%BC%89.assets/image-20201104000517006.png)]

根文件系统的制作/移植就告一段落了,是不是还回味无穷呢~


恭喜你又坚持看完了一篇博客,又进步了一点点!如果感觉还不错就点个赞再走吧,你的点赞和关注将是我持续输出的哒哒哒动力~~

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穿越临界点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值