ทําไมต้อง SWUpdate?
การอัปเดตภาคสนามเป็นสิ่งที่หลีกเลี่ยงไม่ได้ SWUpdate มอบโซลูชันโมดูลาร์ที่มีประสิทธิภาพสําหรับการอัปเดตเฟิร์มแวร์ ระบบไฟล์รูท และเลเยอร์แอปพลิเคชัน ทั้งหมดนี้มีความสามารถในการย้อนกลับในตัว
เป็นโอเพ่นซอร์ส มีเอกสารประกอบอย่างดี และผสานรวมกับเค้าโครงพาร์ติชัน A/B ได้อย่างราบรื่น
ภาพรวมสถาปัตยกรรม
SWUpdate ประกอบด้วยองค์ประกอบหลักหลายประการ:
- Update daemon (swupdate) — ทํางานบนอุปกรณ์และใช้การอัปเดต
- ตัวจัดการการอัปเดต — กําหนดสิ่งที่ต้องอัปเดต (rootfs, ไฟล์, สคริปต์ ฯลฯ )
- อินเทอร์เฟซไคลเอ็นต์ — เว็บอินเตอร์เฟส, REST API หรือ CLI ในเครื่อง
- ไฟล์ sw-description — กําหนดโครงสร้างและตรรกะของแพ็คเกจการอัปเดต
ตัวอย่างโฟลว์การอัปเดต
- สร้างแพ็คเกจการอัปเดต (.swu) ที่ประกอบด้วย:
•ภาพระบบไฟล์รากใหม่
• ไฟล์ sw-description
•สคริปต์เสริม (สําหรับการปรับแต่งหรือการตรวจสอบ)
2.swupdate เขียนการอัปเดตไปยังอุปกรณ์ที่กําหนด - สคริปต์หลังการอัปเดตจะยืนยันความสําเร็จหรือทริกเกอร์การย้อนกลับหากจําเป็น
ตัวอย่าง
ในตัวอย่างนี้ เราแบ่งรูปภาพ Raspberry Pi OS Trixie อย่างเป็นทางการออกเป็นสองไฟล์:
- 2025-10-01-ราสปิออส-ทริกซี่-arm64.boot.vfat
- 2025-10-01-ราสปิออส-ทริกซี่-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 ต่อไปนี้ปรับ UUID พาร์ติชันใน cmdline.txt และ fstab หลังจากกระพริบ:
#!/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 ที่สร้างขึ้น:
- บูต CM5 เข้าสู่ระบบกู้ภัย
- สร้างจุดเชื่อมต่อ เช่น
sudo mkdir -p /mnt/update- เมานต์การแชร์ NFS ที่มีไฟล์อัปเดต:
sudo mount -t nfs :/path/to/share /mnt/update- ใช้การอัปเดต:
sudo swupdate -i /mnt/update/update.swuความเป็นไปได้ในการผสานรวม
ทริกเกอร์การอัปเดตจาก UI ในเครื่องหรือ API แบ็กเอนด์
- ลงนามและตรวจสอบการอัปเดตเพื่อเพิ่มความปลอดภัย
- ใช้เว็บอินเตอร์เฟส SWUpdate’s สําหรับการทดสอบหรือแก้ไขข้อบกพร่อง
- รวมกับบริการ systemd เพื่อกู้คืนและการย้อนกลับโดยอัตโนมัติ
ทําไมถึงเหมาะกับสแต็กนี้
ร่วมกับ rpi-image-gen และ rpi-sb-provisionerSWUpdate ทําให้ภาพสมบูรณ์:
- สร้าง→ rpi-image-gen (การสร้างภาพ)
- ปรับใช้ → rpi-sb-provisioner (การจัดเตรียมอุปกรณ์)
- รักษา→ SWUpdate (การอัปเดต OTA และการจัดการวงจรชีวิต)
ผลลัพธ์ที่ได้คือแพลตฟอร์ม Linux แบบฝังตัวที่ยืดหยุ่น เปิดกว้าง และบํารุงรักษาได้ ซึ่งเป็นแพลตฟอร์มที่พัฒนาไปพร้อมกับผลิตภัณฑ์ของคุณโดยไม่ต้องเสียค่าใช้จ่ายYocto
บทความในชุดนี้
- การสร้างLinuxที่พร้อมใช้งานจริงสําหรับ Raspberry Pi Compute Module 5
- จากสต็อกระบบปฏิบัติการสู่แพลตฟอร์มการผลิต
- การปรับแต่งRaspberry Pi OSด้วย rpi-image-gen
- ความแข็งแกร่งของระบบ — การออกแบบเค้าโครงระบบไฟล์ราก A/B
- Provisioning — การบูตครั้งแรกโดยอัตโนมัติด้วย rpi-sb-provisioner
- OTA และวงจรชีวิต — การอัปเดตซอฟต์แวร์ด้วย SWUpdate
แหล่งที่มา
- 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
- <a href="https://github.com/sbabic/swugenerator: swugenerator" เป้าหมาย="_blank">https://github.com/sbabic/swugenerator