系列第 11 篇|Demo 收官:先 runqemu,再 U 盘双系统编译在 WSL2|验证对比:qemux86-64(虚机)与 genericx86-64(真机)
这是动手线的最后一篇。我们把第 10 篇的两套产物分别跑起来,并刻意对比:
qemux86-64 + runqemu——在 WSL2 里快速证明镜像与 hello;genericx86-64 + U 盘——在 Windows PC 上走真实 UEFI,并尽量做成双系统。成功的最低标准很明确:
安全提醒(请认真读)写 U 盘、改分区、动 EFI 启动项都有风险。操作前备份重要数据。写入镜像时务必反复确认目标是 U 盘,而不是 Windows 系统盘。
建议顺序:先完成路径 A,再做路径 B。若虚机都进不去,先别急着写 U 盘。
前置:第 10 篇已构建出 build-qemux86-64/tmp/deploy/images/qemux86-64/;WSL2 Ubuntu 里还要有 QEMU(见下一节,默认未安装)。
runqemu 不是系统自带的命令,而是 poky 提供的启动脚本,真实路径是:
~/yocto/poky/scripts/runqemu同目录还有若干辅助脚本(如 runqemu-extract-sdk)。你平时不必手写完整路径,因为执行:
source oe-init-build-env build-qemux86-64时,脚本会把 poky/scripts 加入当前 shell 的 PATH,并把工作目录切到 build-qemux86-64。因此只要在「已 source 过的同一个终端」里,直接敲 runqemu 即可。
可自行确认:
which runqemu# 期望类似:.../yocto/poky/scripts/runqemuecho$BUILDDIR# 期望:.../yocto/poky/build-qemux86-64若新开了一个终端却没再 source,会出现 runqemu: command not found——这是环境未初始化,不是镜像坏了。
要。runqemu 只是包装脚本,真正拉起虚机的是宿主上的 qemu-system-x86_64。WSL2 的 Ubuntu 默认不带这个命令。
两件容易混的事:
bitbake 用的,列表里通常没有 qemu-system-x86。所以很多人编完第 10 篇才发现虚机起不来。入门最省事:在 WSL2 Ubuntu 里装宿主 QEMU:
sudo apt updatesudo apt install qemu-system-x86装完确认:
which qemu-system-x86_64# 期望:/usr/bin/qemu-system-x86_64不要只装名为
qemu的元包:较新的 Ubuntu 上它几乎不带qemu-system-x86_64。本 demo 需要的是qemu-system-x86。
另一条路:用 Yocto 自己编出来的 native QEMU(runqemu 会优先找它)。在已 source 的 build-qemux86-64 环境中执行:
bitbake qemu-helper-native -c addto_recipe_sysroot两条路有一条通即可。
不装会怎样:
which runqemu | poky/scripts 里,与是否安装 QEMU 无关 |
runqemu nographicqemu-system-x86_64,或类似 Can't find qemu | |
WSL2 补充:本篇用 nographic,不依赖图形窗口。若提示无法使用 KVM(/dev/kvm 不存在或权限不够),那是嵌套虚拟化问题,不是「没装 QEMU」。此时不要加 kvm,让 QEMU 走软件模拟即可,只是会慢一些。
它不是「随便起一个空虚机」,而是替你把第 10 篇的产物接上宿主上的 QEMU。简化流程:
读当前 build 环境(MACHINE、DEPLOY_DIR_IMAGE 等) → 在 tmp/deploy/images/qemux86-64/ 找到镜像与 *.qemuboot.conf → 按 conf 选定内核、rootfs、内存、串口等参数 → 组装并执行 qemu-system-x86_64 ... → 虚机内:kernel → rootfs → init → … → 可登录并跑 hello要点:
bzImage)、rootfs 镜像,以及构建阶段由 qemuboot 类生成的 *.qemuboot.conf。后者记录了该 MACHINE 该怎么被 QEMU 启动。build-qemux86-64 环境中,不指定镜像名时,它会按当前 MACHINE / 最新产物自行挑选合适文件。runqemu 是包装器,最终会执行 qemu-system-x86_64。WSL2 Ubuntu 默认没有它,见上一节。nographic**:把控制台接到当前终端(串口输出),适合无图形、SSH 进 WSL2 的场景。对照真机路径:真机是 UEFI → GRUB → kernel;这里是 runqemu → QEMU 模拟硬件 → kernel。后面的 rootfs / init / hello 是同一套逻辑。
在 同一 WSL2 Ubuntu 中进入虚机构建环境:
cd ~/yocto/pokysource oe-init-build-env build-qemux86-64# 无图形界面时常用 nographic,直接在当前终端看串口输出runqemu nographic若默认参数与你的版本略有出入,以 runqemu --help 与当前 poky 文档为准;核心目标不变——把刚构建的虚机镜像跑起来。 当出现login提示后输入root回车即可进入qemu Linux系统。
进入系统后:
uname -m# 期望:x86_64which hello# 期望:/usr/bin/hellohello# 期望:Hello from Yocto-built Linux关于默认账号:core-image-base 常见是 root 登录,密码策略因版本 / 配置而异,以你镜像实际提示为准。
退出 QEMU 的常见方式:在 nographic 下可尝试 Ctrl-a 再按 x(具体以 QEMU 提示为准)。
说明了:镜像能引导,rootfs 完整,hello 已打进系统。没说明:你笔记本上的独显、特殊触控板、全部外设一定可用——那是真机驱动覆盖的问题。
build-genericx86-64/tmp/deploy/images/genericx86-64/ 中的 .wic 或 .hddimg | |
.tar.bz2,双系统部署到硬盘时更方便 | |
「写入 U 盘」的本质,是把镜像文件按磁盘的方式复制到 U 盘设备上,使 U 盘带有可被 UEFI 识别的分区与引导文件。
先确认设备名,这是最容易出错的一步:
lsblk看清楚哪个是 U 盘(容量、挂载点通常能帮你辨认)。假设 U 盘是 /dev/sdb(仅示例!),则:
sudo bmaptool copy \ core-image-base-genericx86-64.rootfs.wic \ /dev/sdb如果没有 .bmap 文件,可用 dd:
sudo dd \if=core-image-base-genericx86-64.rootfs.wic \ of=/dev/sdb \ bs=4M status=progress oflag=sync注意:
/dev/sdb 这种「整盘设备」,不要写成 /dev/sdb1 这种「分区」;若 Rufus 无法识别某种后缀,回到 Linux / dd / bmaptool 路径完成即可。
在改电脑硬盘之前,先证明镜像本身能在这台机器上启动。这能把问题拆开:如果 U 盘都进不去,先别急着做双系统。
操作过程用文字描述如下:
uname -m# 期望:x86_64hello# 期望:Hello from Yocto-built Linux如果这一步成功,说明:构建产物、U 盘写入、机器固件启动路径,至少已经打通。
你现在做的事情,是在真实硬件上走一遍第 1~2 篇讲过的 PC 路径:
上电 → UEFI/BIOS 固件启动菜单 → GRUB(或镜像自带引导) → linux kernel → rootfs → init → services → 运行 helloYocto 的 core-image-base 通常没有像 Ubuntu 桌面版那样的图形安装向导。因此我们采用更「工程化」但可操作的路径:
在 Windows 里腾出空闲分区 → 把 rootfs 铺进该分区 → 在 EFI 系统分区里放上启动文件并注册启动项 → 重启后在 Windows 与 Yocto Linux 之间选择。
此时不要删除 Windows 分区,也不要格式化 EFI 分区。
重新用 U 盘启动进入自建系统(或使用带完整磁盘工具的 Linux Live 环境,如 Ubuntu Live——当 Yocto 镜像里工具不够时,这是很实用的备选)。
lsblkfdisk -l你会看到:
记住硬盘设备名,例如 /dev/nvme0n1 或 /dev/sda。不同电脑名字不同。
在空闲空间新建一个 Linux 分区(可用 fdisk、parted 或图形工具),然后格式化为 ext4。假设新分区是 /dev/sdaX(请替换为实际名字):
mkfs.ext4 /dev/sdaXESP(EFI 系统分区)一般已由 Windows 创建好了。双系统时我们复用它来存放 Linux 的引导文件,而不是新建一个胡乱删除旧 ESP。
如果第 10 篇产物里有 rootfs.tar.bz2,这是最直观的方式:
mount /dev/sdaX /mnttar -xjf \ /path/to/core-image-base-\genericx86-64.rootfs.tar.bz2 \ -C /mnt这条命令的含义是:把归档中的整个根文件系统解压到硬盘新分区上。完成后,/mnt 下应能看到 bin、etc、usr、sbin 等目录。
如果只有 .wic、没有 tar 包,也可以在 Linux 上把 wic 当虚拟磁盘挂载,再把其中的 root 分区内容拷到 /mnt。做法更绕一些。核心目标不变——让硬盘分区拥有完整 rootfs。
部署后建议检查并按实际分区修正 /mnt/etc/fstab(如果镜像里有的话),确保系统知道根分区应挂载谁。初学若暂时不会改,至少保证你能用启动参数 root=UUID=... 指到正确分区。
现代 PC 用 UEFI 管理启动项。Windows 有自己的启动项;我们要为 Yocto Linux 再登记一项,或安装 GRUB 并让它能链到 Windows。
示意流程:
# 挂载根分区与 ESP# sdaY 请换成 ESP 分区名mount /dev/sdaX /mntmkdir -p /mnt/boot/efimount /dev/sdaY /mnt/boot/efi# 把 EFI/GRUB 文件拷到# ESP 的独立目录,例如 EFI/yocto/# 注册启动项(路径按实际修改)efibootmgr -c -d /dev/sda -p Y \ -L "Yocto Linux" \ -l '\EFI\yocto\grubx64.efi'若你的环境具备更完整的 GRUB 工具,也可以 chroot 进 /mnt 后执行 grub-install,再生成菜单;很多情况下 GRUB 还能检测到 Windows Boot Manager,从而在菜单里同时列出两边。
不同镜像内置工具不同。若 U 盘里的 Yocto 系统缺少 efibootmgr / grub-install,请改用 Ubuntu Live 这类工具齐全的环境完成「拷贝 rootfs + 安装引导」,逻辑完全一样。
uname -mhello两边都能进,才算双系统闭环完成。
排错时不要盲目重装,先问「卡在链的哪一环」。并善用对比:虚机 OK、真机挂,多半是写入/固件/分区问题,而不是 hello 菜谱写错。
runqemu: command not found | source oe-init-build-env | build-qemux86-64 |
runqemuqemu-system-x86_64 | sudo apt install qemu-system-x86bitbake qemu-helper-native -c addto_recipe_sysroot | |
/dev/kvm | kvm,继续用 runqemu nographic(软件模拟,较慢) | |
tmp/deploy/images/qemux86-64/ 存在;以 runqemu --help 与当前 poky 文档为准 | ||
efibootmgr -v 看是否有新项 | ||
root= 不匹配 | ||
回过头看,这条学习路径是完整的:
meta-demo 与 TEMPLATECONF,让自定义配置可复现、可协作 |
请永远分清几条线:
如果你已经在虚机和真机里都看到 Hello from Yocto-built Linux,恭喜——你不只是「会用 Linux」,而是走通了「自己构建并启动一套 Linux」的最小闭环,并且理解了虚机与真机两条验证路径的差别。自定义配置如何长期用 Git 管理,见下一篇。