一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

meta-balena:实践指南

时间:2026-09-12 15:46:01 编辑:袖梨 来源:一聚教程网

面对实际交付,我看meta-balena的重点不在星标,而在这项能力:用于构建 balenaOS 图像的 Yocto 层集合。团队若要把它用于图像与视觉生产,应先处理风格、尺寸和资源格式容易偏离预期,否则试用结果很容易失真。我建议拿一份明确的视觉参考完成小样,重点记录构图、尺寸、资源可用性和导出质量,再与现有方案比较。它更像给需要可复现视觉结果的设计与内容团队准备的可审查方案,是否长期使用应由试跑数据决定。

Yocto 的 Balena.io 层

描述

该存储库可以为各种设备构建 balenaOS。

层结构

  • meta-balena-common :包含我们所有支持平台的通用配方的层。
  • meta-balena-* :包含 yocto 版本特定配方的层。
  • 其他文件:README、COPYING等

依赖关系

  • https://docs.yoctoproject.org/brief-yoctoprojectqs/#build-host-packages
  • docker
  • 杰克

版本控制

meta-balena 版本保存在 DISTRO_VERSION 变量中。 balena-<board> 版本保存在位于 balena-<board> 存储库根目录中名为 VERSION 的文件中,并在构建中作为变量 HOSTOS_VERSION 读取。

  • meta-balena 的版本采用 semver 格式,由点分隔的 3 个数字组成。补丁号可以有 beta 标签。 e.g。 1.2.3、1.2.3-beta1、2.0.0-beta1。
  • 基于特定 meta-balena 版本 X.Y.Z 的第一个 balena-<board> 版本将是 X.Y.Z,与 meta-balena 版本相同。示例:基于 meta-balena 1.2.3 的第一个 balena-<board> 版本将为 1.2.3。
  • 后续的 balena-<board> 版本是通过向 meta-balena 版本附加 rev 标签来构建的。例如,meta-balena 1.2.3 可以经历 3 个主板修订版,即 1.2.3 为初始修订版,1.2.3+revN 为后续修订版,最终版本为 1.2.3+rev2 。
  • 当在balena-<board>中更新meta-balena版本时,版本将重置为meta-balena版本。例如: 1.2.3+rev4 将更新为 1.2.4 。

我们将主机 OS 版本定义为 balena-<board> 版本,并将该版本用作 HOSTOS_VERSION。

建立标志

在使用 meta-balena 支持进行 bitbake 之前,可以在构建目录中的 conf/local.conf 中更改一些标志。 local.conf 的编辑应在源码完成后进行。 有关此类构建标志的说明,请参阅下文。

配置自定义网络管理器

默认情况下,balena 使用主机 OS 上的 NetworkManager 来提供连接。如果您想更改并使用其他提供商,请使用 NETWORK_MANAGER_PACKAGES 列出您的软件包。您可以将此变量添加到 local.conf。这是一个例子:

NETWORK_MANAGER_PACKAGES =“mynetworkmanager mynetworkmanager-client”

自定义启动画面

我们将所有初始映像配置为在启动、关闭或重新启动时生成 balena 徽标。但我们鼓励任何用户用自己的徽标替换该徽标。 您所要做的就是用您自己的映像替换您在映像的第一个分区(启动分区)中找到的 splash/balena-logo.png 文件。 NOTE:按照目前的情况,普利茅斯希望该映像被命名为 balena-logo.png。在旧版本中,此文件称为 resin-logo.png

Docker存储驱动

默认情况下,构建系统将设置 docker 能够使用 aufs 存储驱动程序所需的所有位。这可以通过在 local.conf 中定义 BALENA_STORAGE 来更改。它支持aufsoverlay2

OS开发

要配置禁用安静启动并允许引导加载程序 shell 访问的开发版本,请编辑该版本的 local.conf 添加:

OS_DEVELOPMENT = "1"

这是仅用于开发的设置,不会部署 OS_DEVELOPMENT 配置的映像。

OS

SSH 和 Avahi 服务

