06 - 文件系统(下)

---- 整理自 王利涛老师 课程
实验环境:宅学部落 www.zhaixue.cc

上一篇不迷路: 06 - 文件系统(上)

15. 根文件系统

15.1 根文件系统的基本概念

  • 什么是根文件系统?
  • 根文件系统和一般文件系统有什么区别?
  • 为什么需要根文件系统?
  • 根文件系统的目录
  • VFS 和根文件系统是什么关系?
  • 如何指定根文件系统?

15.2 挂载根文件系统的三种方式

在这里插入图片描述

15.3 根文件系统的挂载

15.3.1 rootfs 文件系统的概念

  • rootfs 的作用
    • 子文件系统挂载到父文件系统上,那么最上层文件系统挂载到哪里?根文件系统肯定是挂载到根目录上,根目录是哪里来的?这就是 rootfs 的作用,在挂载根文件系统之前,完成一些基本环境的初始化,后续才能去挂载我们真正的根文件系统。
  • 为什么不直接挂载分区,而先使用 rootfs?
  • rootfs 和根文件系统是什么关系?
    • 不是一个概念
  • rootfs 和根目录的关系?
  • 第一个根目录 “ / ” 何时创建的?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

rootfs 文件系统设置了自己的根目录和当前目录为 " / "。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
根据 rootfs_fs_type 可知,实际调用到 rootfs_init_fs_context:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

回到 vfs_kern_mount 中调用 fc_mount:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

回到 fc_mount:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

15.3.2 root= 参数分析

  • root=/dev/mmcblk0 挂载 SD 卡为根文件系统
  • root=/dev/nfs 挂载NFS为根文件系统:根据 root 参数挂载指定的根文件系统
  • noinitrd 启动参数
  • init=/linuxrc 启动
"tftp 0x60003000 uImage;tftp 0x60800000 vexpress-v2p-ca9.dtb;setenv bootargs 'root=/dev/nfs rw nfsroot=192.168.33.145:/home/nfs,proto=tcp,nfsvers=3,nolock init=/linuxrc ip=192.168.33.144 console=ttyAMA0';bootm 0x60003000 - 0x60800000;"

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

"tftp 0x60003000 uImage;tftp 0x60800000 vexpress-v2p-ca9.dtb;setenv bootargs 'root=/dev/nfs rw nfsroot=192.168.33.145:/home/nfs,proto=tcp,nfsvers=3,nolock init=/linuxrc ip=192.168.33.144 console=ttyAMA0';bootm 0x60003000 - 0x60800000;"
# 其中包含 init=/linuxrc

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

回到这里的代码:
在这里插入图片描述

我们当前进程的当前目录 current->pwd 设置为了 "/root" 目录。但是当前进程的根目录 current->root 还是 "/"

在这里插入图片描述
在这里插入图片描述
这里的 current 定义如下:
在这里插入图片描述

再回到代码的这里:
在这里插入图片描述
init_mount 改变挂载点,NFS 文件系统本来挂载在"/root" 目录,现在移动到根目录 “/”,如下图中的红色虚线。
init_chroot 将当前目录也就是 “/root” 设置为根目录 “/”,如图中的红色实线。这样,NFS 就成了根文件系统。

在这里插入图片描述

15.3.3 根目录“ / ”

  • 作用是什么?
  • 什么时候初始化的?
  • 根文件系统和根目录是什么关系?
  • rootfs 的根目录: /
  • NFS 的根目录 :/root -> vfsmount->mnt_root
  • 一个系统中允许多个 “/” 吗?
  • 根目录可以切换吗?

在这里插入图片描述

16. 使用 initrd 作为根文件系统:CPIO 格式

