Portal:MicroOS/Yocto

跳转到:导航搜索

使用 Yocto 创建 MicroOS 包

Yocto 项目 [1] 是一个基于 OpenEmbedded [2] 的构建系统,用于为嵌入式系统创建 Linux 发行版。Poky 是 Yocto 的参考发行版,大多数开发者为他们的系统创建 Poky 衍生版,重用和调整不同的 Poky 层和配方,并集成他们自己的驱动程序和应用程序。

openSUSE MicroOS 是一个不可变、事务性、滚动发布的发行版,使用 open build service (OBS) [3] 构建。相同的构建系统可以用于为现有发行版创建不同的发行版和软件包(如 Debian、RedHat 或 Arch)。

在某些领域,Yocto 是开发者和集成商的事实标准,一些制造商将内核补丁和驱动程序作为板级支持包 (BSP) 层或 bitbake 配方部署。从技术上讲,OBS 可以被调整为构建这些组件,但这将不是一项简单的任务,而且也没有 Yocto 开发者可以提供帮助。

另一种方法是看看是否可以使用 Yocto 构建 MicroOS 的软件包,使用更接近他们的工具和生态系统。

初始方法

从一开始,Yocto 就支持集成第三方工具链,如 Linaro、Arm 或 Sourcery。可以下载这些 SDK,并配置 Yocto 在创建 sysroot 和发行包时使用它们。

要配置工具链,需要提供一些 meta 文件。随着时间的推移,这些 meta 文件合并到一个项目中,即 meta-arm-toolchain,作为 meta-arm 层 [4] 的一部分。

该项目的旧版本使用了这个 meta-arm-toolchain(meta-arm 的一个子层),但需要手动修补该层才能找到 MicroOS 交叉编译器的某些组件。此外,该层的做法是重新打包交叉编译器的某些库并使其在目标系统上可用。这对于从头开始编译的发行版来说是正确的方法,但对于已经有二进制软件包的发行版来说则不然。

旧方法的另一个问题是用户需要手动提供构成配方依赖项的 MicroOS 库,并将它们部署到 sysroot 中,而没有明确的机制。

这种初始方法用于验证 Yocto 确实可以用于构建 MicroOS 包的想法,在这方面,这是一个成功。

如果您有兴趣了解更多关于原始想法的细节,可以查看此页面的编辑历史记录。

一种新的方法

基于经验教训,新想法基于三个原则

- 提供一个 "microos" Yocto 发行版

- 自动按需将二进制 RPM 导入 sysroot

- 使用可用的交叉编译器,而无需提取任何子包,使用 MicroOS 中已有的那些

Yocto 发行版允许管理当前和新配方之间共享的某些全局配置、控制当前版本以及定义外部编译器。

由于 MicroOS 已经使用 OBS 构建,我们已经有了发行版的全部 RPM 包。Yocto 配方可以被调整为获取、解包和部署 MicroOS 包到 Yocto sysroot 中。使用 "scripts/microos -u" 我们可以将 "meta-microos" 配方更新到最新的 MicroOS 发布版本,这将指向当前版本的软件包,更新依赖项、提供者、许可证和校验和。

新的配方现在可以直接 "依赖" 这些 MicroOS 包,Yocto 将负责在 "do_compile" 任务期间将内容移动到 sysroot 中以便链接。

最后,交叉编译器不再污染目标系统。在以前的方法中(如在 meta-arm-toolchain 中所做的那样),一些文件和库被重新打包并部署到配方 sysroot 中。正如所评论的,当发行版从源代码构建时,那是正确的方法,但对于 MicroOS,我们已经在不同的 RPM 包中有了相同的库。glibc、glibc-devel 或 gcc 库现在使用 MicroOS 当前版本。

工具链安装

工具链被部署为 tarball,其中包含用于为 MicroOS 编译应用程序的交叉编译器、二进制文件和库。它使用与 MicroOS 可用的相同编译器和库,但依赖于旧版本的 glibc,因此可以在不同的 Linux 发行版中使用。

目前,该工具链并非完全自包含,在这方面还有更多的工作要做。现有的工具链足以在其他发行版(如 Debian、Ubuntu 或 RedHat)中进行成功的构建。

安装只需要下载 tarball 并将其放置在系统中

 mkdir -p cross-sdk && cd cross-sdk
 wget https://download.opensuse.org/repositories/home:/aplanas:/yocto/images/cross-sdk.x86_64.tar.xz
 tar -xJvf cross-sdk.x86_64.tar.xz

此版本的工具链正在开发中,将来会发生变化,但安装过程将保持不变。

有一种版本的相同工具链部署为容器,可以使用 Podman 安装

 podman pull registry.opensuse.org/home/aplanas/yocto/containerfile/opensuse/yocto-microos:latest

该容器还提供了 Yocto 所需的依赖项,因此它是开始创建新的 MicroOS 包的最简单方法。容器的完整文档可以在 OBS 项目的 README 文件中找到 [5]。

安装 meta-microos

新的 meta-microos 层包含 Yocto 中 MicroOS 发行版的定义、定义 openSUSE MicroOS 和 Tumbleweed 的配方集合,以及外部交叉编译器的配置文件。

该层可以直接通过 git 安装。主分支代表 Poky 的最新稳定版本(撰写本文时为 "mickledore")。

 git clone https://github.com/aplanas/meta-microos.git

安装 Yocto

有很多关于如何安装 Yocto 的信息 [6]。如果我们在使用虚拟机或物理主机,我们需要安装 Yocto 所需的一些依赖项,如 gcc、git 和 Python。请参阅项目文档 [7] 以获取完整的需求列表。

