ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

yocto: 15-image

yocto: 15-image 第5课是 Yocto 学习路线中最重要的一课之一。到目前为止你已经学会了1.建立 Build Environment2.自己写 recipehello、C 程序、script3.do_install4.PackagePACKAGES、FILES5.把 package 放进 image6.systemd service7.创建自己的 Layermeta-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内容SUMMARYMy Product ImageLICENSEMITinherit 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”例如SUMMARYMy ProductLICENSEMITinherit core-image IMAGE_INSTALLpackage生成后/usr/bin/package就进入 RootFS。五、加入多个 Package例如IMAGE_INSTALL \ package \ execute-c \ myservice \ 生成的 Imagepackage execute-c myservice全部都会安装。这也是以后产品 Image 最常见的写法。六、IMAGE_INSTALL 的工作流程例如IMAGE_INSTALL “package”BitBake 会执行package.bb ↓ 生成 package.ipk ↓ RootFS 安装 package ↓ 生成 Image所以Recipe ↓ Package ↓ Image这是固定流程。七、加入 SSH如果希望开机能够 SSHIMAGE_INSTALL “openssh”或者IMAGE_FEATURES “ssh-server-openssh”推荐IMAGE_FEATURES “ssh-server-openssh”因为它会自动处理依赖。八、加入调试工具例如IMAGE_FEATURES “debug-tweaks”效果允许root直接登录开发阶段方便。正式产品一般删除。九、一个比较完整的 Image例如SUMMARYMy Product ImageLICENSEMITinherit 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\ifmyproduct-image-raspberrypi2.wic\of/dev/sdX\bs4M\convfsync\statusprogress十一、与 local.conf 的区别很多初学者会把所有包都写在IMAGE_INSTALL:append package虽然可以工作但这只是当前 Build 配置。更推荐的做法是把产品需要的软件写进自己的 Image RecipeIMAGE_INSTALL \ package \ execute-c \ myservice \ 这样产品配置与构建配置分离Image Recipe 本身就定义了产品内容更容易维护、复用和版本管理。十二、本课实验推荐为了真正掌握 Image Recipe建议做一个完整实验1.创建目录meta-myproduct/ └── recipes-core/ └── images/ └── myproduct-image.bb2.编写一个最小的 myproduct-image.bb仅包含 inherit core-image。3.在 IMAGE_INSTALL 中加入你前面课程完成的三个软件包- package - execute-c - myservice4.执行bitbake myproduct-image5.将生成的 .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内容先不要写复杂只写最小版本SUMMARYMy Product ImageLICENSEMITinherit 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.bbSUMMARYMy Product ImageLICENSEMITinherit core-image IMAGE_FEATURESssh-server-opensshIMAGE_INSTALL \ product-test \ 这里会把你之前写的 product-test.bb如果这是你实际创建的 Recipe 名称加入到产品镜像中。到那时你会真正理解Recipe → Package → Image 的完整关系。请现在执行这两条命令bitbake myproduct-imagels tmp/deploy/images/raspberrypi2/myproduct*mp/deploy/images/raspberrypi2/myproduct-image-raspberrypi2.rootfs.ext3tmp/deploy/images/raspberrypi2/myproduct-image-raspberrypi2.rootfs.manifesttmp/deploy/images/raspberrypi2/myproduct-image-raspberrypi2.rootfs.spdx.tar.zsttmp/deploy/images/raspberrypi2/myproduct-image-raspberrypi2.rootfs.tar.bz2tmp/deploy/images/raspberrypi2/myproduct-image-raspberrypi2.rootfs.testdata.jsontmp/deploy/images/raspberrypi2/myproduct-image-raspberrypi2.rootfs.wic.bmaptmp/deploy/images/raspberrypi2/myproduct-image-raspberrypi2.rootfs.wic.bz2我们一起确认第一张属于你自己的产品 Image 已经生成。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进