initrd 总的来说目前有两种格式:image 格式和 cpio 格式。image 格式也叫文件系统镜像文件(老式块设备的 initrd 文件),主要在 linux 2.4 内核中使用流行;在linux 2.5 内核开始引入 initramfs 技术,initramfs 实际上已经克服了 imgae-initrd 的缺点,本质上也是 cpio 格式的 initrd,只不过是和内核编译到了一个 image 文件,放在了 .init.ramfs 段内;到 linux 2.6 的内核支持两种格式的 initrd,即 image-initrd 和 cpio-initrd,此时的 cpio-initrd 文件已不再编译进内核而单独成一文件,使用 cpio 工具生成。https://blog.51cto.com/u_15064644/4817854

16.1 initrd 和 ramdisk

  • 什么是 ramdisk?
  • 什么是 initrd?
  • 为什么会有 initrd?
  • Linux 内核在初始化之后会启动一个 init 进程,在这个 init 进程中挂载根文件系统,但是 init 进程的二进制 bin 文件是存储在文件系统中的,所以这就有了先有鸡还是先有蛋的问题。为了解决这个问题,内核采用了两步走的方法:除了内核镜像外,还有一个独立的 initrd.img 镜像,内核会先 mount 这个镜像作为根文件系统,然后执行 initrd 中的 /linuxrc 或者 /init 来挂载真正的根文件系统。
  • initrd 和 ramdisk 的关系,其实就像 系统备份镜像C 盘 的关系,普通的根文件系统数据(包括二进制文件、脚本、配置文件、目录等)是存放在磁盘中的,因为 ramdisk 是在内存中模拟的一块磁盘设备,断电后数据不会永久保存,所以我们需要一个备份镜像保存在磁盘上,在系统启动时,将备份数据镜像加载到内存中的 ramdisk 中就可以了,而 initrd 就是根文件系统的备份镜像,为了节省体积,还会支持各种压缩格式,加载到内核中再解压。
  • 如何制作 initrd 镜像?
    通过 ramdisk
    通过 loopback
    cpio 格式:find . | cpio -o -H newc | gzip -c > ../initrd.gz
  • 如何设置 root、initrd 参数挂载 initrd?
    root=
    initrd=
    rdinit=/linuxrc

16.2 内核配置

因为 initrd 基于 ramdisk 实现,所以内核需要支持 initrd 和 ramdisk 功能。

在这里插入图片描述
在这里插入图片描述
注:ramdisk 大小设置为了 4M,下面会用到。

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- vexpress_defconfig -j$(nproc)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig -j$(nproc)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j$(nproc)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- uImage LOADADDR=0x60003000 -j$(nproc)

16.3 uboot 配置

使用 initrd 作为根文件系统,需要在启动参数中指定,然后传输给内核,在嵌入式系统中,一般可以通过 uboot 的 bootcmd 和 bootargs 来传递。

在这里插入图片描述

tftp 0x60003000 uImage;tftp 0x60500000 vexpress-v2p-ca9.dtb;tftp 0x62000000 initrd.gz;setenv bootargs 'initrd=0x62000000,4M root=/dev/ram0 rw rdinit=/linuxrc console=ttyAMA0';bootm 0x60003000 - 0x60500000;

16.4 制作 initrd 镜像

  1. 基于之前的 NFS 镜像文件制作 initrd 镜像,NFS 镜像文件如下,大小为 26M,大于 4M。

在这里插入图片描述

  1. 先拷贝一份 NFS 的镜像文件,然后删除其中 lib 目录下的库文件,只保留 libc 库。

在这里插入图片描述
在这里插入图片描述

  1. find . | cpio -o -H newc | gzip -c > ../initrd.gz

在这里插入图片描述

  1. 加载 initrd 结果。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

16.5 initrd 挂载过程分析

find . | cpio -o -H newc | gzip -c > ../initrd.gz

16.5.1 CPIO initrd 挂载过程分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

