initramfs 与早期用户态机制与实现详解
源码路径:
rk3588/kernel-6.1/init/initramfs.c、noinramfs.c、do_mounts_initrd.c
内核版本:Linux 6.1(RK3588 / ARM64)
文档目录:linuxDoc/init/
目录
一、原理
1.1 initramfs vs initrd
| 机制 | 实现 | 特点 |
|---|---|---|
| initramfs | initramfs.c,cpio 解到 rootfs |
常内置进内核镜像(INITRAMFS_SOURCE) |
| initrd | do_mounts_initrd.c |
旧式内存盘镜像,可能 pivot 到真实根 |
RK 产品多数使用 内置 initramfs 携带固件、模块或最小 /init 脚本。
1.2 早期用户态
若 rootfs 中存在可执行的 ramdisk_execute_command(默认常指向 /init),可在 prepare_namespace 之前由该程序完成存储驱动加载、挂根、switch_root。
二、实现方式
2.1 解包流程(initramfs.c)
populate_rootfs(rootfs initcall):读取内置 cpio 或外部 blobunpack_to_rootfs:解析 cpio 项(目录、文件、符号链接、devnode)- 支持 多种压缩(gzip、xz 等,取决于
decompress_method配置) wait_for_initramfs():kernel_init_freeable中等待解包完成
2.2 RK 硬件解压
1 | #if defined(CONFIG_ROCKCHIP_THUNDER_BOOT) && defined(CONFIG_ROCKCHIP_HW_DECOMPRESS) |
在 Thunder Boot + 硬件解压驱动场景下,解包前等待 HW 完成,与 CPU 软件解压路径互斥配置。详见 07。
2.3 noinramfs.c
CONFIG_BLK_DEV_INITRD=n 时链接,提供空 rootfs 占位,避免缺少符号。
2.4 do_mounts_initrd.c
处理 bios/initrd 传入 的 initrd 镜像:initrd_load() 在 prepare_namespace 中调用;若成功可能 不再 走常规 mount_root(goto out)。
三、关键接口
| 符号 | 作用 |
|---|---|
populate_rootfs |
注册解包 initcall |
unpack_to_rootfs |
cpio + 解压主循环 |
wait_for_initramfs |
同步点 |
ramdisk_execute_command |
早期 init 路径(main.c 可 rdinit= 设置) |
rootfs_fs_type |
rootfs 文件系统类型(ramfs/tmpfs) |
四、RK3588 平台说明
- 编解码固件:部分 BSP 通过 initramfs 释放到
/lib/firmware - 快启:HW decompress + 延迟 memblock 组合缩短 可见启动时间
- Kconfig:
INITRAMFS_SOURCE指向 cpio 列表;与CONFIG_BLK_DEV_INITRD配合 Makefile 选initramfs.o或noinitramfs.o
五、调试与观测
| 问题 | 检查 |
|---|---|
compression method ... not configured |
内核未编进对应 decompressor |
| initramfs 空 | INITRAMFS_SOURCE、构建是否更新 cpio |
早期 /init 未运行 |
rdinit=、ramdisk_execute_command、init_eaccess |
| 解压 stall | RK HW decompress 是否超时(dmesg 驱动日志) |
1 | # 从构建产物查看 |
附录:源码索引
| 文件 | 说明 |
|---|---|
initramfs.c |
cpio 解包、populate |
noinramfs.c |
无 initrd 桩 |
do_mounts_initrd.c |
initrd 加载 |
main.c |
wait_for_initramfs、ramdisk_execute_command |
正在加载留言…