如果您正在使用容器,则这些依赖项已经可用。

第一步应该是克隆 Poky git 存储库

 git clone git://git.yoctoproject.org/poky -b mickledore

Poky 是 Yocto 的参考发行版,但也捆绑了所有 OpenEmbedded Core 配方和层、相关的 bbclass、bitbake 工具集以及 Yocto 脚本和文档。

我们不会使用 "master",而是切换到 "mickledore" 分支,其中包含最新的(撰写本文时)稳定 Poky 发布版本。

对于此版本,我们需要从 "master" 分支移植一个提交。

 cd poky
 git cherry-pick cc2c3b1b62070db2b84d967ce20a1651fd50b7fb

这可能会导致冲突,很容易解决。下一个 Yocto 稳定版本将默认包含此更改。

现在我们可以使用以下命令创建构建目录和配置文件

 source oe-init-build-env

此脚本还会设置多个环境变量(包括 PATH),因此每次要使用 Yocto 时都需要对其进行 sourcing。

第一次调用它将创建构建目录(并将我们放置在其中),以及 conf/bblayers.conf 和 conf/local.conf 配置文件,我们需要对其进行调整。

对于 conf/bblayers.conf,我们需要注册 meta-microos 和 meta-example(稍后描述)层,以便 bitbake 在解析阶段可以找到它们。因此,请确保 BBLAYERS 变量如下

 BBLAYERS ?= " \
   ...
   FULL-PATH/meta-microos \
   FULL-PATH/meta-example \
   "

对于 conf/local.conf,我们需要请求 "microos" 发行版并将目标设置为 aarch64 机器。我们需要指示外部工具链的路径。将这些行添加到文件末尾

 DISTRO = "microos"
 MACHINE ?= "qemuarm64"
 DEFAULTTUNE = "aarch64"
 EXTERNAL_TOOLCHAIN = "FULL-PATH/cross-sdk"

创建 MicroOS 包

最后一步是创建这个 "meta-example" 层,它将包含我们可以编译的东西。为了演示,我准备了一个精简的、自包含的,并进行了一些调整以针对 MicroOS。

 git clone https://github.com/aplanas/meta-example.git

配方 (example-c_0.1.bb) 是一个默认配方,它直接调用 "gcc" 编译器并生成一个二进制文件。默认情况下,它将自动依赖 glibc,但可以在配方中添加其他依赖项。

 bitbake example-c

这将生成 RPM 并将其放置在构建目录中的 tmp/work/aarch64-poky-linux/example/0.1-r0/deploy-rpms/aarch64 中。此包可以直接安装到我们的 MicroOS 系统中。

查看此存储库以查找其他示例。

MicroOS 和 Tumbleweed

“meta-microos” 包含一个快照,可以自动生成 Tumbleweed 和 MicroOS 的所有软件包的配方。

我们可以使用以下命令更新这些配方

 ./scripts/microos -u

这将更新 "pool-tumbleweed" 中的所有软件包以及 "recipes-microos" 中构成 MicroOS 的子集。该脚本还会负责更新分发文件中 MicroOS 的版本,以及 "recipes-microos/opensuse_microos.group" 文件,其中包含构成 MicroOS 的 Tumbleweed 包的列表。

MicroOS 的配方是链接到 pool 目录中的配方的,但该脚本会在引入或删除新包时检测并更新这些链接。

默认情况下,Yocto 无法看到软件包池。Yocto 还没有准备好解析和分析 50000 个配方。为了解决这个问题,除了 "recipes-microos" 的拆分之外,我们还在 "recipes-devtools" 和 "recipes-core" 中包含其他子集。

第一个子集是不属于 MicroOS 组但需要在构建新软件包时需要的软件包(如编译器、binutils 等)。我们可以使用 "scripts/import/ "工具创建我们自己的拆分

 mkdir recipes-my-set
 ./script/import -r recipes-my-set mylib

这将从池中创建链接到请求的软件包和所有缺少的依赖项的新配方目录。如果脚本在依赖关系图闭包遍历期间找到多个提供者,我们可以使用 "--preferred" 参数来消除歧义。

Yocto 还收集了编译过程中找到的各种许可证,包括 MicroOS 包的许可证。如果未识别许可证,Yocto 默认配置为停止编译并显示错误消息。如果我们将许可证识别为有效许可证,则需要在 "meta-microos" 层的 "license" 目录中包含它才能继续编译。

问题和未来工作

项目的当前状态表明我们可以很好地将 MicroOS 与 Yocto 集成,并且可以使用相同的签名包为 aarch64 生成新的软件包。

但仍有一些方面可以改进。

当前的工具链并非完全自包含。应该使用 PatchELF 来修复这个问题,将一些库从系统中指向捆绑包。但还缺少一些其他编译器,如 Fortran、Go 或 Rust。还需要包含其他架构,如 RISC-V。

从 Yocto 集成的角度来看,还有更多步骤需要在当前方向上完成,例如验证使用 autotools 的配方、提供内核模块或生成最终 ISO 镜像。

参考资料

[1] https://www.yoctoproject.org/

[2] https://www.openembedded.org/wiki/Main_Page

[3] https://openbuildservice.org/

[4] https://git.yoctoproject.org/meta-arm/

[5] https://build.opensuse.org/package/show/home:aplanas:yocto/yocto-microos-image

[6] https://docs.yoctoproject.org/brief-yoctoprojectqs/index.html

[7] https://docs.yoctoproject.org/ref-manual/system-requirements.html