具体文件系统与根盘
根文件系统初始化把设备发现、卷解析、root policy、格式检测和 mount 发布分成五个阶段。格式实现只接收裁剪后的 BlockRegion;它不知道设备在 probe registry 中的顺序,也不解释 bootargs。
1. 根盘选择
根盘选择先把物理磁盘归一成 BlockVolume,再检测每个 region 的文件系统格式,最后由 RootSpec 或默认策略选择唯一候选。卷 parser 不读取 bootargs,root policy 也不重复解析 GPT/MBR。
1.1 卷发现
volume::scan_volumes(reader, DiskId) 按以下顺序识别磁盘:
- 读取 LBA0;
- 若存在 protective MBR,尝试 GPT;
- 否则解析 MBR primary entry 和 extended partition 的 EBR chain;
- 没有可用分区表时返回覆盖全盘的 raw volume。
扫描结果统一使用 BlockVolume 保存 region 和可选 partition metadata,使 root selector 不需要识别 GPT entry 或 MBR entry 的原始布局。
| 类型 | 保存的 metadata |
|---|---|
| GPT | partition index、LBA region、type/unique GUID、UTF-16 label |
| MBR | primary/logical partition index、type、bootable、由 disk signature 和 index 形成的 PARTUUID |
| Raw | 整个 reader 的 block region,无 partition id |
GPT header、entry size/count 和 entry-array 范围必须完全位于设备内;MBR/EBR 的逻辑分区必须同时位于磁盘和 extended container 内。无效表返回结构化 volume error,root 层记录诊断并跳过该 disk,不把损坏分区表误当 raw filesystem。
1.2 格式检测
collect_partitions() 对每个 BlockVolume 读取最小 magic:
| 格式 | 检测位置 | 条件 |
|---|---|---|
| ext4 | volume byte offset 1024 + 0x38 | little-endian 0xEF53 |
| FAT16 | first sector 54..59 | boot signature 55 aa 且 FAT16 |
| FAT32 | first sector 82..87 | boot signature 55 aa 且 FAT32 |
检测只决定尝试哪个 adapter,不代替完整 mount 校验。读取失败、region 太小、block size 不合法或 magic 不匹配均视为不支持,真正的 superblock、feature 和一致性检查由具体格式实现完成。
1.3 显式选择
RootSpec::parse_bootargs() 提取 root= 并支持:
PARTUUID=<uuid>;PARTLABEL=<label>;/dev/sdXN;/dev/nvmeCn1pN;/dev/mmcblkXpN;- 裸 disk path(不带 partition)。
设备 path 被解析成发现顺序中的 disk_index 和 zero-based partition_index。PARTUUID 比较不区分大小写,PARTLABEL 按原字符串精确匹配。已经成功解析的 selector 找不到候选时启动失败;无法识别的 root= 语法当前会得到空 RootSpec,随后进入默认选择策略。
1.4 默认策略
没有显式 root 时使用确定性且 fail-closed 的顺序:
- 恰好一个
PARTLABEL=rootfs; - 恰好一个带受支持文件系统的 bootable MBR partition;
- 恰好一个带受支持文件系统的 partition;
- 没有可用 partition 且恰好一个 raw disk;
- 否则无法判定并失败。
多个 rootfs label 会直接报错,多个同优先级候选不会按枚举先后猜测。raw disk 只有在没有 partition match 时才参与 fallback,避免把有分区表的整盘误挂成文件系统。