系列文章目录
- Exynos4412 移植Linux-6.1(一)下载、配置、编译Linux-6.1
- Exynos4412 移植Linux-6.1(二)SD卡驱动——解决无法挂载SD卡的根文件系统
- Exynos4412 移植Linux-6.1(三)SD卡驱动——解决mmc0: Timeout waiting for hardware interrupt.
- Exynos4412 移植Linux-6.1(四)NandFlash卡驱动
- Exynos4412 移植Linux-6.1(五)DM9000网卡驱动
- Exynos4412 移植Linux-6.1(六)【已解决】SROMC寄存器的数值不正确的问题
- Exynos4412 移植Linux-6.1(七)挂载Ramdisk文件系统,【已解决】Couldn’t find valid RAM disk image starting at 0
【已解决】Exynos4412 移植Linux-6.1(七)挂载Ramdisk 文件系统,解决RAMDISK: Couldn't find valid RAM disk image starting at 0的问题
0、问题描述
通过 busybox 制作 Linux 的根文件系统,压缩打包成ramdisk文件镜像。挂载ramdisk文件系统,无法启动Linux,提示
RAMDISK: Couldn't find valid RAM disk image starting at 0
[...]
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)
1、原因分析
Linux内核在加载initrd data到/dev/ram0之前,会创建/initrd.image。initrd.image镜像文件的内容,就是复制由BootLoader加载的ramdisk镜像文件。BootLoader会在启动Linux之前,通过bootargs 中的initrd参数,把ramdisk文件的加载地址传入Linux内核。
那么问题来了,如果initrd参数不正确,或者说BootLoader加载ramdisk的地址与initrd参数不一致,就会提示RAMDISK: Couldn't find valid RAM disk image starting at 0
的错误。
更具体的代码分析可以参考博客《Linux内核启动过程中,ramdisk加载失败,系统崩溃》。1
由此可见,关键是要确定BootLoader的加载地址。
2、BootLoader加载ramdisk的三种方式
我用的是u-boot-2022.01-rc4,在boot/image-board.c文件中的boot_ramdisk_high
实现指定ramdisk_addr,在Linux启动之前加载ramdisk。
u-boot 分三种情况,指定不同的ramdisk_addr2:
- setenv initrd_high 0xffffffff: 不进行reloacate,保留这块内存
- setenv initrd_high 0 : 从lmb.memory.region[0]中任意位置申请内存,并拷贝镜像
- 没有环境变量initrd_high: initrd_high = bootm_mapsize + bootm_low
在boot/image-board.c中添加printf语句,或者把源代码中的debug改为printf,(我在include/common.h中定义宏DEBUG会报错),打印ramdisk_addr的相关信息。
同时,修改include/configs/cbt4412.h(这个文件根据自己的开发板修改),增加initrd_high
参数。
- 选择第1种方式(setenv initrd_high 0xffffffff)
include/configs/cbt4412.h修改示例如下:
#define CONFIG_EXTRA_ENV_SETTINGS