なぜ? SWUpdate?
フィールド・アップデートは避けられません。 SWUpdateは、ファームウェア、ルート・ファイルシステム、アプリケーション・レイヤーを更新するための、堅牢でモジュール化されたソリューションを提供します。
オープンソースで、ドキュメントも充実しており、A/Bパーティション・レイアウトとシームレスに統合できます。
建築概要
SWUpdateはいくつかの主要なコンポーネントで構成されています:
- アップデート・デーモン (swupdate) - デバイス上で実行され、アップデートを適用します。
- 更新ハンドラ - 更新対象(ルートファイル、ファイル、スクリプトなど)を定義します。
- クライアント・インターフェイス - ウェブ・インターフェイス、REST API、またはローカルCLI
- sw-descriptionファイル - アップデート・パッケージの構造とロジックを定義します。
更新フロー例
1.以下を含むアップデートパッケージ (.swu) をビルドします:
- 新しいルートファイルシステムイメージ
- 新しいルートファイルシステムイメージ sw-descriptionファイル
- オプションのスクリプト(カスタマイズまたは検証用)
2.swupdate定義されたデバイスに更新を書き込みます。
3.ポストアップデートスクリプトが成功を確認し、必要に応じてロールバックをトリガーします。
例
この例では Raspberry Pi OSTrixie イメージを 2 つのファイルに分割します:
- 2025-10-01-raspios-trixie-arm64.boot.vfat
- 2025-10-01-raspios-trixie-arm64.root.ext4
これらのファイルは sw-descriptionファイルで参照され、.swu パッケージが作成されます:
software =
{
version = "0.1.0";
description = "Firmware update for XXXXX Project";
hardware-compatibility: [ "1.0", "1.2", "1.3"];
images: (
{
filename = "2025-10-01-raspios-trixie-arm64.boot.vfat";
device = "/dev/mmcblk0p1";
compressed = "zlib";
installed-directly = true;
},
{
filename = "2025-10-01-raspios-trixie-arm64.root.ext4";
device = "/dev/mmcblk0p2";
compressed = "zlib";
installed-directly = true;
}
);
scripts: (
{
type: "lua",
filename: "repair-disk-uuid.lua"
}
),
}以下のLuaスクリプトは、.swuパッケージを作成するファイルで参照されます。 cmdline.txtと fstabでパーティションUUIDを調整します:
#!/usr/bin/lua
-- helper: run shell command and capture output
function run(cmd)
local f = io.popen(cmd)
local out = f:read("*a")
f:close()
return (out:gsub("%s+$", ""))
end
-- detect PARTUUIDs
local root_part = "/dev/mmcblk0p2"
local boot_part = "/dev/mmcblk0p1"
local root_uuid = run("blkid -s PARTUUID -o value " .. root_part)
local boot_uuid = run("blkid -s PARTUUID -o value " .. boot_part)
print("Rootfs PARTUUID: " .. root_uuid)
print("Boot PARTUUID: " .. boot_uuid)
-- mount points
os.execute("mkdir -p /mnt/root /mnt/boot")
os.execute("mount " .. root_part .. " /mnt/root")
os.execute("mount " .. boot_part .. " /mnt/boot")
-- update cmdline.txt
local cmdline_path = "/mnt/boot/cmdline.txt"
local file = io.open(cmdline_path, "r")
local text = file:read("*a")
file:close()
text = text:gsub("root=PARTUUID=[^ ]+", "root=PARTUUID=" .. root_uuid)
file = io.open(cmdline_path, "w")
file:write(text)
file:close()
-- update /etc/fstab
local fstab_path = "/mnt/root/etc/fstab"
local fstab = io.open(fstab_path, "r")
local content = fstab:read("*a")
fstab:close()
-- replace root line
content = content:gsub("PARTUUID=[^%s]+%s+/%s", "PARTUUID=" .. root_uuid .. " /")
-- replace boot line (/boot or /boot/firmware)
content = content:gsub("PARTUUID=[^%s]+%s+/boot", "PARTUUID=" .. boot_uuid .. " /boot")
fstab = io.open(fstab_path, "w")
fstab:write(content)
fstab:close()
os.execute("sync")
os.execute("umount /mnt/boot")
os.execute("umount /mnt/root")
print("All PARTUUIDs updated successfully.")アップデートをバンドルするには swugeneratorを使用してアップデートをバンドルします:(https://github.com/sbabic/swugenerator).
アップデートの適用
生成された .swu ファイルをテストするには
1.CM5をレスキューシステムで起動します。
2.マウントポイントを作成します:
sudo mkdir -p /mnt/update- 更新ファイルを含む NFS 共有をマウントします:
sudo mount -t nfs :/path/to/share /mnt/update4.アップデートを適用します:
sudo swupdate -i /mnt/update/update.swu統合の可能性
ローカルUIまたはバックエンドAPIからアップデートをトリガー
- セキュリティ強化のためのアップデートの署名と検証
- 使用方法 SWUpdate’sテストやデバッグのためのウェブインタフェース
-systemd サービスと組み合わせてリカバリとロールバックを自動化
このスタックに合う理由
とともに rpi-image-genと rpi-sb-provisioner, SWUpdateで絵が完成します:
- ビルド rpi-image-gen(イメージの作成)
- デプロイ → (デバイスのプロビジョニング rpi-sb-provisioner(デバイスのプロビジョニング)
- メンテナンス → (OTAアップデートとライフサイクル管理 SWUpdate(OTAアップデートとライフサイクル管理)
その結果、柔軟でオープンで保守可能な組み込みプラットフォームが実現します。 Linux製品とともに進化する組み込みプラットフォームです。 Yocto.
情報源
- rpi-image-gen:https://github.com/raspberrypi/rpi-image-gen
- rpi-sb-provisioner:https://github.com/raspberrypi/rpi-sb-provisioner
- SWUpdate:https://github.com/sbabic/swupdate
- swugenerator:https://github.com/sbabic/swugenerator