"tftp 0x60003000 uImage;tftp 0x60500000 vexpress-v2p-ca9.dtb;tftp 0x62000000 initrd.gz;setenv bootargs 'initrd=0x62000000,4M root=/dev/ram0 rw rdinit=/linuxrc console=ttyAMA0';bootm 0x60003000 - 0x60500000;"
# 这里是 rdinit=/linuxrc

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
do_initcalls 就会执行到如下函数:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

16.5.2 rdinit=/linuxrc 的启动

回到前面:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

17. 使用 initrd 作为文件系统:ramdisk 格式

  • 制作一个 ramdisk 镜像
  • ramdisk 格式的 initrd 挂载过程分析
  • 使用 initrd 的优点、缺点: page cache \ 地址空间

在这里插入图片描述
在这里插入图片描述

需要修改 boot 配置中的 bootcmd 参数:

# 将之前的 initrd.gz 改成 initrd
CONFIG_BOOTCOMMAND="tftp 0x60003000 uImage;tftp 0x60500000 vexpress-v2p-ca9.dtb;tftp 0x62000000 initrd;setenv bootargs 'initrd=0x62000000,4M root=/dev/ram0 rw rdinit=/linuxrc console=ttyAMA0';bootm 0x60003000 - 0x60500000;"

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

前面过程一样,一直走到这里:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

18. 使用 initramfs 作为根文件系统

  • 相比 initrd(一种 cpio 制作的,一种传统 ramdisk 方式制作的),initramfs 的优势有哪些?
  • 启动参数
    • root:initramfs 作为根文件系统,root、init 不用设置,只需要指定文件系统的源目录就可以了
    • 文件系统中默认要有一个 init 文件

18.1 initramfs 配置挂载过程

  • 使用 initramfs 的内核配置
    使用之前创建的 ramdisk 路径,同时将路径下的 linux 更名为 init 。然后再开始编译内核。

在这里插入图片描述
在这里插入图片描述

  • 使用 initramfs 的 u-boot 编译配置
tftp 0x60003000 uImage;tftp 0x60800000 vexpress-v2p-ca9.dtb;setenv bootargs 'console=ttyAMA0';bootm 0x60003000 - 0x60800000;

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

18.2 initramfs 挂载过程分析

  • initramfs 的挂载过程分析
  • Linkscript: arch/arm/kernel/vmlinux.lds
  • Head file: include/asm-generic/vmlinux.lds.h
  • Makefile: usr/Makefile

前面过程和之前章节一样:

在这里插入图片描述

这里着重分析一下两个参数:__initramfs_start__initramfs_size

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

19. 基于内存的文件系统:tmpfs

  • 内存的文件系统
    • ramfs VS ramdisk
    • ramfs VS tmpfs
  • tmpfs 的优点:
    • 快、不用格式化、动态调整大小、扩展性好
  • tmpfs 的实现:linux-5.10.4/mm/shmem.c
  • tmpfs 的应用领域
    • 临时目录、临时文件
  • tmpfs 的挂载:mount -t tmpfs -o size=4m tmpfs /tmp

在这里插入图片描述
在这里插入图片描述

20. 文件系统的自动挂载

  • 文件系统挂载方式
    • 内核挂载、启动参数、自动挂载
  • 根文件系统的常用目录
  • 启动脚本
  • 文件系统的自动挂载

在这里插入图片描述

注意:实验前将文件系统还原成 NFS 配置,包括 boot 和 kernel。

在这里插入图片描述
在这里插入图片描述

21. 文件系统的性能指标

  • 不同应用场景
    分布式
    服务器、PC
    消费电子
  • 文件系统得到性能指标
    文件名长度、最大文件数、最大分区、最大文件大小
    挂载速度、读写速度、稳定性、日志
  • 如何选型文件系统?
  • 常见的文件系统
    • Windows:FAT16、FAT32、NTFS
    • Linux:ext2、ext3、ext4、btrfs、zfs
    • 光盘:ISO9660
    • 网络文件系统:SMBAFS、CIFS、NFS
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

uuxiang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值