拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

yocto: 15-image

yocto: 15-image

第5课:是 Yocto 学习路线中最重要的一课之一。
到目前为止,你已经学会了:
1.建立 Build Environment
2.自己写 recipe(hello、C 程序、script)
3.do_install
4.Package(PACKAGES、FILES)
5.把 package 放进 image
6.systemd service
7.创建自己的 Layer(meta-myproduct)

现在开始真正做一个产品镜像(Product Image)。


第05课:自己写 Image Recipe —— 掌握产品 Image
学习目标
理解:

image recipe IMAGE_INSTALL inherit core-image IMAGE_FEATURES

最终做到:bitbake myproduct-image
得到属于自己的:myproduct-image-raspberrypi2.wic

而不是一直使用: core-image-minimal


一、为什么要自己写 image
以前一直编译:bitbake core-image-minimal
实际上:core-image-minimal.bb 也是一个 recipe。
它只是告诉 BitBake:我要哪些 package
例如:

BusyBox systemd kernel modules...

所以:

Image Recipe 的作用就是:决定 RootFS 中安装哪些 Package。

可以理解成:

Application Recipe ↓ 生成 package Package ↓ 放进 Image Image ↓ 生成 SD Card

整个 Yocto 就围绕这个流程。


二、Image Recipe 放哪里?
放到自己的 Layer。
例如:

meta-myproduct/ recipes-core/ images/ myproduct-image.bb

推荐目录:

meta-myproduct └── recipes-core └── images └── myproduct-image.bb

三、最简单的 Image
建立:myproduct-image.bb
内容:

SUMMARY="My Product Image"LICENSE="MIT"inherit core-image

只有这一句:inherit core-image
就已经是一张 Image。
因为:core-image.bbclass 已经实现:

- rootfs - image - wic - ext4 - manifest

全部流程。


四、加入自己的 Package
例如:

meta-myproduct recipes-example package

里面有:package.bb
那么:IMAGE_INSTALL += “package”
例如:

SUMMARY="My Product"LICENSE="MIT"inherit core-image IMAGE_INSTALL+="package"

生成后:/usr/bin/package

就进入 RootFS。


五、加入多个 Package
例如:

IMAGE_INSTALL+=" \ package \ execute-c \ myservice \ "

生成的 Image:

package execute-c myservice

全部都会安装。

这也是以后产品 Image 最常见的写法。


六、IMAGE_INSTALL 的工作流程
例如:IMAGE_INSTALL += “package”
BitBake 会执行:

package.bb ↓ 生成 package.ipk ↓ RootFS 安装 package ↓ 生成 Image

所以:

Recipe ↓ Package ↓ Image

这是固定流程。


七、加入 SSH
如果希望开机能够 SSH:IMAGE_INSTALL += “openssh”
或者:IMAGE_FEATURES += “ssh-server-openssh”
推荐:IMAGE_FEATURES += “ssh-server-openssh”

因为它会自动处理依赖。


八、加入调试工具
例如:IMAGE_FEATURES += “debug-tweaks”
效果允许:root
直接登录(开发阶段方便)。

正式产品一般删除。


九、一个比较完整的 Image
例如:

SUMMARY="My Product Image"LICENSE="MIT"inherit core-image IMAGE_FEATURES+=" \ ssh-server-openssh \ debug-tweaks \ "IMAGE_INSTALL+=" \ package \ execute-c \ myservice \ "

以后真正产品可能就是这样维护。


十、开始编译
编译:bitbake myproduct-image
生成:

tmp/deploy/images/raspberrypi2/ myproduct-image-raspberrypi2.wic myproduct-image-raspberrypi2.rootfs.tar.bz2 myproduct-image-raspberrypi2.manifest

以后烧录:

sudodd\if=myproduct-image-raspberrypi2.wic\of=/dev/sdX\bs=4M\conv=fsync\status=progress

十一、与 local.conf 的区别
很多初学者会把所有包都写在:IMAGE_INSTALL:append = " package"
虽然可以工作,但这只是当前 Build 配置。
更推荐的做法是把产品需要的软件写进自己的 Image Recipe:

IMAGE_INSTALL+=" \ package \ execute-c \ myservice \ "

这样产品配置与构建配置分离,Image Recipe 本身就定义了产品内容,更容易维护、复用和版本管理。


十二、本课实验(推荐)
为了真正掌握 Image Recipe,建议做一个完整实验:
1.创建目录:

meta-myproduct/ └── recipes-core/ └── images/ └── myproduct-image.bb

2.编写一个最小的 myproduct-image.bb,仅包含 inherit core-image。

3.在 IMAGE_INSTALL 中加入你前面课程完成的三个软件包:

- package - execute-c - myservice

4.执行:bitbake myproduct-image
5.将生成的 .wic 烧录到 SD 卡,启动 Raspberry Pi 2,验证:

- package 可以执行。 - execute-c 可以正常运行。 - myservice 开机自动启动(如果已配置为 systemd 服务)。

完成这一课后,你已经具备了 Yocto 产品开发的基本能力:不仅能编写单个 Recipe,还能通过自己的 Image Recipe 定义一整套产品镜像。下一步建议学习 自定义发行版(Distribution),

