根文件系统挂载机制与实现详解
源码路径:
rk3588/kernel-6.1/init/do_mounts.c、do_mounts_initrd.c、do_mounts_rd.c
内核版本:Linux 6.1(RK3588 / ARM64)
文档目录:linuxDoc/init/
目录
一、原理
1.1 目标
在 initramfs 早期环境(若存在)之后,将 真正的根文件系统 挂载到合适位置,并通过 MS_MOVE + chroot 使之成为全局 /,使后续 kernel_execve 的 init 运行在最终根上。
1.2 rootfs 与真实根
| 类型 | 说明 |
|---|---|
rootfs fs |
启动时内存中的初始根(ramfs/tmpfs),用于解 cpio |
| 块设备/NFS 根 | mount_root() 挂载的最终根 |
init_rootfs() 可根据配置选择 rootfs 为 tmpfs(无 root= 时常见)。
二、实现方式
2.1 prepare_namespace() 流程
1 | void __init prepare_namespace(void) |
要点:
root_delay:故意延迟挂根wait_for_device_probe():等待驱动异步 probe(常见数秒级延迟)initrd_load():传统 initrd 路径(与内置 initramfs 不同机制)rootwait:设备未就绪时轮询name_to_dev_tmount_root():NFS/CIFS/nodev/块设备devtmpfs_mount():填充/dev- 把
.移到/并 chroot
2.2 mount_root()
ROOT_DEV == 0且配置了root_fs_names→mount_nodev_root(如 nfs4)- 否则
create_dev("/dev/root", ROOT_DEV)+mount_block_root
2.3 root= 解析
PARTUUID=:遍历块设备分区元数据 UUID(devt_from_partuuid)/dev/mmcblk0pN:name_to_dev_tmtd/ubi前缀:直接mount_block_root路径名
默认挂载标志:MS_RDONLY | MS_SILENT;ro/rw 内核参数可改。
2.4 与 kernel_init_freeable 的衔接
仅当 ramdisk_execute_command 不可执行 时才调用 prepare_namespace();否则 initramfs 内 /init 可能已完成 switch_root。
三、关键变量与启动参数
| 参数/变量 | 作用 |
|---|---|
root= |
→ saved_root_name |
rootwait |
等待块设备出现 |
rootflags= |
文件系统挂载选项 |
rootfstype= |
强制 fs 类型列表 |
ro / rw |
只读/读写根 |
root_delay= |
秒级延迟 |
四、RK3588 平台说明
典型产品配置:
- eMMC:
root=PARTUUID=xxxx或root=/dev/mmcblk0pN,文件系统 ext4/f2fs rootwait:存储控制器或 regulator 晚就绪时避免挂根失败- AB 分区 / AVB:用户态 updater 处理;内核层仍依赖
root=指向当前 slot 分区
挂根慢时优先查 Waiting for root device 与 wait_for_device_probe 之前的驱动 probe 日志,而非仅看 mount 错误。
五、调试与观测
| 日志 | 含义 |
|---|---|
Waiting for root device |
rootwait 轮询中 |
VFS: Unable to mount root fs |
类型/设备/权限错误 |
Failed to create /dev/root |
ROOT_DEV 无效 |
1 | # 用户态(启动后) |
启动阶段可加 rootfstype=ext4、debug(若文件系统支持)缩小失败面。
附录:源码索引
| 符号 | 文件 |
|---|---|
prepare_namespace |
do_mounts.c ~600 |
mount_root |
~566 |
rootfs_fs_type |
~660 |
init_rootfs |
~666 |
相关:05 initramfs
正在加载留言…