OS 在端口 22222 上运行 SSH (openSSH)。运行此服务利用套接字激活 systemd 功能,因此 SSH 守护进程仅在存在到设备的 SSH 连接时运行,以这种方式节省空闲资源。为了连接到设备,可以使用已知的 IP 或通过 mDNS 解析主机名,因为其主机名是使用 avahi 服务通过网络公布的。当使用后者时,需要配置客户端(参见例如https://wiki.archlinux.org/index.php/Avahi#Hostname_resolution)。

时间同步

启动时,时间设置和同步如下:

  • 构建时间
  • 上次启动系统时间
  • RTC 可用时间
  • HTTPs时间
  • 网络时间

构建时间

最初时间是根据映像构建时间时间戳设置的,存储在 /etc/timestamp 中,并在生成映像时由构建系统生成。

上次启动系统时间

然后,系统检查先前的引导系统时间是否存储在持久存储器中,并使用它来纠正时间。时间按每小时计时器以及系统重新启动或关闭时存储在持久存储器中。设置上次启动系统时间后开始记录。

RTC时间

当 RTC 可用 (/dev/rtc) 时,将启动 timeinit-rtc 服务,该服务使用从 RTC 读取的值更新系统时钟。如果没有可用的 RTC,该服务将不会执行任何操作。

HTTPs时间

在网络连接事件之后,假设之前尚未从 RTC 设置正确的系统时间,则使用 HTTPs 时间同步服务 timesync-https 来纠正 HTTP 标头时间戳中的时间。这保证了时间大致正确并且证书过期检查不会失败。其他网络服务将被保留,直到此时同步发生。默认情况下,时间同步使用 config.jsonconnectivity 部分中定义的 NetworkManager 连接 URL。要禁用 HTTPs 时间同步并允许其他服务运行,请将连接检查 URI 设置为“null”。这也将禁用 连接检查。

网络时间

chronyd 服务负责使用 NTP 管理之后的时间。它被配置为大约每 4 小时同步一次以节省带宽。如果 NTP 服务器变得无法访问,该服务将不断尝试更新时间。如果时间不同步,NTP 客户端服务将重新启动以纠正故障。

当 RTC 可用和不可用时,上面解释的时间保持框架都提供强大的时间初始化和管理。

引导装载程序

引导加载程序需要选择活动根文件系统、加载并启动 Linux 内核。它还管理启动计数和回滚。 BalenaOS 在受支持的设备系列中支持多个引导加载程序。

  • 巴莱纳引导加载程序

    • 这是新的支持 kexec 的设备的首选引导加载程序
    • 它是一个最小的 Linux 内核,包含 balena 的所有逻辑,,例如回滚支持,位于 initramfs 中,因此不必在不同的引导加载程序之间复制
    • 它从活动根分区获取最终内核并 kexecs 到其中
    • balena 引导加载程序是启用安全引导的平台的必需条件,因为它需要挂载和解密根文件系统以启动最终内核。标准引导加载程序通常不支持解密磁盘。
    • 它还提供了一个中央环境文件 bootenv,用于由系统执行引导加载程序配置
    • 理想情况下,balena booloader 可以构建为 EFI 二进制文件,并由支持 EFI 的 bootROM 直接启动
    • 或者,可以对 U-Boot 等供应商引导加载程序进行最低配置来启动它
    • 使用 balena 引导加载程序可以减少移植新硬件的麻烦,因为对供应商引导加载程序的修改很少,通常只需启动配置,并且所有 balena 逻辑都已经实现和测试,并且在所有设备上都是相同的
  • 支持的其他引导加载程序可用于启动 balena 引导加载程序(如果需要)或在不支持 kexec 的设备上:

  • U盘启动

    • 用于大多数旧版支持的 ARM 设备类型
    • 仅块设备可与 BalenaOS 一起使用,不支持 RAW 闪存设备
    • 通用功能在u-boot环境中实现,该环境由通用OS Yocto层提供
    • 该环境嵌入在 u-boot 二进制文件中。这允许预期的配置与 BalenaOS 的匹配版本一起使用,并避免来自任何预编程环境的干扰
    • 设备特定功能由设备存储库提供,可以在 u-boot 脚本 中,也可以在 板配置文件 定义的环境中
    • 特定的Jetson模块(TX2,Nano)使用额外的extlinux.conf文件,该文件由u-boot加载和解析
    • 三个环境文件由 u-boot 从 BalenaOS 启动分区存储和加载。 resinOS_uEnv.txt 用于存储活动根分区索引, extra_uEnv.txt 存储特定于设备的配置元素,例如可选内核命令行参数以及任何自定义选择的设备树,同时bootcount.env 存储 OS 更新期间尝试引导重试失败的次数。 NOTE:仅在 特定设备 上支持自定义设备树选择
    • 在 Beaglebone 设备上应用 uEnv.txt_internal/uEnv.txt 中指定的内核设备树覆盖
  • 蛴螬

    • 用于旧版支持的 x86 设备类型
    • 通用功能由 grub 配置模板 中的 OS 层实现
  • 启动程序

    • 用于运行 L4T 32.X 的 Jetson Xavier 设备
    • 从设备特定的 A/B 分区加载设备树
    • 与其他引导加载程序不同,它不支持 FAT 文件系统
    • 当前活动的根文件系统标签是在内核设备树提供的内核命令行中定义的。启动时根据活动设备树选择活动 rootfs
  • UEFI L4发射器

    • 用于 Jetson Orin 平台
    • 从 extlinux.conf 文件获取内核映像路径和内核命令行参数
    • 回滚和活动根文件系统选择在 引导加载程序补丁 中实现,该补丁由 balena-jetson-orin 设备存储库 提供
    • 通过存储和读取 resinOS_uEnv.txt、extra_uEnv.txt 和 bootcount.env 文件中的环境变量,采用与 u-boot 中的 balenaOS 相同的回滚机制

回滚框架

检查 docs/rollbacks.md 回滚文档

OS 更新锁

主机 OS 更新脚本(hostapp-update 中的 safe_reboot)在重新启动设备之前检查任何容器中 /tmp/balena/updates.lock 上的独占 flock()。如果进程在此文件上拥有独占的羊群,这些脚本将等到锁被释放后再继续重新启动。

这独立于 Supervisor 管理的应用程序更新锁定机制。 Supervisor 使用锁定文件(文件存在)来防止应用程序更新,而主机 OS 使用 flock() 来防止 OS 更新期间重新启动。

在关键操作期间,应同时使用两种机制以提供全面保护。有关应用程序更新锁定以及如何组合两者的详细信息,请参阅 Supervisor 更新锁定文档。

创建羊群

壳牌

使用 群 (Debian:util-linux 包):

flock /tmp/balena/updates.lock -c '... (command to run while locked)'

要在长时间运行的进程中保持锁定:

exec {FD}>/tmp/balena/updates.lock
flock -x $FD || exit 1
# ... critical section; safe_reboot will wait ...
exec {FD}>&-

蟒蛇

使用fcntl.flock(标准库):

import fcntl
import os
import time

LOCK_PATH = '/tmp/balena/updates.lock'

def with_update_lock(fn):
    fd = os.open(LOCK_PATH, os.O_CREAT | os.O_EXCL | os.O_RDWR)
    try:
        fcntl.flock(fd, fcntl.LOCK_EX)
        fn()
    finally:
        fcntl.flock(fd, fcntl.LOCK_UN)
        os.close(fd)
        try:
            os.unlink(LOCK_PATH)
        except OSError:
            pass

with_update_lock(critical_function)

设备支持

WiFi 适配器

我们目前测试并提供对以下 WiFi 适配器的明确支持:

  • 基于 bcm43143 的适配器

调制解调器

我们目前作为发布过程的一部分进行测试,并为以下调制解调器提供明确支持:

  • USB 调制解调器(在 Raspberry Pi 3、Balena Fin、Intel NUC 和 Nvidia TX2 上测试)
    • 华为 MS2131i-8
    • 华为 MS2372
  • mPCI 调制解调器(在 Balena Fin 和 Nvidia TX2 Spacely 运营商上测试)
    • 华为 ME909s-120
    • 移远EC20
    • SIM7600E

推荐 WiFi USB 加密狗

  • Panda N600 双频 (2.4 GHz + 5 GHz) 无线-N USB 适配器 该USB加密狗基于Ralink RT5572芯片组,并受通用rt2800usb驱动程序支持。 测试已在 Panda N600 双频 USB 适配器的 PAU09 型号上进行,并具有 固件文件 rt2870.bin 中的固件版本 0.36

如何修复各种构建错误

  • Supervisor 失败并显示类似以下内容的日志:
Step 3 : RUN chmod 700 /entry.sh
---> Running in 445fe69866f9
operation not supported

这可能是因为 docker 错误,如果您更新内核并且不重新启动,docker 会感到困惑。修复方法是重新启动系统。 更多信息:http://stackoverflow.com/questions/29546388/getting-an-operation-not-supported-error-when-trying-to-run-something-while-bu

config.json

可以通过在引导分区中的 config.json 文件中设置以下键来配置 balenaOS 的行为。这个配置文件也被supervisor使用。

主机名

(字符串)设备的配置主机名,否则使用设备 UUID。

persistentLogging

(布尔值)启用或禁用设备上的持久日志记录 - 默认为 false。启用持久日志后,它们最终会作为设备上数据分区的一部分存储(在 SD 卡、eMMC、硬盘等上)。它位于设备上的 /var/log/journal/<uuid>,其中 UUID 是可变的。

国家

(字符串)设备运行所在国家/地区的两个字母国家/地区代码。这用于设置 WiFi 监管域,您应该检查 WiFi 设备驱动程序以获取支持的国家/地区代码列表。

ntpServers

(字符串)用于时间同步的 NTP 服务器的空格分隔列表。默认为 resinio.pool.ntp.org 服务器:

  • 0.resinio.pool.ntp.org
  • 1.resinio.pool.ntp.org
  • 2.resinio.pool.ntp.org
  • 3.resinio.pool.ntp.org

dnsServers

(字符串)用于名称解析的首选 DNS 服务器的空格分隔列表。

  • dnsServers 未定义或为空时,Google 的 DNS 服务器 (8.8.8.8) 将添加到通过 DHCP 获取或在 NetworkManager 连接配置文件中静态配置的 DNS 服务器列表中。
  • dnsServers为“null”(字符串)时,Google的DNS服务器(8.8.8.8)将如上所述添加NOT。
  • 当定义 dnsServers 且不为“空”时,列出的服务器将添加到通过 DHCP 获取的服务器列表或通过 NetworkManager 连接配置文件静态配置的服务器列表中。

balenaRootCA

(字符串)将安装到根信任存储中的 Base64 编码的 PEM CA 证书。这使得设备信任来自该机构的 TLS/SSL 证书。 当设备在重新加密的网络设备(例如透明代理或某些深度数据包检查设备)后面运行时,这非常有用。

"balenaRootCA": "4oCU4oCTQkVHSU4gQ0VSVElGSUNBVEXigJTi..."

developmentMode

要在运行时启用开发模式:

"developmentMode": true

默认情况下,开发模式允许未经身份验证的 SSH 登录,除非存在自定义 SSH 密钥,在这种情况下,将强制执行 SSH 密钥访问。

此外,开发模式提供串行控制台无密码登录以及暴露的 balena 引擎套接字以在本地模式开发中使用。

操作系统

包含在运行时自定义主机 OS 的设置的对象。

网络

无线网络

定义与 Wi-Fi 相关的配置的对象。

  • “randomMacAddressScan”(布尔值)配置扫描期间 Wi-Fi 设备的 MAC 地址随机化

以下示例在扫描期间禁用 Wi-Fi 设备的 MAC 地址随机化:

"os": {
 "network" : {
  "wifi": {
    "randomMacAddressScan": false
  }
 }
}

连接性

定义与网络连接检查相关的配置的对象。此功能基于 NetworkManager 的连接检查,该检查在连接部分 (此处为)中进行了进一步记录。

  • “uri”(字符串)用于查询连接检查的 url 值。默认为 $API_ENDPOINT/connectivity-check
  • “interval”(字符串)连接检查之间的时间间隔(以秒为单位)。默认为 3600。要禁用连接检查,请将间隔设置为“0”。
  • “响应”(字符串)。如果设置控制请求 URI 时检查哪些正文内容。如果为空值,则 HTTP 服务器预计会以状态码 204 进行应答或不发送任何数据。

以下示例通过以 5 分钟间隔传递 balenaCloud 连接端点来配置连接检查。

"os": {
 "network" : {
  "connectivity": {
    "uri" : "https://api.balena-cloud.com/connectivity-check",
    "interval" : "300"
  }
 }
}

udevRules

包含一个或多个自定义 udev 规则(作为 key:value 对)的对象。

要将规则转换为可以轻松添加到 config.json 的格式,请使用以下命令:

cat rulefilename | jq -sR .

例如:

root@resin:/etc/udev/rules.d# cat 64.rules | jq -sR .
"ACTION!="add|change", GOTO="modeswitch_rules_end"nKERNEL=="ttyACM*", ATTRS{idVendor}=="1546", ATTRS{idProduct}=="1146", TAG+="systemd", ENV{SYSTEMD_WANTS}="u-blox-switch@'%E{DEVNAME}'.service"nLBEL="modeswitch_rules_end"n"

以下示例包含两个自定义 udev 规则,将创建 /etc/udev/rules.d/56.rules/etc/udev/rules.d/64.rules。第一次添加规则或修改规则时,udevd 会重新加载规则并重新触发。

"os": {
 "udevRules": {
  "56": "ENV{ID_FS_LABEL_ENC}=="resin-root*", IMPORT{program}="resin_update_state_probe $devnode", SYMLINK+="disk/by-state/$env{BALENA_UPDATE_STATE}"",
  "64" : "ACTION!="add|change", GOTO="modeswitch_rules_end"nKERNEL=="ttyACM*", ATTRS{idVendor}=="1546", ATTRS{idProduct}=="1146", TAG+="systemd", ENV{SYSTEMD_WANTS}="u-blox-switch@'%E{DEVNAME}'.service"nLBEL="modeswitch_rules_end"n"
 }
}

sshKeys

(数组)包含公共 SSH 密钥列表的字符串数组,SSH 服务器将使用这些密钥进行身份验证。

"os": {
 "sshKeys": [
  "ssh-rsa AAAAB3Nza...M2JB balena@macbook-pro",
  "ssh-rsa AAAAB3Nza...nFTQ balena@zenbook"
 ]
}

风扇

定义热相关配置的对象。适用于运行 Jetpack 6 或更高版本、balenaOS v6.1.24 或更高版本以及 Supervisor v16.10.0 或更高版本的 Jetson Orin 设备。

fan.profile

(字符串)用于选择所需冷却配置文件的字符串。支持的值为“quiet”和“cool”。在运行时,这 配置选项应通过 API 或从 balenaCloud 仪表板设置。

"os": {
 "fan": {
  "profile":"cool"
 }
}

电源

定义功耗相关配置的对象。适用于运行 Jetpack 6 或更高版本、balenaOS v6.1.24 或更高版本以及 Supervisor v16.10.0 或更高版本的 Jetson Orin 设备。

power.mode

(字符串)用于选择所需电源模式的字符串。 Jetpack 6 及更高版本支持的值为“low”、“mid”和“high”,其中“low” 是最低功耗模式,而“高”对应于 MAXN 或您的设备类型的最高可用功耗模式。在运行时,这 配置选项应通过 API 或从 balenaCloud 仪表板设置,这将导致设备重新启动。

"os": {
 "power": {
  "mode":"high"
 }
}

内核

允许配置内核设置的对象,这些设置在引导或运行时应用。

kernel.extraFirmwareVol

(字符串)用于指定用于存储附加固件的卷的名称的字符串。该卷用作 Linux 固件的附加搜索路径。 在运行时,此设置由 Supervisor 管理,默认卷名称为“extra-firmware”。

"os": {
 "kernel": {
  "extraFirmwareVol":"extra-firmware"
 }
}

安装人员

配置 balenaOS 安装程序映像的行为的对象。

安全启动

(布尔值)选择安装安全启动和加密磁盘系统 支持的设备类型。

"installer": {
  "secureboot": true
}

迁移

配置 balenaOS 安装程序迁移行为的对象 模块。

migrate.force

(布尔值)强制迁移运行。默认情况下,迁移仅在以下情况下运行: 安装程序在单磁盘系统或 migrate 参数中启动 在内核命令行中传递。

"installer": {
  "migrate": {
    "force": true
  }
}

目标设备

(字符串)覆盖配置目标介质的默认列表。可能包含一个或多个 设备,用空格分隔。将使用第一个找到的。

"installer": {
  "target_devices":"nvme0n1 sda"
}

Yocto 版本支持

支持以下 Yocto 版本:

  • 柯克斯通 (4.0):长期支持
  • 霍尼斯特 (3.4):EOL
  • 邓菲尔 (3.1):长期支持
  • 战士(2.7):EOL
  • 重击(2.6):EOL
  • 相扑(2.5):EOL
  • 洛可 (2.4): EOL
  • 火焰兵 (2.3):EOL

热门栏目