系列第 9 篇|在 hello 之外:默认镜像、启动画面、内核版本、Bootloader Logo、时区语言、裁剪与包管理改完配置后,下一篇再开长构建;虚机 / 真机两套 build 共用这些定制
第 8 篇已经讲清:内核经 MACHINE 进镜像、apt 默认不在 core-image-base 里,以及「改 conf / 自己的 layer,不改 poky 原文件」。本篇按该原则动手,每项定制都先对照「改原文件」和「改 conf」两种方案,实际步骤走后者。回答七个常见问题:
这些改动对 qemux86-64 与 genericx86-64 同样适用(Bootloader Logo 以真机 GRUB 路径为主)。两套 build 都要生效时:优先改 meta-demo/conf/templates/*/local.conf.sample(便于第 12 篇用 Git 托管),并同步到已有的 build-qemux86-64/conf/local.conf 与 build-genericx86-64/conf/local.conf。改完后统一进第 10 篇 bitbake。
仍先对齐启动链——本篇会改到链上的多环:
bootloader(可改 Logo)→ linux kernel(可改版本)→ rootfs→ init → services → application ↑ 还可改 psplash / 时区 / 裁剪 / 包管理本系列镜像目标是 core-image-base。可以把它理解成:
在「能登录的最小系统」之上,再带上一组常见硬件相关支持,方便在 PC / 虚机上当「基础控制台系统」用。
core-image-basecore-image-minimal 多出的无线、蓝牙、声卡等相关 packagegroup | ||
IMAGE_INSTALL / IMAGE_FEATURES / PREFERRED_* / bbappend 决定 |
想确认「当前配方到底装了啥」,构建前可用:
bitbake -e core-image-base | grep "^IMAGE_INSTALL="构建后也可到 rootfs 目录或用目标机上的包管理命令核对(若已启用包管理,见第 7 节)。
这里的「启动闪屏」指:内核起来之后、进登录界面之前的 framebuffer 画面,不是桌面壁纸,也不是下一节的 GRUB Logo。
Yocto 里最常见的是 psplash。第 8 篇读过 core-image-base.bb:它已有 IMAGE_FEATURES += "splash",默认就会装 psplash。本节能改的是画面内容。
meta/recipes-core/psplash/ 下的默认 PNG(文件名以本机 SRC_URI / SPLASH_IMAGES 为准) | meta-demo | |
meta-demo 写 .bbappend,用 FILESEXTRAPATHS 覆盖同名 PNG |
换图没有「一行 local.conf 变量」可换路径,bbappend 就是配置层做法,不要去 poky 里覆盖原文件。
部分发行版也会用 SPLASH 指向别的闪屏实现;入门保持默认 psplash 即可。若你用的不是 core-image-base、确认没有 splash,再在 local.conf 追加:
IMAGE_FEATURES:append = " splash"# 或:IMAGE_INSTALL:append = " psplash"meta-demo 里为 psplash 写一个 .bbappend;bitbake core-image-base。图片尺寸与格式(psplash)
psplash 画的是「居中 Logo + 进度条」,不是全屏壁纸(全屏背景见下一节 GRUB)。现代 Poky 菜谱接受 PNG,构建时由 make-image-header.sh(内部用 gdk-pixbuf-csource)转成 C 头文件再编进 psplash 可执行文件。
| PNG | |
| 无固定分辨率要求 | |
220×137、427×214 等);入门可用 约 200~500 px 宽 的 Logo | |
psplash-poky.png / psplash-poky-img.png(以本机 psplash 菜谱 SRC_URI / SPLASH_IMAGES 为准) |
实践建议:先用一张小而清晰的 Logo(例如 320×180)在 qemux86-64 上验证流程,确认能显示后再换成最终品牌图。
示意目录:
meta-demo/recipes-core/psplash/ psplash_%.bbappend files/psplash-poky.pngpsplash_%.bbappend 示意:
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"# 用同名文件覆盖上游默认图;具体文件名以本机 psplash 菜谱为准SRC_URI:append = " file://psplash-poky.png"改完后务必先在 qemux86-64 上验证。
两条可以同时做:先看到 GRUB Logo,再看到 psplash,最后进登录。
本系列真机路径是 UEFI → GRUB → 内核(见第 2 篇)。「Bootloader 启动 Logo」在这里就是:给 GRUB 菜单换一张背景图。
qemux86-64的 QEMU 启动路径往往不经过完整 GRUB 菜单体验;Logo 验证以genericx86-64(U 盘 / 双系统)为主。配置仍建议写进共用的meta-demo,两套 build 都能编进产物。
meta/recipes-bsp/grub/(或本机实际的 grub-bootconf / grub-efi 菜谱)里直接换 PNG、改 grub.cfg 片段 | ||
meta-demo 写 bbappend:把 PNG 打进 boot 分区,并追加 background_image 等 cfg 片段 |
GRUB 背景同样没有现成的 GRUB_LOGO = "..." 变量可写在 local.conf 里,方案 B 用 bbappend 完成「装图 + 改 cfg」。下面按方案 B 做。
meta-demo/recipes-bsp/grub/ files/boot-logo.png grub-bootconf_%.bbappend(菜谱名因 Yocto 版本略有差异:可能是 grub-bootconf、grub-efi 相关 append,或镜像后处理。先在 poky 里 find . -name '*grub*bootconf*' / bitbake -e | grep -i grub 确认本机实际菜谱名,再命名 bbappend。)
目标效果等价于在 GRUB 配置里增加类似片段:
insmod all_videoinsmod gfxterminsmod pngset gfxmode=autoterminal_output gfxtermbackground_image -m stretch /boot-logo.png示意 bbappend(按本机菜谱字段微调):
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"SRC_URI:append = " file://boot-logo.png"do_install:append() { install -m 0644 ${WORKDIR}/boot-logo.png ${D}/boot-logo.png}# 若菜谱用 cfg 片段组装 grub.cfg,可追加自己的片段文件;# 或用 ROOTFS_POSTPROCESS / wic 钩子把 background_image 写进最终 grub.cfg。background_image 读到文件 | |
grub.cfg 里启用 gfxterm + 加载 png 模块 | |
timeout |
genericx86-64,写 U 盘或装双系统(第 11 篇)。嵌入式板上若走 U-Boot,Logo 定制方式完全不同(splash 环境变量 / 厂商工具)。本系列 PC demo 只覆盖 GRUB。
启动链上的下一环是内核。Yocto 不会「随便下一个最新 mainline」;它用 virtual/kernel 指向具体菜谱(本系列 x86 机型默认多为 linux-yocto),版本由该菜谱的 PV / PREFERRED_VERSION 决定。
在已 source 的 build 环境中:
# 当前 virtual/kernel 由谁提供、版本是多少bitbake -e virtual/kernel | grep -E '^(PREFERRED_PROVIDER_virtual/kernel|PN|PV)='# 本层可见的 linux-yocto 版本列表bitbake -s | grep '^linux-yocto '也可以到源码树里直接看菜谱文件名,例如:
meta/recipes-kernel/linux/linux-yocto_6.6.bb文件名里的版本号,就是你「可以选」的候选之一——只能选本套 poky / layer 里已经存在的菜谱,不能凭空写一个上游还没提供的版本号。
在 local.conf(及对应 TEMPLATECONF)中追加,例如:
# 提供内核的菜谱(x86 默认一般已是 linux-yocto,可显式写出)PREFERRED_PROVIDER_virtual/kernel = "linux-yocto"# 钉住大版本;% 表示匹配该前缀下的具体修订号PREFERRED_VERSION_linux-yocto = "6.6%"PREFERRED_PROVIDER_virtual/kernel | linux-yocto;换厂商内核时才改) |
PREFERRED_VERSION_linux-yocto = "6.6%" | linux-yocto_*.bb 并存时,优先选 6.6.x |
改完后立刻校验:
bitbake -e virtual/kernel | grep '^PV='应看到你钉住的版本前缀。再 bitbake virtual/kernel 或整编镜像时,内核会按新版本重编(耗时明显,属正常)。
只换版本用上面两行即可。若还要加驱动补丁或改 .config,在 meta-demo 里追加:
meta-demo/recipes-kernel/linux/ linux-yocto_%.bbappend files/demo.cfg # 可选:配置片段 files/0001-demo.patch # 可选:补丁linux-yocto_%.bbappend 示意:
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"SRC_URI:append = " \ file://demo.cfg \ file://0001-demo.patch \"配置片段里写 CONFIG_XXX=y 这类一行一项即可;具体是否被 linux-yocto 的 kernel-meta 机制吸收,以你所用 Yocto 版本文档为准。入门阶段:先会钉版本,再按需加补丁。
preferred version ... not available。uname -r 确认,应与你钉的版本一致。目标:进系统后时间对、中文环境可用(至少 locale 数据齐全)。
tzdata 菜谱里的默认 DEFAULT_TIMEZONE(常见默认是 Universal / UTC) | local.confDEFAULT_TIMEZONE = "Asia/Shanghai" | |
meta-poky/conf/distro/poky.conf 里的 IMAGE_LINGUAS 等 | local.confIMAGE_LINGUAS、GLIBC_GENERATE_LOCALES |
时区和语言正好是为 conf 准备的旋钮:方案 B 两行就能钉住,不必 fork 上游 distro。好处见第 8 篇:升级 poky 不丢设置,两套 MACHINE 的模板各写一份(或共用同一段)即可复现。
下面只写方案 B。在 conf/local.conf 中追加:
# 时区:中国常用 Asia/ShanghaiDEFAULT_TIMEZONE = "Asia/Shanghai"# 镜像携带的语言包(按需增减)IMAGE_LINGUAS = "en-us zh-cn"# glibc 生成哪些 locale(与上面呼应)GLIBC_GENERATE_LOCALES = "\ en_US.UTF-8 \ zh_CN.UTF-8"DEFAULT_TIMEZONE | /etc/localtime 指向哪个时区。不做这一步,很多镜像默认是 UTC,你会感觉「时间差八小时」 |
IMAGE_LINGUAS | zh-cn) |
GLIBC_GENERATE_LOCALES | LANG 却没生成对应 locale,运行时容易出现警告或回退到 C locale |
datetimedatectl status # 若有 systemdlocaleecho$LANG若时区不对,先查镜像是否安装了 tzdata,以及 DEFAULT_TIMEZONE 是否写进了本次构建。
控制台字体能否完美显示中文,还取决于终端 / 字体包,不只是 locale。本篇目标是「时区与语言数据正确」;完美中文 TUI/GUI 可后续再加字体与终端配置。
裁剪的原则很简单:
能不装的包,就不要装进 rootfs;必须装但默认不该开机自启的服务,就关掉自动启用。
在 local.conf:
# 示例:不要装某个包(名字换成你要去掉的)IMAGE_INSTALL:remove = "\ packagegroup-base-wifi \ packagegroup-base-bluetooth"# 更强硬:构建时直接排除(注意依赖可能被连带)PACKAGE_EXCLUDE += "\ bluez5"IMAGE_INSTALL:remove | ||
PACKAGE_EXCLUDE |
# 示例:去掉不需要的 IMAGE_FEATURESEXTRA_IMAGE_FEATURES:remove = "\ tools-debug \ dbg-pkgs"文档包、调试符号、开发头文件等,往往经 IMAGE_FEATURES / EXTRA_IMAGE_FEATURES 进来。产品镜像通常不需要它们。
若 DISTRO 使用 systemd,可在自己的 recipe 或 image 的后处理里禁用单元,例如:
# 写在某个 bbappend / image 配方中的示意SYSTEMD_AUTO_ENABLE:${PN} = "disable"或在 image 的 ROOTFS_POSTPROCESS_COMMAND 里对指定 unit 做 systemctl mask。入门阶段更推荐:
IMAGE_INSTALL:remove 去掉整包;第 5 篇讲过:Ubuntu 用 apt,Fedora 用 dnf。第 8 篇也强调过:core-image-base默认不带 apt——PACKAGE_CLASSES 只管构建时打哪种包,目标机要带包管理器还得打开 package-management。
若你希望目标系统也能像发行版一样「以后再装包」,需要两件事:
package-management 镜像特性。core-image-base.bb 里加 IMAGE_FEATURES += "package-management",并改 meta-poky 模板里的 PACKAGE_CLASSES | ||
local.conf / TEMPLATECONF 里设 PACKAGE_CLASSES 和 EXTRA_IMAGE_FEATURES |
要 apt 就选 package_deb;保持 Poky 默认 rpm 则目标机是 rpm / dnf 一族。不要为了装 apt 去改 core-image-base.bb。
# 三选一(与工具链习惯有关,选一种坚持用)PACKAGE_CLASSES ?= "package_rpm"# PACKAGE_CLASSES ?= "package_ipk"# PACKAGE_CLASSES ?= "package_deb"# 把包管理器与在线/离线装包能力打进镜像EXTRA_IMAGE_FEATURES += "package-management"package_rpm | rpmdnf(视具体配方而定) |
package_ipk | opkg |
package_deb | dpkgapt 一族 |
本系列读者若更熟 Ubuntu,可尝试 package_deb;若更偏嵌入式资料,package_ipk 也很常见。关键是:构建时的 PACKAGE_CLASSES 与目标机工具要一致。
IMAGE_INSTALL | ||
package-management |
两者可以同时存在:预装保底功能,包管理负责后续扩展。
打开包管理会增大镜像,并引入「运行时改系统」的能力。产品固件若强调只读、可复现,可能故意不装包管理器,只在构建时用 IMAGE_INSTALL 固化内容。按你的场景选择即可。
把本篇常用项收成一块,按需删减后追加到第 8 篇已有配置之后(两套 MACHINE 的模板 / local.conf 都建议加上):
# --- 09 进一步定制(按需启用)---# 启动闪屏(用户空间)IMAGE_INSTALL:append = " psplash"# 内核版本(版本号须是本套 poky 里真实存在的;先 bitbake -s | grep linux-yocto)PREFERRED_PROVIDER_virtual/kernel = "linux-yocto"# PREFERRED_VERSION_linux-yocto = "6.6%"# 时区与语言DEFAULT_TIMEZONE = "Asia/Shanghai"IMAGE_LINGUAS = "en-us zh-cn"GLIBC_GENERATE_LOCALES = "\ en_US.UTF-8 \ zh_CN.UTF-8"# 预装包管理(示例用 rpm;可改 ipk/deb)PACKAGE_CLASSES ?= "package_rpm"EXTRA_IMAGE_FEATURES += "package-management"# 裁剪示例(确认不需要再取消注释)# IMAGE_INSTALL:remove = "\# packagegroup-base-bluetooth"# EXTRA_IMAGE_FEATURES:remove = "\# tools-debug"GRUB Logo / psplash 换图没有对应的local.conf变量,方案 B 靠meta-demo里的 bbappend 与资源文件,不要去 poky 里覆盖原图。钉内核版本用上面的PREFERRED_*;换图后记得把 bbappend 一并纳入第 12 篇的 Git 托管。
改完后仍建议先做轻量校验,再进入长构建:
bitbake -e | grep "^MACHINE="bitbake -e | grep "^DEFAULT_TIMEZONE="bitbake -e virtual/kernel | grep -E '^(PN|PV)='bitbake -e core-image-base \ | grep "^IMAGE_FEATURES="core-image-base = 最小可登录系统 + 一组可裁的中等能力 + 你追加的包。meta-demo),不改 poky 原文件:时区、语言、包管理用 local.conf 变量;psplash / GRUB Logo 换图用 bbappend。core-image-base 已启用 splash;换图用 bbappend。grub.cfg);以 genericx86-64 验证为主。PREFERRED_PROVIDER / PREFERRED_VERSION 钉住本套 poky 已有的 linux-yocto;可选 bbappend 打补丁。DEFAULT_TIMEZONE,语言看 IMAGE_LINGUAS 与 locale 生成。IMAGE_INSTALL:remove / IMAGE_FEATURES,服务自启再细调。PACKAGE_CLASSES 并打开 package-management;要 apt 用 package_deb,不要改 core-image-base.bb。下一篇在 WSL2 里执行 bitbake core-image-base,分别产出虚机与真机镜像。