理解 DISTRO、DISTRO_FEATURES 和产品级配置,这将帮助你进一步将 Build 配置、产品镜像和发行版职责清晰分离。


Build 一个最小的image
第1步:确认自己的 Layer 已经加入 bblayers.conf
进入 build 目录:cd ~/yocto/build-rpi2
查看:cat conf/bblayers.conf
应该能看到类似:

BBLAYERS ?=" \ ... ~/yocto/meta-myproduct \ "

如果能看到:meta-myproduct

说明 Layer 已经启用。


第2步:建立 Image Recipe 目录
先看看现在有没有 images 目录。
执行:

cd~/yocto/meta-myproductfind.-maxdepth3-typed

如果没有 recipes-core/images
我们就建立它:mkdir -p recipes-core/images

然后进入:cd recipes-core/images


第3步:建立 myproduct-image.bb
创建文件:touch myproduct-image.bb
编辑:vi myproduct-image.bb
内容先不要写复杂,只写最小版本:

SUMMARY="My Product Image"LICENSE="MIT"inherit core-image

保存退出。


第4步:确认文件位置
执行:find ~/yocto/meta-myproduct -name “myproduct-image.bb”
应该看到:/home/cxicc/yocto/meta-myproduct/recipes-core/images/myproduct-image.bb
为什么先写这么少?
很多初学者一开始就写:

IMAGE_INSTALL+="..."IMAGE_FEATURES+="..."

结果出错时,不知道是 Image Recipe 本身 有问题,还是 Package 有问题。
我们采用工程师常用的方法:
1.先建立一个最小 Image(只有 inherit core-image)。
2.确认 BitBake 能识别它。
3.再一步步加入 IMAGE_INSTALL、IMAGE_FEATURES。
4.最后再加入自己的 Package。

这样出了问题,很容易定位。

你的目录结构已经正确:

meta-myproduct/ ├── conf ├── recipes-core │ └── images │ └── myproduct-image.bb └── recipes-test

这完全符合 Yocto 的规范。


第5步:确认 BitBake 能识别 myproduct-image
这是最关键的一步。
在 build-rpi2 目录执行:cd ~/yocto/build-rpi2

然后:bitbake-layers show-recipes | grep myproduct


如果没有任何输出

再执行:bitbake-layers show-recipes | grep image


为什么要做这一步?
很多人一开始就执行:bitbake myproduct-image
如果失败:ERROR: Nothing PROVIDES ‘myproduct-image’
就不知道原因。
实际上可能是:

- Layer 没扫描到 - .bb 文件名错误 - BBFILES 配置错误 - Recipe 语法错误

所以我们先确认 BitBake 是否已经发现这个 Recipe。


预期结果
理想情况下,你应该能看到类似:

myproduct-image: meta-myproduct1.0meta-myproduct1.0

只要出现 myproduct-image,说明 Recipe 已经被 BitBake 收录了。
出现了两次。这通常意味着 有两个同名的 myproduct-image.bb 被扫描到了,或者 BBFILES 配置重复了。
现在先不用处理,因为它不会影响我们继续学习。等课程结束后,我们再找出原因并整理 Layer。

第6步:第一次编译自己的 Image
现在真正开始编译。
进入 build 目录:cd ~/yocto/build-rpi2
执行:bitbake myproduct-image

第一次编译可能需要几分钟。


编译完成后,不要急着烧录。
请继续执行:ls tmp/deploy/images/raspberrypi2/myproduct*
你应该能看到类似:

myproduct-image-raspberrypi2.rootfs.tar.bz2 myproduct-image-raspberrypi2.manifest myproduct-image-raspberrypi2.wic

为什么先编译一个"空 Image"?
这是一个最小 Image。如果它能成功编译,就证明:
✅ Layer 正确
✅ Image Recipe 正确
✅ Yocto Image 流程正确


Build 真正的产品 Image
这一课将进入真正的产品 Image
在最小 Image 编译成功后,我们会逐步修改 myproduct-image.bb:

SUMMARY="My Product Image"LICENSE="MIT"inherit core-image IMAGE_FEATURES+="ssh-server-openssh"IMAGE_INSTALL+=" \ product-test \ "

这里会把你之前写的 product-test.bb(如果这是你实际创建的 Recipe 名称)加入到产品镜像中。到那时,你会真正理解
Recipe → Package → Image 的完整关系。


请现在执行这两条命令
bitbake myproduct-image
ls tmp/deploy/images/raspberrypi2/myproduct*

mp/deploy/images/raspberrypi2/myproduct-image-raspberrypi2.rootfs.ext3
tmp/deploy/images/raspberrypi2/myproduct-image-raspberrypi2.rootfs.manifest
tmp/deploy/images/raspberrypi2/myproduct-image-raspberrypi2.rootfs.spdx.tar.zst
tmp/deploy/images/raspberrypi2/myproduct-image-raspberrypi2.rootfs.tar.bz2
tmp/deploy/images/raspberrypi2/myproduct-image-raspberrypi2.rootfs.testdata.json
tmp/deploy/images/raspberrypi2/myproduct-image-raspberrypi2.rootfs.wic.bmap
tmp/deploy/images/raspberrypi2/myproduct-image-raspberrypi2.rootfs.wic.bz2我们一起确认第一张属于你自己的产品 Image 已经生成。

返回列表