使用 Yocto 进行 OpenSTLinux 系统的构建
使用 Yocto 进行 OpenSTLinux 系统的构建
前言:
Yocto 项目是一个基于 Linux 的开源操作系统构建框架,专为嵌入式设备和物联网设备设计。它提供了一个全面的工具链和文档集,支持从源代码构建完整的 Linux 系统,包括内核、根文件系统、应用程序和库等。Yocto 项目的核心组件包括 OpenEmbedded 构建系统(基于 BitBake)、Poky 参考发行版以及丰富的元数据集。通过 Yocto,开发者可以创建高度定制化的 Linux 发行版,以满足不同硬件平台和应用需求。本文主要记录如何使用 Yocto 项目进行 OpenSTLinux 系统的构建与开发。OpenSTLinux 是一个专为 STMicroelectronics 的硬件平台设计的 Linux 发行版,它充分利用了 Yocto项目的灵活性和可定制性,为开发者提供了强大的工具来优化和扩展其嵌入式系统的功能。
开始前:
在使用 Yocto 前,我们先了解一些相关工具和项目的概念。
- Yocto 与 OpenEmbedded :Yocto 项目起源于 OpenEmbedded 项目并与之协作,它和 OpenEmbedded 共享一个核心元数据集合,称为 OpenEmbedded-Core。OpenEmbedded 为各种体系结构、功能和应用程序提供了一套全面的元数据,而 Yocto 专注于为一组核心架构和特定单板提供功能强大、易于使用、可互操作、经过良好测试的工具、元数 据和 BSPs。
- Poky:Poky 是 Yocto 参考嵌入式发行版 OS,实际上是一个有效的构建实例,它包含构建系统(Bitbake、OpenEmbedded Core、meta-poky、meta-yocto-bsp)以及一组元数据,可帮助我们构建自己的发行版。要使用 Yocto 工具和组件,需要下载(clone)Poky 并使用它来引导构建自己的发行版。
- BitBake:BitBake 是 OpenEmbedded 构建系统中的一个关键组件,它负责控制构建过程并解决依赖关系。BitBake 使用描述文件(.bb 或 .bbappend 文件)来确定如何构建每个软件包,并确保所有依赖项都得到满足。
- Devtool:Devtool 是 Yocto 项目中的一个命令行工具,旨在简化软件开发、测试和打包的流程。它为开发者提供了操作菜谱、修改源代码、构建软件包以及将生成的软件集成到镜像中的功能。Devtool 特别适用于可扩展 SDK 环境,可以大大提高开发效率。
相关文档:
openEuler Embedded 在线文档
BitBake 手册
Yocto 构建的工作流
通常,Yocto 构建的工作流由几个功能区域组成:
- 用户构建配置(User Configuration):可用于控制生成过程的元数据 (bblayer.conf/local.conf)。
- 构建元数据层(Metadata Layers):提供软件、板子和发行版元数据的各种层,通过元数据层可以有效实现复用和抽象。
- 软件包源代码(Source Files):构建使用的软件包源码,可以来自上游发布的软件包、本地代码目录或者软件代码仓(例如git,svn,http,ftp)。
- 构建系统(Build System):在 Bitbake 控制下的进程。这个模块扩展了 Bitbake 如何获取源代码、应用补丁、完成编译、分析生成包的输出、创建和测试包、生成镜像 以及生成交叉开发工具。
- 软件包源(Package Feeds):包含输出包(RPM、DEB或IPK)的目录,这些输出包随后用于构建由构建系统生成的镜像或软件开发工具包(SDK)。如果启用了运行时包管理,还可以使用 web 服务器或其他方式复制和共享这些软件包,以便于在运行时扩展或更新设备上的现有镜像。
- 镜像(Images):生成的镜像,包括内核镜像、根文件系统镜像等。
- 应用开发工具(Application Development SDK):生成的包含交叉编译工具链、头文件和库文件的开发组件。
编译前准备
硬件配置:
虽然 Yocto 构建系统对硬件配置的要求并不是特别高,但为了确保构建过程的顺利进行,建议采用性能较好的计算机。这主要是因为构建过程涉及大量的编译工作,需要足够的 CPU 和内存资源。
- 处理器:主频较高的多核处理器,建议 6核12线程以上,以加快编译速度。
- 内存:建议 32GB 或更高,以应对复杂的构建任务。
- 存储空间:硬盘空间建议 100G 以上,用于存储源代码、构建文件和生成的镜像。
系统环境
Yocto 构建系统通常运行在 Linux 操作系统上。因此,需要准备一个 Linux 发行版作为构建环境。
- 操作系统:Linux 发行版,如 Ubuntu,也可以使用 WSL。
- 文件系统:确保文件系统有足够的空间,并配置为支持大文件(如果构建大型项目)。
- 网络连接:稳定的网络连接,以便下载所需的软件包和依赖项,有时可能需要 VPN。
软件依赖
在使用 Yocto 构建系统之前,需要安装一些必要的依赖项目。这些依赖项目包括 Git、Python 等,它们将用于获取 Yocto 项目的源代码、执行构建脚本等。
sudo apt install gawk wget git diffstat unzip texinfo gcc build-essential chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping python3-git python3-jinja2 python3-subunit zstd liblz4-tool file locales libacl1
sudo locale-gen en_US.UTF-8
代码下载与同步
仓库管理工具
相关仓库主要有:
- meta-openembedded(OE-core 相关层)
- meta-st-openstlinux(OpenSTLinux 的框架元数据层)
- meta-st-stm32mp(stm32mp BSP 元数据层)
- meta-st-stm32mpu-app-lorawan(lorawan chirpstack 协议栈)
- poky 源码
这里使用了 west 管理工具对多个相关仓库进行管理,类似的工具还有 repo,git submodule 等。
pip3 install west
# 检查是否安装成功
west --version
# 如果出现以下提示,说明pip的安装目录没有添加到系统环境变量中
Command 'west' not found, did you mean:
command 'jest' from deb jest (27.5.1~ds+~cs69.51.22-2)
command 'test' from deb coreutils (8.32-4.1ubuntu1.2)
Try: sudo apt install <deb name>
# 将下面这条命令添加到 ~/.bashrc中
PATH=${PATH}:"~/.local/bin"
# 重新执行
source ~/.bashrc
代码同步
mkdir yocto_ws && cd yocto_ws
west init -m git@gitee.com:ideal-embedded/meta_lora_gateway.git && west update
代码结构如下:
构建配置
-
设置构建环境。
# 构建操作系统不推荐在源码目录中进行构建,我们将在 yocto_ws 的上一级目录进行开发 cd .. # 设置完环境变量,他会自动跳转到构建目录中,此时应处于与 yocto_ws 同级目录下的 build 目录中。 source yocto_ws/poky/oe-init-build-env
-
设置构建参数。
# 设置 MACHINE sed -i 's/^MACHINE ??=.*/MACHINE ??= \"stm32mp15-loar-gateway\"/' conf/local.conf # 设置发行版 sed -i 's/^DISTRO ?=.*/DISTRO=\"openstlinux-weston\"/' conf/local.conf # 设置 DL_DIR 可以加速下载(非必要),默认是 downloads 目录 sed -i 's/^#DL_DIR ?=.*/DL_DIR ?= \"\/home\/ubuntu\/work\/Yocto\/downloads\"/' conf/local.conf # 也可以手动修改 conf/local.conf 中的 MACHINE,DISTRO,DL_DIR 等变量
-
在 build/conf/bblayers.conf 中添加 layer,指定参与构建的层,比如:
BBLAYERS ?= " \ /home/chenqinhu/lorawan/yocto_ws/poky/meta \ /home/chenqinhu/lorawan/yocto_ws/poky/meta-poky \ /home/chenqinhu/lorawan/yocto_ws/poky/meta-yocto-bsp \ /home/chenqinhu/lorawan/yocto_ws/meta-openembedded/meta-oe \ /home/chenqinhu/lorawan/yocto_ws/meta-openembedded/meta-python \ /home/chenqinhu/lorawan/yocto_ws/meta-openembedded/meta-networking \ /home/chenqinhu/lorawan/yocto_ws/meta-openembedded/meta-gnome \ /home/chenqinhu/lorawan/yocto_ws/meta-openembedded/meta-multimedia \ /home/chenqinhu/lorawan/yocto_ws/meta-openembedded/meta-webserver \ /home/chenqinhu/lorawan/yocto_ws/meta-loar-gateway \ /home/chenqinhu/lorawan/yocto_ws/meta-st-stm32mp \ /home/chenqinhu/lorawan/yocto_ws/meta-st-openstlinux \ /home/chenqinhu/lorawan/yocto_ws/meta-st-stm32mpu-app-lorawan \ "
也可以使用 bitbake-layers add-layer 命令添加 layer,但要注意 layer 的依赖关系。
bitbake-layers add-layer ../yocto_ws/meta-openembedded/meta-oe bitbake-layers add-layer ../yocto_ws/meta-openembedded/meta-python # ....... # 逐一添加
-
开始构建系统,openstlinux 提供了如下两种 image 构建目标,这里我选择了构建 st-image-weston 镜像。
bitbake st-image-weston # 首次构建比较久,需要下载的相关源代码基本都在国外服务器,可能需要挂 VPN
-
构建成功的制品位置位于
build/tmp-glibc/deploy/images/stm32mp15-loar-gateway
。
烧录系统镜像
- 将板子配置成 USB 烧录模式, 使用 ST 的烧录软件 STM32_Programmer_CLI 进行镜像烧录。
- 在 STM32MP 系列的芯片烧录过程中,TSV 文件用于定义闪存布局(Flash Layout),指定了如何将不同的固件组件(如引导加载程序、内核、根文件系统等)烧录到 STM32MP 设备的闪存中。通过STM32CubeProgrammer 等烧录工具,可以将这些组件按照 TSV 文件中的定义烧录到设备的闪存中。
# 也可以使用命令烧录 STM32_Programmer_CLI -c port=usb1 -d flashlayout_st-image-weston/optee/FlashLayout_emmc_stm32mp15-loar-gateway-optee.tsv
如何修改操作系统相关源码
-
当需要对操作系统相关配方源码进行修改时,请在 build 目录下执行:
# 比如要修改kernel源码 devtool modify linux-stm32mp # 比如要修改 kernel 源码 devtool modify u-boot-stm32mp #比如要修改可信固件的源码 devtool modify tf-a-stm32mp
devtool 是要 source poky 的环境变量才能获得,使用 devtool modify 时,build/conf/bblayers.conf 的 layer 中会自动添加 xxx/build/workspace,这意味着在 build/workspace/source 目录下进行的任何代码修改都将在下次编译中起作用。
-
执行完后我们可以在 build/workspace/source 下看到相关配方镜像的源代码,通常每个配方都对应着一个仓库,进入源代码目录后可以进行 git 管理。
-
当修改完成后,需要将该 patch 保存下来。
git add . git commit -m "add your change commit message" git format-patch -1 # 其中1代表的是从HEAD开始,一共要生成几个 patch
-
使用 bbappend 文件来应用补丁(patch)。
在 Yocto 项目中,bbappend 文件通常用于向现有的配方(recipe)添加额外的指令或覆盖配方中的某些设置。这种机制允许开发者在不修改原始配方的情况下,为自己的项目定制构建过程。
将 patch 拷贝到我们自己管理的配方目录,比如 meta-loar-gateway。
- 比如修改的是 linux-stm32mp,那么就应该拷贝到 meta-loar-gateway/recipes-kernel/linux/linux-stm32mp 目录下。
- 比如要修改的是 u-boot-stm32mp,那么就应该拷贝到 meta-loar-gateway/recipes-bsp/u-boot/u-boot-stm32mp 目录下。
- 比如要修改的是 tf-a-stm32mp,那么就应该拷贝到 meta-loar-gateway/recipes-bsp/trusted-firmware-a/tf-a-stm32mp 目录下。
要注意,yocto为伞型结构的代码管理,每层的路径都应该是一致的。
-
将你的 patch 名称添加到 SRC_URI 中。
SRC_URI += " \ file://0001-add-your-change-commit-message.patch \ "
file 命令会在当前目录下的同配方名目录中进行搜索,所以 patch 不是随便拷贝的。