当前位置:首页 > 嵌入式 > 嵌入式分享
[导读]在嵌入式Linux开发中,同时支持多款ARMv8-A硬件平台是一个常见但不易做好的需求。每款开发板都有自己独特的Bootloader、内核配置、设备树和用户态驱动,若为每款板卡独立维护一套构建配置,维护成本会随硬件种类线性增长。Yocto Project的meta层架构为解决这一问题提供了系统化的手段——通过合理的层结构设计和复用策略,一套BSP层即可支撑多个板卡的构建。

在嵌入式Linux开发中,同时支持多款ARMv8-A硬件平台是一个常见但不易做好的需求。每款开发板都有自己独特的Bootloader、内核配置、设备树和用户态驱动,若为每款板卡独立维护一套构建配置,维护成本会随硬件种类线性增长。Yocto Project的meta层架构为解决这一问题提供了系统化的手段——通过合理的层结构设计和复用策略,一套BSP层即可支撑多个板卡的构建。

硬件多样性与meta层复用的核心思路

ARMv8-A平台的多板卡支持主要涉及三类差异:一是Bootloader配置差异,不同板卡可能使用U-Boot或EDK2,配置参数各异;二是内核设备树差异,每款板卡有独立的dts文件和内核补丁;三是用户态差异,特定板卡需要加载专有固件或使用不同版本的驱动库。

Yocto解决这一问题的核心工具是**MACHINE变量**和**机器继承机制**。在Yocto中,每个板卡对应一个MACHINE配置文件,该文件包含了该板卡的所有定制信息——从内核映像类型、串口配置,到启动存储介质和引导方式。在此基础上,通过合理的meta层结构,将共性部分抽取到上层,差异性部分按板卡分别定义。

meta-xxx/

├── conf/

│ └── machine/

│ ├── include/

│ │ └── armv8a-common.inc # 所有ARMv8板卡的通用配置

│ ├── board-a.conf # 板卡A,require通用配置

│ ├── board-b.conf # 板卡B,require通用配置

│ └── board-c.conf # 板卡C,require通用配置

├── recipes-kernel/

│ └── linux/

│ ├── linux-yocto_%.bbappend

│ └── board-a/

│ ├── defconfig

│ └── board-a.dts

├── recipes-bsp/

│ └── u-boot/

│ ├── u-boot_%.bbappend

│ └── board-a/

│ └── board-a_defconfig

└── recipes-core/

└── images/

└── my-image.bb

在上述结构中,`armv8a-common.inc`包含所有板卡共用的配置——如`DEFAULTTUNE = "armv8a-crc"`、通用的`MACHINE_FEATURES`定义,以及`PREFERRED_PROVIDER_virtual/kernel`的默认选择。各板卡配置文件通过`require`指令继承通用配置,然后添加自身独有的设备树、MACHINE_FEATURES和固件依赖。

**`MACHINEOVERRIDES`变量**是实现板卡级定制的关键。通过`MACHINEOVERRIDES .= ":board-a"`,可为特定板卡定义专属的变量值。例如在BBAPPEND文件中,可对不同板卡分别应用不同的内核补丁或设备树编译参数。

LmP的多BSP layer协同实践

实际工程中,上述基础模式往往需要应对更复杂的场景——同时集成多个硬件厂商的BSP层。Foundries.io的LmP发行版提供了一个典型案例。

LmP将代码组织为多个子层:`meta-lmp-base`存放发行版共用的distro配置和核心类,`meta-lmp-bsp`则集中管理所有BSP相关的改动。其策略核心包括:

- **统一BBAPPEND规范**:不同BSP厂商的U-Boot和内核recipe可能使用不同的名称(如`u-boot-_*.bb`而非标准的`u-boot_*.bb`)。LmP要求所有meta层使用统一的recipe命名规范,避免BBAPPEND无法匹配。

- **BSP适配性检查**:在引入新BSP层时,需验证其是否满足复用要求——是否定义了`COMPATIBLE_MACHINE`、是否使用弱赋值而非强赋值定义`KERNEL_DEVICETREE`等变量,避免跨层覆盖冲突。

- **内核与固件管理**:以`genericarm64`机器为例,其配置明确“安装所有内核模块”和“选择性安装固件”(如wl12xx、wl18xx、rtl-nic等),使通用镜像体积从近1GB压缩至可管理水平。

ARMv8-A多板卡支持的程序实现

构建一个多板卡支持的Yocto工程,流程如下:

1. 定义通用ARMv8架构配置

在`conf/machine/include/armv8a-common.inc`中:

# 通用ARMv8架构配置

DEFAULTTUNE ?= "armv8a-crc"

require conf/machine/include/arm/arch-armv8a.inc

MACHINE_FEATURES = "rtc screen usbhost wifi"

KERNEL_IMAGETYPE = "Image"

PREFERRED_PROVIDER_virtual/kernel ?= "linux-yocto"

2. 定义具体板卡配置

以`conf/machine/board-a.conf`为例:

#@TYPE: Machine

#@NAME: Board A

#@DESCRIPTION: Configuration for Board A (ARMv8-A)

require conf/machine/include/armv8a-common.inc

MACHINE_FEATURES:append = " bluetooth"

KERNEL_DEVICETREE = "board-a.dtb"

UBOOT_MACHINE = "board_a_defconfig"

SERIAL_CONSOLES = "115200;ttyS0"

3. 分层管理内核和U-Boot

在`recipes-kernel/linux/linux-yocto_%.bbappend`中,通过`COMPATIBLE_MACHINE`指定支持的板卡,并按板卡分别定义内核补丁和配置:

COMPATIBLE_MACHINE = "board-a|board-b"

FILESEXTRAPATHS:prepend := "${THISDIR}/${MACHINE}:"

SRC_URI:append:board-a = " file://board-a-patch.patch"

SRC_URI:append:board-b = " file://board-b-patch.patch"

4. 构建与发布

设置`MACHINE = "board-a"`后执行`bitbake core-image-minimal`,即可生成对应板卡的镜像。通过复用共享层,多板卡构建的代码冗余最小化。

5. 运行验证

对于使用Armv8-A Base Platform FVP进行模拟验证的场景,在meta-arm-bsp中设置`MACHINE = "fvp-base"`后执行`bitbake core-image-minimal`即可生成模拟镜像。

在多板卡嵌入式Linux系统构建中,meta层的复用策略是将“碎片化硬件”映射到“结构化管理”的关键手段。通过MACHINE继承、MACHINEOVERRIDES板级定制和多BSP层的统一化管理,即可在Yocto框架内将多板卡的支持成本从线性增长降低为常数级。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