You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Linux启动过程调试:自定义内核切换根文件系统失败及无发行版内核调试方法咨询

问题分析与解决方案

一、initrd-switch-root失败的原因及修复步骤

你遇到的切换根失败问题,核心原因基本是自定义内核缺少根分区所需的磁盘驱动,或者initramfs没有正确打包这些驱动,导致initrd阶段无法识别/dev/sda3。具体排查和修复步骤如下:

1. 检查自定义内核的磁盘驱动配置

QEMU默认通过IDE控制器挂载你的fedora.qcow2磁盘,所以内核必须包含IDE相关驱动。打开内核配置文件(.config),确认以下选项是否开启:

  • CONFIG_IDE=yCONFIG_IDE=m(如果选模块,需确保dracut将其加入initramfs)
  • CONFIG_IDE_GENERIC=y
  • CONFIG_SATA_AHCI=y(若虚拟机磁盘用AHCI模式,不过默认是IDE)
  • 若之前切换过virtio磁盘模式,需确保CONFIG_VIRTIO_BLK=y

建议把这些选项设为内置(y),避免initramfs遗漏驱动模块,之后重新编译内核。

2. 重新生成正确的initramfs

你用dracut生成initramfs时,可能没有指定主机专属模式或关联自定义内核的模块路径。尝试用以下命令重新生成:

dracut --hostonly --kver 6.19.0+ --modules "base ide scsi virtio" initramfs-6.19.0+.img
  • --hostonly:只打包当前QEMU虚拟机需要的驱动,避免冗余同时防止遗漏
  • --kver:明确指定自定义内核版本,确保dracut找到对应模块
  • --modules:强制包含磁盘相关模块组,兜底保障驱动存在

3. 优化cmdline参数

你的root=/dev/sda3是正确的,但可以换成UUID(更可靠,避免设备名变动):

  1. 启动原Fedora虚拟机,执行blkid /dev/sda3获取UUID
  2. 将append参数改为root=UUID=xxx-xxx rw console=ttyS0 nokaslr

另外,确认启动命令没有磁盘参数冲突——如果原虚拟机用了virtio模式,需在自定义内核启动命令中添加-device virtio-blk-pci,drive=hd0,并调整-drive参数为-drive file=~/work/vms/fedora.qcow2,format=qcow2,id=hd0

二、用空白qcow2启动调试内核的可行性及步骤

完全可以!这种方式适合快速调试内核,无需完整发行版。具体操作如下:

1. 创建空白qcow2并格式化

# 创建空白镜像
qemu-img create -f qcow2 blank.qcow2 10G
# 用losetup挂载并格式化(无需启动虚拟机)
losetup -fP blank.qcow2
mkfs.ext4 /dev/loop0p1
losetup -d /dev/loop0

2. 制作最小化rootfs(可选,替代发行版)

如果不想安装完整发行版,可用busybox制作极简rootfs:

mkdir rootfs && cd rootfs
# 安装busybox工具集
busybox --install -s
# 创建必要目录结构
mkdir proc sys dev etc tmp
chmod 1777 tmp
# 编写init脚本
cat > init << EOF
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devtmpfs none /dev
exec /bin/sh
EOF
chmod +x init
# 打包成cpio镜像(可直接作为initramfs使用)
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../minimal-initramfs.img

3. 启动调试命令

  • 如果用空白qcow2作为根分区:
qemu-system-x86_64 -kernel ~/work/linux/arch/x86_64/boot/bzImage -initrd ~/work/linux/initramfs-6.19.0+.img -append "root=/dev/sda1 rw console=ttyS0 nokaslr" -drive file=blank.qcow2,format=qcow2 -m 2G -s -S -nographic
  • 如果直接用busybox的initramfs(无需磁盘):
qemu-system-x86_64 -kernel ~/work/linux/arch/x86_64/boot/bzImage -initrd minimal-initramfs.img -append "console=ttyS0 nokaslr" -m 2G -s -S -nographic

之后在另一个终端运行gdb vmlinux并执行target remote :1234即可开始调试。


内容的提问来源于stack exchange,提问作者babon

火山引擎 最新活动