系列第 10 篇|Demo:在 WSL2 里 bitbake,分别产出虚机与真机镜像提醒:第一次构建可能要数小时;两机型都编会更久,属正常现象
第 8~9 篇的配置与定制已经就绪。本篇做的事情很单纯,但通常最耗时间:
在 WSL2 Ubuntu 中分别进入两个 build 目录,先做出 qemux86-64,再做出 genericx86-64,并确认两套产物分别在哪里。
这些产物将在第 11 篇分别用于 runqemu 与 U 盘双系统。再次强调:这是 x86_64 虚机/真机镜像,不是玄铁板卡烧写包。
开始前花两分钟确认,能少熬几个失败的小时:
~/...,不要放在 /mnt/c/... | |
build-qemux86-64 与 build-genericx86-64,各自 MACHINE 已写对 | |
bitbake -s | grep hello 能看到 | |
core-image-base |
如果你是合上电脑很久后再回来,按目标机型重新进入环境:
cd ~/yocto/pokysource oe-init-build-env build-qemux86-64# 或source oe-init-build-env build-genericx86-64cd ~/yocto/pokysource oe-init-build-env build-qemux86-64# 可选确认bitbake -e | grep "^MACHINE="# 期望:MACHINE="qemux86-64"bitbake core-image-base成功后,产物在(相对当前 build 目录):
ls tmp/deploy/images/qemux86-64/完整路径类似:
~/yocto/poky/build-qemux86-64/tmp/deploy/images/qemux86-64/这一套主要供第 11 篇 runqemu 使用。
不必改虚机目录里的配置。另进真机 build:
cd ~/yocto/pokysource oe-init-build-env build-genericx86-64bitbake -e | grep "^MACHINE="# 期望:MACHINE="genericx86-64"# 确认 IMAGE_FSTYPES 仍含 wic / hddimg / tar.bz2(见第 8~9 篇)bitbake core-image-base成功后:
ls tmp/deploy/images/genericx86-64/完整路径类似:
~/yocto/poky/build-genericx86-64/tmp/deploy/images/genericx86-64/这一套主要供第 11 篇写 U 盘与双系统使用。
第 8 篇模板已把 DL_DIR、SSTATE_DIR 指到 poky 下同一共享目录(downloads/、sstate-cache/)。先编完虚机再编真机时,共用模块一般不必重复下载、也不必从零再编。
即使共享缓存,内核、机器相关打包仍会按 MACHINE 分别做——这很正常。别急着删整个 build 目录「图个干净」,除非你明确知道自己在做什么。
bitbake core-image-base终端会刷很久,看起来像「卡住了」。其实 BitBake 在按依赖图并行跑几百个菜谱。第 7 篇给过总链路;这里拆成两层看:整镜像在干什么,以及其中一个最重的包(Linux 内核)具体怎么编。
读 conf / 扫 layer → 解析 core-image-base 的依赖图(内核、busybox、hello、工具链……) → 查 sstate:能复用的任务直接跳过 → 缺的源码进 DL_DIR(downloads/) → 按任务链编每个包 → 组装 rootfs(用户态) → 把内核放进启动分区,打成 wic / hddimg / tar.bz2 → 拷到 tmp/deploy/images/<machine>/对应到屏幕上常见的几类输出:
Parsing recipes... | .bb / .conf,算出要编哪些包 |
Checking sstate...Setscene | |
do_fetch | |
do_compile | |
do_rootfsdo_image_* |
hello 只是依赖图里很小的一环。第一次构建真正耗时的,通常是交叉工具链和 linux-yocto。
第 8 篇说过:镜像配方里往往不写linux-yocto,内核是经 MACHINE → virtual/kernel 拉进来的。bitbake core-image-base 会顺带构建它;你也可以单独跑:
bitbake virtual/kernel# 等价于当前 MACHINE 下的 linux-yocto先对照你在裸机上编内核的习惯:
手工编内核(概念) Yocto 里对应的任务─────────────────────────────────────────────────────git clone / 下 tarball do_fetch解压、切到指定提交 do_unpack(linux-yocto 还有 checkout)打补丁 do_patchmake defconfig / 合并配置 do_kernel_metadata → do_configuremake -jN(出 bzImage) do_compilemake modules do_compile_kernelmodulesmake modules_install do_install把 bzImage 拷到启动介质 do_deploy → 镜像的 do_image_wic 再装进启动分区linux-yocto 比 hello 多几步,是因为内核配置不是一张手写的 .config,而是由 MACHINE 默认配置 + kernel-meta 片段(第 9 篇 bbappend 里的 demo.cfg 也走这条路)拼出来的。不会弹 make menuconfig。
任务顺序可以记成:
do_fetch → do_unpack / 检出源码 → do_patch → do_kernel_metadata # 按 MACHINE 收集配置片段 → do_configure # 生成 .config(类似 olddefconfig) → do_compile # 编 vmlinux / bzImage,最耗 CPU → do_compile_kernelmodules → do_install # 模块、头文件进暂存目录 ${D} → do_package # 打成 kernel-image、kernel-module-* 等包 → do_deploy # bzImage 等放到 deploy/images/<machine>/工作目录在当前 build 下,路径模式:
tmp/work/<arch>-poky-linux/linux-yocto/<版本>-<修订>/例如 qemux86-64 上常见类似:
tmp/work/qemux86_64-poky-linux/linux-yocto/6.6.xx-r0/ ├── linux-qemux86_64-standard-build/ # 编译目录:.config、vmlinux ├── image/ # do_install 的暂存根 ├── packages-split/ # 打出来的各个子包 └── temp/ # 每个任务的日志 ├── log.do_configure ├── log.do_compile └── log.do_deploy版本号随你钉的 PREFERRED_VERSION 变化,以实际目录名为准。想确认「现在卡在哪一步」,打开对应 temp/log.do_* 即可,不必等整镜像结束。
编完后,内核相关文件会出现在两处,职责不同:
tmp/deploy/images/<machine>/bzImage | |
/lib/modules/<uname -r>/ | do_rootfs 装进用户态 |
镜像打包时再把它们和 rootfs 合到一起:
bzImage ──► wic / hddimg 的启动分区(GRUB 或 QEMU 直接加载)模块 ──► rootfs(/lib/modules/...)hello 等 ──► rootfs(/usr/bin/hello) ↓ core-image-base-*.wic / *.hddimg / *.tar.bz2这就是第 1~3 篇那条启动链在构建侧的对应关系:你等的不是「编一个 hello」,而是「编出能被 Bootloader 跳进去的内核 + 能被内核挂上的 rootfs」。
同一 build 目录同时只能跑一条 bitbake(有锁)。想先摸清内核任务,开编整镜像之前执行:
# 这个菜谱会跑哪些任务(名字即可,不必全懂)bitbake -c listtasks virtual/kernel# 只编内核、不组整镜像(第一次仍会拉工具链,但范围更小)bitbake virtual/kernel整镜像已经在跑时,不要再开第二条 bitbake。看当前 build 的终端输出即可;若长时间停在 linux-yocto 的 do_compile,属于正常:那就是在跑内核的 make -jN。要核对细节,直接读工作目录里的 temp/log.do_compile。
bitbake hello,成功后再构建完整镜像。路径可以拆开理解:
build-*/tmp/ | |
deploy/ | |
images/ | |
<machine>/ |
build-qemux86-64/tmp/deploy/images/qemux86-64/主要用途:第 11 篇在同一 WSL2 环境里 runqemu。
常见文件角色:内核、rootfs 相关镜像、wic 等;具体文件名以目录中实际为准。runqemu 通常会按当前 MACHINE 自动挑选合适文件。
build-genericx86-64/tmp/deploy/images/genericx86-64/主要用途:写 U 盘、双系统部署。
.wic | core-image-base-genericx86-64.rootfs.wic) |
.hddimg | |
.bmap | |
.tar.bz2 | |
虚机产物 → QEMU → kernel → rootfs → … → hello真机产物 → UEFI/BIOS → GRUB → kernel → rootfs → … → hello也就是说:你拿到的不是「某一个 hello 文件」而已,而是两套能被各自环境引导起来的系统材料。
build-qemux86-64 环境,直接 runqemu 即可 | |
真机文件清单:
*.rootfs.wic(以及若存在的 *.wic.bmap)*.hddimg*.rootfs.tar.bz2(双系统往硬盘分区部署时更方便)从 WSL2 拷到 Windows,可用 /mnt/c/Users/<你的用户名>/ 下的某个文件夹,或资源管理器访问 \\wsl$。
写入工具怎么选:
/mnt/c 下 | ~/ 下的 Linux 文件系统再试 |
bblayers.conf 是否加入 meta-demo;IMAGE_INSTALL 是否包含 hello | |
bitbake -e | grep "^MACHINE="build-*/tmp/deploy/images/<machine>/ | |
备注:官方 Quick Start(宿主依赖与兼容环境)见https://docs.yoctoproject.org/5.0/brief-yoctoprojectqs/
如果错误日志很长,先看第一处 error,不要只看最后几行翻滚输出。
bitbake core-image-base。build-qemux86-64,再 build-genericx86-64。linux-yocto 走 do_configure → do_compile → do_deploy,产物是 bzImage + 模块。tmp/deploy/images/<machine>/。下一篇:先用 QEMU 跑通 hello,再把真机镜像写入 U 盘完成双系统。配置如何用 Git 托管见第 12 篇。