【问题标题】:Kernel Panic with ramfs on embedded device: No filesystem could mount root嵌入式设备上带有 ramfs 的内核恐慌:没有文件系统可以挂载 root
【发布时间】:2017-01-22 20:50:33
【问题描述】:

我正在开发一个运行 Linux(内核 3.10)的嵌入式 ARM 设备,该设备使用 NAND 内存进行存储。我正在尝试构建一个最小的 linux,它将驻留在自己的分区上并执行主固件的更新。

内核使用一个非常小的根 fs,它存储在 ramfs 中。但是,我无法启动它。我收到以下错误:

[    0.794113] List of all partitions:
[    0.797600] 1f00             128 mtdblock0  (driver?)
[    0.802669] 1f01            1280 mtdblock1  (driver?)
[    0.807697] 1f02            1280 mtdblock2  (driver?)
[    0.812735] 1f03            8192 mtdblock3  (driver?)
[    0.817761] 1f04            8192 mtdblock4  (driver?)
[    0.822794] 1f05            8192 mtdblock5  (driver?)
[    0.827820] 1f06           82944 mtdblock6  (driver?)
[    0.832850] 1f07           82944 mtdblock7  (driver?)
[    0.837876] 1f08           12288 mtdblock8  (driver?)
[    0.842906] 1f09           49152 mtdblock9  (driver?)
[    0.847928] No filesystem could mount root, tried:  squashfs
[    0.853569] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)
[    0.861806] CPU: 0 PID: 1 Comm: swapper Not tainted 3.10.73 #11
[    0.867732] [<800133ec>] (unwind_backtrace+0x0/0x12c) from [<80011a50>] (show_stack+0x10/0x14)
(...etc)

根 fs 由构建过程构建,使用以下内容(为清楚起见进行了简化):

# [Copy some things to $(ROOTFS_OUT_DIR)/mini_rootfs]
cd $(ROOTFS_OUT_DIR)/mini_rootfs && find . | cpio --quiet -o -H newc > $(ROOTFS_OUT_DIR)/backup.cpio
gzip -f -9 $(ROOTFS_OUT_DIR)/backup.cpio

这会创建 $(ROOTFS_OUT_DIR)/backup.cpio.gz

然后内核是这样构建的:

@$(MAKE) -C $(LINUX_SRC_DIR) O=$(LINUX_OUT_DIR) \
             CONFIG_INITRAMFS_SOURCE="$(ROOTFS_OUT_DIR)/backup.cpio.gz" \
             CONFIG_INITRAMFS_ROOT_UID=0 CONFIG_INITRAMFS_ROOT_GID=0

我认为这意味着它使用与主固件相同的配置(在其他地方构建),但使用 CONFIG_INITRAMFS_SOURCE 提供最小的 ramfs 映像。

Kernel.Org 开始,ramfs 始终是构建的,而 CONFIG_INITRAMFS_SOURCE 是指定要使用的预制根 fs 所需的全部内容。没有构建错误表明创建 ramfs 存在问题,并且生成的内核的大小看起来正确。 backup.cpio.gz 大约是 3.6 MB;最终的 zImage 为 6.1 MB;图像被写入大小为 8 MB 的分区。

为了使用这个镜像,我设置了(自定义)引导加载程序使用的一些标志,告诉它从最小分区引导,并为内核设置不同的命令行。这是用于启动的命令行:

console=ttyS0 rootfs=ramfs root=/dev/ram rw rdinit=/linuxrc mem=220M

请注意,最简单的根 fs 包含“/linuxrc”,它实际上是到 /bin/busybox 的链接:

lrwxrwxrwx  1 root root   11 Nov  5  2015 linuxrc -> bin/busybox

为什么不开机?为什么要尝试“squashfs”文件系统,这是错误的吗?

【问题讨论】:

  • PS:我读到这个:linuxquestions.org/questions/…,并确认在配置中设置了 CONFIG_BLK_DEV_INITRD=y 和 CONFIG_RD_GZIP=y。
  • 您不必在命令行中指定rootfs=。正确配置的内核将始终只使用正确附加的 initramfs(并忽略任何 rootfs= 参数)。您不需要压缩 cpio 存档,因为它会在 zImage 中再次被压缩。好久没有亲手构建一个initramfs,然后和内核合并了。现在有了 Buildroot,这就是我使用的。
  • @sawdust 我从 cmdline 参数中删除了“rootfs=ramfs”,但仍然出现同样的错误。
  • “但我仍然遇到同样的错误” -- 一点也不奇怪。您的 initramfs 有问题,导致内核忽略它。根据Documentation/init 程序文件必须在 initramfs 中找到,否则内核会寻找根分区。
  • 您需要传递 rootfstype=ramfs 而不是 rootfs=ramfs root=/dev/foobar rw。确保您已启用所有必要的内核选项。另外,rdinit=/something_standard 是多余的。

标签: linux linux-kernel embedded boot


【解决方案1】:

已解决!事实证明,(自定义)构建系统使用的文件名作为更新的一部分已更改,因此它没有将正确的内核映像放入固件包中。我实际上是在尝试使用“rootfs = ramfs”参数启动错误的内核,该参数没有 ramfs。

因此,为了将来参考,如果您指定“rootfs=ramfs”但您的内核未使用任何内置的 rootfs 构建(CONFIG_INITRAMFS_SOURCE=...未指定),则会出现此错误

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-29
    • 1970-01-01
    相关资源
    最近更新 更多