基于Intel服务器iPXE启动Yocto镜像无法识别磁盘的问题排查
问题描述
基于Yocto Kirkstone分支集成meta-intel开发项目,构建产物包含可引导ISO、内核文件及多个initramfs文件。在VirtualBox虚拟机中启动ISO可正常完成Live启动、安装并识别/dev/sda,开机GRUB菜单显示Live启动和安装选项。但通过iPXE向搭载Xeon处理器的HP服务器传输bzImage内核和core-image-full-cmdline-intel-corei7-64.cpio.gz initramfs进行Live启动时,虽能成功启动,但/dev目录下无磁盘设备可见:执行lsblk无结果,fdisk -l仅显示ram0至ram8等条目,且无法通过ISO、hddimg等格式进行iPXE启动。要从Live启动环境完成服务器安装,/dev/sdX或/dev/nvme*设备的识别是核心前提,推测问题源于文件系统/磁盘驱动未正确加载。
当前配置文件
local.conf(精简版)
IMAGE_TYPEDEP_wic = "ext4" INITRD_IMAGE_LIVE="core-image-minimal-initramfs" LABELS_LIVE = "boot install" EFI_PROVIDER = "grub-efi" do_image_wic[depends] += "${INITRD_IMAGE_LIVE}:do_image_complete" do_rootfs[depends] += "virtual/kernel:do_deploy" IMAGE_BOOT_FILES:append = "\ ${KERNEL_IMAGETYPE} \ microcode.cpio \ ${IMGDEPLOYDIR}/${IMAGE_BASENAME}-${MACHINE}.ext4;rootfs.img \ ${@bb.utils.contains('EFI_PROVIDER', 'grub-efi', 'grub-efi-bootx64.efi;EFI/BOOT/bootx64.efi', '', d)} \ ${@bb.utils.contains('EFI_PROVIDER', 'grub-efi', '${IMAGE_ROOTFS}/boot/EFI/BOOT/grub.cfg;EFI/BOOT/grub.cfg', '', d)} \ ${@bb.utils.contains('EFI_PROVIDER', 'systemd-boot', 'systemd-bootx64.efi;EFI/BOOT/bootx64.efi', '', d)} \ ${@bb.utils.contains('EFI_PROVIDER', 'systemd-boot', '${IMAGE_ROOTFS}/boot/loader/loader.conf;loader/loader.conf ', '', d)} \ ${@bb.utils.contains('EFI_PROVIDER', 'systemd-boot', '${IMAGE_ROOTFS}/boot/loader/entries/boot.conf;loader/entries/boot.conf', '', d)} " INIT_MANAGER = "systemd" VIRTUAL-RUNTIME_init_manager = "systemd" DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" MACHINE_FEATURES_NATIVE:append = " efi" MACHINE_FEATURES:append = " efi" MACHINE_FEATURES:append = " pcbios util-linux-blkid" IMAGE_INSTALL:append = " grub grub-efi grub-bootconf" CORE_IMAGE_EXTRA_INSTALL:append = " kernel-modules"
bblayers.conf
# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf # changes incompatibly POKY_BBLAYERS_CONF_VERSION = "2" BBPATH = "${TOPDIR}" BBFILES ?= "" BBLAYERS ?= " \ /home/poky/meta \ /home/poky/meta-poky \ /home/poky/meta-yocto-bsp \ /home/poky/meta-openembedded/meta-oe \ /home/poky/meta-openembedded/meta-python \ /home/poky/meta-openembedded/meta-networking \ /home/poky/meta-openembedded/meta-filesystems \ /home/poky/meta-openembedded/meta-perl \ /home/poky/meta-selinux \ /home/poky/meta-virtualization \ /home/poky/meta-intel \ "
boot.ipxe
# Fetch the kernel kernel ${base}/bzImage root=/dev/nfs initrd=core-image-full-cmdline-intel-corei7-64.cpio.gz initrd ${base}/core-image-full-cmdline-intel-corei7-64.cpio.gz imgargs bzImage LABEL=boot rootwait console=ttyS0,115200 console=tty0 boot || goto failed goto start
解决步骤:确保驱动在内核与initramfs中正确加载
1. 内核层面:编译磁盘控制器驱动为内置模块
HP Xeon服务器常见的磁盘控制器类型包括Intel AHCI、NVMe、LSI SAS,需确保这些驱动直接编译进内核(而非动态模块):
- 执行
bitbake -c menuconfig virtual/kernel进入内核配置界面,开启以下选项:- AHCI控制器:
CONFIG_SATA_AHCI=y - NVMe设备:
CONFIG_NVME_CORE=y、CONFIG_BLK_DEV_NVME=y - SCSI/SAS控制器:
CONFIG_SCSI=y、CONFIG_SCSI_SAS=y、CONFIG_SCSI_LSI_SAS=y
- AHCI控制器:
- 也可在
local.conf中通过KERNEL_FEATURES追加配置:KERNEL_FEATURES:append = " cfg/sata.scc cfg/nvme.scc cfg/scsi.scc" - 验证配置:编译后在目标系统执行
zcat /proc/config.gz,确认上述配置值为y。
2. initramfs层面:补充磁盘工具与驱动模块
core-image-full-cmdline默认可能缺失磁盘管理工具或驱动模块,需调整配置:
- 在
local.conf中追加必要工具:CORE_IMAGE_EXTRA_INSTALL:append = " e2fsprogs fdisk lsblk util-linux-blkid udev" - 若驱动采用动态模块形式,需指定加入initramfs的模块:
INITRD_MODULES:append = " ahci nvme scsi_mod sd_mod" - 验证initramfs内容:执行
zcat core-image-full-cmdline-intel-corei7-64.cpio.gz | cpio -t,确认存在/lib/modules/<kernel-version>/kernel/drivers/ata/ahci.ko等驱动文件,以及磁盘工具、udev规则。
3. 调整iPXE启动参数
当前boot.ipxe中的root=/dev/nfs参数不符合Live启动逻辑,需修正:
# Fetch the kernel kernel ${base}/bzImage initrd=core-image-full-cmdline-intel-corei7-64.cpio.gz console=ttyS0,115200 console=tty0 rootwait LABEL=boot initrd ${base}/core-image-full-cmdline-intel-corei7-64.cpio.gz boot || goto failed goto start
- 移除错误的
root=/dev/nfs,确保initramfs作为根文件系统启动 - 保留
rootwait参数,等待磁盘控制器初始化完成 - 若服务器为老型号,可尝试添加
libata.force=noncq参数解决兼容性问题
4. 替换为ISO使用的Live initramfs
你在local.conf中配置了INITRD_IMAGE_LIVE="core-image-minimal-initramfs",这是ISO Live启动时使用的initramfs,包含更完善的磁盘初始化逻辑,可尝试替换:
kernel ${base}/bzImage initrd=core-image-minimal-initramfs-intel-corei7-64.cpio.gz console=ttyS0,115200 console=tty0 rootwait LABEL=boot initrd ${base}/core-image-minimal-initramfs-intel-corei7-64.cpio.gz boot || goto failed
5. 验证内核配置一致性
对比VirtualBox中正常启动的内核与iPXE使用的bzImage配置:
- 在VirtualBox启动的系统中执行
zcat /proc/config.gz导出配置 - 在构建主机执行
bitbake -c savedefconfig virtual/kernel导出当前内核配置 - 对比两者的磁盘驱动相关配置,确保无差异
最佳实践
- 优先将磁盘控制器驱动编译进内核(
=y),避免initramfs加载动态模块失败 - 直接在目标HP服务器上测试内核配置,不要依赖虚拟机的默认配置
- 执行
bitbake -c checktasks virtual/kernel检查内核构建任务,确保驱动被正确包含 - iPXE启动后执行
dmesg | grep -E 'ahci|nvme|scsi|sd',查看驱动加载与磁盘识别日志,定位具体问题
内容的提问来源于stack exchange,提问作者Nauman Shakir

