BR2_PACKAGE_RAUC=y
BR2_PACKAGE_RAUC_DBUS=y
BR2_PACKAGE_RAUC_GPT=y
BR2_PACKAGE_RAUC_NETWORK=y
BR2_PACKAGE_RAUC_STREAMING=y
BR2_PACKAGE_RAUC_JSON=y
BR2_TARGET_UBOOT_PATCH="board/stmicroelectronics/stm32mp_uboot/rauc/patches/uboot/" <- refer to output/build/uboot-custom/include/configs/stm32mp25_st_common.h
BR2_PACKAGE_HOST_RAUC=y
BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_ST_PATH)/board/stmicroelectronics/common/post-image.sh $(BR2_EXTERNAL_ST_PATH)/board/stmicroelectronics/common/generate-rauc-bundle.sh"
BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="$(LINUX_DIR)/arch/arm64/configs/fragment-01-defconfig-cleanup.config $(LINUX_DIR)/arch/arm64/configs/fragment-02-defconfig-addons.config $(BR2_EXTERNAL_ST_PATH)/board/stmicroelectronics/common/linux-disable-etnaviv.config $(BR2_EXTERNAL_ST_PATH)/board/stmicroelectronics/common/linux-enable-rauc.config"
BR2_ROOTFS_USERS_TABLES=""
BR2_ROOTFS_OVERLAY="$(BR2_EXTERNAL_ST_PATH)/board/stmicroelectronics/stm32mp2/overlay-demo"
BR2_ROOTFS_PRE_BUILD_SCRIPT=""
BR2_ROOTFS_POST_BUILD_SCRIPT="$(BR2_EXTERNAL_ST_PATH)/board/stmicroelectronics/common/post-build.sh $(BR2_EXTERNAL_ST_PATH)/board/stmicroelectronics/stm32mp2/post-build-demo.sh"
BR2_ROOTFS_POST_FAKEROOT_SCRIPT=""
BR2_ROOTFS_POST_IMAGE_SCRIPT="$(BR2_EXTERNAL_ST_PATH)/board/stmicroelectronics/common/post-image.sh $(BR2_EXTERNAL_ST_PATH)/board/stmicroelectronics/common/generate-rauc-bundle.sh"
BR2_ROOTFS_POST_SCRIPT_ARGS="$(BR2_EXTERNAL_ST_PATH)/board/stmicroelectronics/stm32mp2/genimage-demo.cfg"
buildroot-external-st/board/stmicroelectronics/stm32mp2/genimage_demo.cfg
image sdcard.img {
hdimage {
partition-table-type = "gpt"
}
partition fsbla {
image = "%ATFBIN%"
size = 256k
}
partition fip {
image = "fip.bin"
size = 4M
}
partition u-boot-env {
# Matches CONFIG_ENV_OFFSET in U-Boot
offset = 0x900000
# Matches CONFIG_ENV_SIZE in U-Boot
size = 0x2000
}
partition u-boot-env-red {
# Matches CONFIG_ENV_OFFSET_REDUND in U-Boot
offset = 0x940000
# Matches CONFIG_ENV_SIZE in U-Boot
size = 0x2000
}
partition rootfs-a {
image = "rootfs.ext4"
bootable = "yes"
partition-uuid = b26967be-18fb-40fe-9d9b-ae035fc4a1c5
}
partition rootfs-b {
image = "rootfs.ext4"
bootable = "yes"
partition-uuid = 1bfbb0ca-04cc-4a2a-969a-9259cad55bd0
}
}
image emmc.img {
hdimage {
partition-table-type = "gpt"
}
partition fsbla {
image = "%ATFBIN%"
size = 256k
}
partition fip {
image = "fip.bin"
size = 4M
}
partition u-boot-env {
# Matches CONFIG_ENV_OFFSET in U-Boot
offset = 0x900000
# Matches CONFIG_ENV_SIZE in U-Boot
size = 0x2000
}
partition u-boot-env-red {
# Matches CONFIG_ENV_OFFSET_REDUND in U-Boot
offset = 0x940000
# Matches CONFIG_ENV_SIZE in U-Boot
size = 0x2000
}
partition rootfs {
image = "rootfs.ext4"
bootable = "yes"
partition-uuid = b26967be-18fb-40fe-9d9b-ae035fc4a1c5
}
}
output/build/uboot-custom/include/configs/stm32mp25_st_common.h
#define RAUC_BOOT_ENV \
"scriptaddr=0x90000000\0" \
"kernel_addr_r=0x94000000\0" \
"fdt_addr_r=0x98000000\0" \
"pxefile_addr_r=0x90100000\0" \
"BOOT_ORDER=A B\0" \
"BOOT_A_LEFT=3\0" \
"BOOT_B_LEFT=3\0" \
"try_boot_a=if test ${BOOT_A_LEFT} -gt 0; then " \
"setexpr BOOT_A_LEFT ${BOOT_A_LEFT} - 1; " \
"saveenv; " \
"echo 'Attempting Slot A... (${BOOT_A_LEFT} tries left)'; " \
"setenv distro_bootpart ${distro_bootpart_a}; " \
"setenv extlinux_bootpart rootfs-a; " \
"setenv raucslot rauc.slot=A; " \
"run rauc_sysboot; " \
"fi\0" \
"try_boot_b=if test ${BOOT_B_LEFT} -gt 0; then " \
"setexpr BOOT_B_LEFT ${BOOT_B_LEFT} - 1; " \
"saveenv; " \
"echo 'Attempting Slot B... (${BOOT_B_LEFT} tries left)'; " \
"setenv distro_bootpart ${distro_bootpart_b}; " \
"setenv extlinux_bootpart rootfs-b; " \
"setenv raucslot rauc.slot=B; " \
"run rauc_sysboot; " \
"fi\0" \
"rauc_sysboot=sysboot mmc ${mmcdev}:${distro_bootpart} any ${scriptaddr} /boot/extlinux/extlinux.conf\0" \
"boot_rauc_slot=if test \"${BOOT_ORDER}\" = \"A B\"; then " \
"run try_boot_a; run try_boot_b; " \
"else run try_boot_b; run try_boot_a; fi\0"
#define STM32MP25_BOOTCMD \
"bootcmd=if test \"${boot_device}\" = \"nor\"; then " \
"setenv mmcdev 1; setenv distro_bootpart_a 1; setenv distro_bootpart_b 2; " \
"else setenv mmcdev 0; setenv distro_bootpart_a 5; setenv distro_bootpart_b 6; fi; " \
"run boot_rauc_slot\0"
#undef CFG_EXTRA_ENV_SETTINGS
#define CFG_EXTRA_ENV_SETTINGS \
STM32MP_MEM_LAYOUT \
STM32MP25_BOOTCMD \
RAUC_BOOT_ENV \
BOOTENV \
STM32MP_EXTRA \
STM32MP_BOARD_EXTRA_ENV
STM32MP257F-DK side
# fdisk /dev/mmcblk0
Found valid GPT with protective MBR; using GPT
Command (m for help): p
Disk /dev/mmcblk0: 15136768 sectors, 3295M
Logical sector size: 512
Disk identifier (GUID): 9b8d2e4d-626e-4a18-93a3-b8f7de45dd50
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 633366
Number Start (sector) End (sector) Size Name
1 34 545 256K fsbla
2 546 8737 4096K fip
3 18432 18447 8192 u-boot-env
4 18944 18959 8192 u-boot-env-red
5 18960 326159 150M rootfs-a
6 326160 633359 150M rootfs-b
# if it shows the message, fix the fw_env.config
(rauc:532): rauc-WARNING **: 04:17:54.056: Failed getting primary slot: uboot backend: fw_printenv failed with exit co1
# ls -alh /etc/fw_env.config
lrwxrwxrwx 1 root root 18 Jan 1 00:54 /etc/fw_env.config -> fw_env_ubuntu.config
# cat /etc/fw_env_ubuntu.config
# Device name Device offset Env. size
/dev/mmcblk0 0x900000 0x2000
/dev/mmcblk0 0x940000 0x2000
The MathPrimary Env (Partition 3):
Start Sector: 18432
Calculation: 18432 * 512 = 9,437,184 bytes -> Hex: 0x900000
Redundant Env (Partition 4):
Start Sector: 18944
Calculation: 18944 * 512 = 9,699,328 bytes -> Hex: 0x940000
Size (Matches 16 sectors):
Calculation: 16 * 512 = 8,192 bytes -> Hex: 0x2000
STM32MP257F-DK side
STM32MP> printenv
BOOT_A_LEFT=0
BOOT_B_LEFT=3
BOOT_ORDER=A B
api_address=f807a450
arch=arm
autoload=0
baudrate=115200
board=stm32mp2
board_name=stm32mp257f-dk
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
boot_device=mmc
boot_efi_binary=load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} efi/boot/bootaa64.efi; if fdt addr -q ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r};else bootefi ${kernel_addr_r} ${fdtcontroladdr};fi
boot_efi_bootmgr=if fdt addr -q ${fdt_addr_r}; then bootefi bootmgr ${fdt_addr_r};else bootefi bootmgr;fi
boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}${boot_syslinux_conf}
boot_instance=0
boot_net_usb_start=true
boot_prefixes=/ /boot/
boot_rauc_slot=if test "${BOOT_ORDER}" = "A B"; then run try_boot_a; run try_boot_b; else run try_boot_b; run try_boot_a; fi
boot_script_dhcp=boot.scr.uimg
boot_scripts=boot.scr.uimg boot.scr
boot_syslinux_conf=extlinux/extlinux.conf
boot_targets=mmc1 ubifs0 mmc0 mmc2 usb0 pxe
bootcmd=if test "${boot_device}" = "nor"; then setenv mmcdev 1; setenv distro_bootpart_a 1; setenv distro_bootpart_b 2; else setenv mmcdev 0; setenv distro_bootpart_a 5; setenv distro_bootpart_b 6; fi; run boot_rauc_slot
bootcmd_mmc0=devnum=0; run mmc_boot
bootcmd_mmc1=devnum=1; run mmc_boot
bootcmd_mmc2=devnum=2; run mmc_boot
bootcmd_pxe=run boot_net_usb_start; dhcp; if pxe get; then pxe boot; fi
bootcmd_ubifs0=bootubipart=UBI; bootubivol=boot; bootubioff=; run ubifs_boot
bootcmd_usb0=devnum=0; run usb_boot
bootdelay=1
console=ttySTM0
cpu=armv8
distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done
distro_bootpart_a=5
distro_bootpart_b=6
efi_dtb_prefixes=/ /dtb/ /dtb/current/
env_check=if env info -p -d -q; then env save; fi
ethaddr=10:e7:7a:e3:cc:ba
fdt_addr_r=0x98000000
fdtcontroladdr=f8006010
fdtfile=stm32mp257f-dk.dtb
fdtoverlay_addr_r=0x90300000
kernel_addr_r=0x94000000
kernel_comp_addr_r=0x84000000
kernel_comp_size=0x04000000
load_efi_dtb=load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} ${prefix}${efi_fdtfile}
loadaddr=0x84000000
mmc_boot=if mmc dev ${devnum}; then devtype=mmc; run scan_dev_for_boot_part; fi
mmcdev=0
pxefile_addr_r=0x90100000
ramdisk_addr_r=0x90400000
rauc_sysboot=sysboot mmc ${mmcdev}:${distro_bootpart} any ${scriptaddr} /boot/extlinux/extlinux.conf
scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;run scan_dev_for_efi;
scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then part uuid ${devt
ype} ${devnum}:${distro_bootpart} distro_bootpart_uuid ; run scan_dev_for_boot; fi; done; setenv devplist
scan_dev_for_efi=setenv efi_fdtfile ${fdtfile}; for prefix in ${efi_dtb_prefixes}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${efi_fdtfile}; then run load_efi_dtb; fi;done;run boot_efi_bootmgr;if test -e ${devtype} ${
devnum}:${distro_bootpart} efi/boot/bootaa64.efi; then echo Found EFI removable media binary efi/boot/bootaa64.efi; run boot_efi_binary; echo EFI LOAD FAILED: continuing...; fi; setenv efi_fdtfile
scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${boot_syslinux_conf}; then echo Found ${prefix}${boot_syslinux_conf}; run boot_extlinux; echo EXTLINUX FAILED: continuing...; fi
scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done
scriptaddr=0x90000000
serial#=004800394236501600363847
serverip=192.168.1.1
soc=stm32mp
try_boot_a=if test ${BOOT_A_LEFT} -gt 0; then setexpr BOOT_A_LEFT ${BOOT_A_LEFT} - 1; saveenv; echo 'Attempting Slot A... (${BOOT_A_LEFT} tries left)'; setenv distro_bootpart ${distro_bootpart_a}; setenv extlinux_bootpart rootfs-a; setenv
raucslot rauc.slot=A; run rauc_sysboot; fi
try_boot_b=if test ${BOOT_B_LEFT} -gt 0; then setexpr BOOT_B_LEFT ${BOOT_B_LEFT} - 1; saveenv; echo 'Attempting Slot B... (${BOOT_B_LEFT} tries left)'; setenv distro_bootpart ${distro_bootpart_b}; setenv extlinux_bootpart rootfs-b; setenv
raucslot rauc.slot=B; run rauc_sysboot; fi
ubifs_boot=if ubi part ${bootubipart} ${bootubioff} && ubifsmount ubi0:${bootubivol}; then devtype=ubi; devnum=ubi0; bootfstype=ubifs; distro_bootpart=${bootubivol}; run scan_dev_for_boot; ubifsumount; fi
usb_boot=usb start; if usb dev ${devnum}; then devtype=usb; run scan_dev_for_boot_part; fi
usb_pgood_delay=2000
vendor=st
ver=U-Boot 2023.10-stm32mp-r2-rc8 (Jan 22 2026 - 10:24:06 +0800)
Environment size: 4849/8187 bytes
rauc status, MP2 side
# rauc status
=== System Info ===
Compatible: stm32mp257f-dk
Variant:
Booted from: rootfs.1 (B)
=== Bootloader ===
Activated: rootfs.1 (B)
=== Slot States ===
x [rootfs.1] (/dev/disk/by-partlabel/rootfs-b, raw, booted)
bootname: B
boot status: good
o [rootfs.0] (/dev/disk/by-partlabel/rootfs-a, raw, inactive)
bootname: A
boot status: good
# rauc status
=== System Info ===
Compatible: stm32mp257f-dk
Variant:
Booted from: rootfs.0 (A)
=== Bootloader ===
Activated: rootfs.0 (A)
=== Slot States ===
o [rootfs.1] (/dev/disk/by-partlabel/rootfs-b, raw, inactive)
bootname: B
boot status: good
x [rootfs.0] (/dev/disk/by-partlabel/rootfs-a, raw, booted)
bootname: A
boot status: good
//switch partition
#fw_printenv BOOT_ORDER
BOOT_ORDER=A B
# rauc status mark-active rootfs.1
rauc status: activated slot rootfs.1
# fw_printenv BOOT_ORDER
BOOT_ORDER=B A
/etc/rauc/system.conf
# cat /etc/rauc/system.conf
[system]
compatible=stm32mp257f-dk
bootloader=uboot
max-bundle-download-size=209715200
mountprefix=/tmp/rauc
data-directory=/data/rauc
[keyring]
path=/etc/rauc/ca.cert.pem
use-bundle-signing-time=true
[slot.rootfs.0]
device=/dev/mmcblk1p5 or mmcblk0p5, ls /dev/mmcblk...
type=raw
bootname=A
[slot.rootfs.1]
device=/dev/mmcblk1p6 or mmcblk0p6
type=raw
bootname=B
Make the raucb file for localMP2 side...Because the emulator cannot run the rauc-related daemon/background programs.
# mount /dev/sda1 /mnt
# cd /mnt/rauc_test/
# tree
.
|-- contents
| |-- manifest.raucm
| `-- rootfs.img
|-- dev-cert.pem
|-- dev-key.pem
|-- manifest.raucm
`-- update.raucb
# date -s "2026-02-25 15:10:00"
# ls -alh /mnt/rauc_test/contents/
total 150M
-rwxr-xr-x 1 root root 177 Feb 25 2026 manifest.raucm
-rwxr-xr-x 1 root root 150.0M Feb 25 2026 rootfs.img
# sha256 /mnt/rauc_test/contents/rootfs.img
0516ac54a13c6f409c0fa86205b0211b18cdc3cd5a2c27a1d8743c9830e73d48
# vi contents/manifest.raucm
# cat /mnt/rauc_test/contents/manifest.raucm
[update]
compatible=stm32mp257f-dk
version=2026.02.23
[image.rootfs]
sha256=0516ac54a13c6f409c0fa86205b0211b18cdc3cd5a2c27a1d8743c9830e73d48
size=157286400
filename=rootfs.img
# rauc bundle --keyring dev-cert.pem --cert dev-cert.pem --key dev-key.pem contents/ update.raucb
Creating 'plain' format bundle
WARNING: The manifest does not specify a bundle format, defaulting to 'plain'.
We recommend using the 'verity' format instead, if possible.
To silence this warning, select the 'plain' format explicitly.
See https://rauc.readthedocs.io/en/latest/reference.html#sec-ref-formats for details.'
rauc-Message: 00:12:04.850: Keyring given, doing signature verification
rauc-Message: 00:12:05.844: Verified detached signature by 'C = TW, ST = Taipei, L = Daan, O = Dev, CN = stm32-update'
# cd /etc/rauc
# mv ca.cert.pem ca.cert.pem_orig
# cp /mnt/rauc_test/dev-cert.pem ./ca.cert.pem
# ls
ca.cert.pem ca.cert.pem_orig system.conf version
# chmod 644 ca.cert.pem
# rauc install /mnt/rauc_test/update.raucb
installing
0% Installing
0% Determining slot states
10% Determining slot states done.
10% Checking bundle
10% Verifying signature
[ 31.715752] vddio3: disabling
[ 31.715838] vddio4: disabling
[ 31.716099] vdda18adc: disabling
[ 31.719430] v5v_vconn: disabling
20% Verifying signature done.
[ 32.102549] loop0: detected capacity change from 0 to 88660
20% Checking bundle done.
[ 32.122492] loop0: detected capacity change from 88660 to 88656
20% Checking manifest contents
30% Checking manifest contents done.
30% Determining target install group
40% Determining target install group done.
40% Updating slots
40% Checking slot rootfs.1
46% Checking slot rootfs.1 done.
46% Copying image to rootfs.1
47% Copying image to rootfs.1
48% Copying image to rootfs.1
49% Copying image to rootfs.1
...
...
99% Copying image to rootfs.1
99% Copying image to rootfs.1 done.
99% Updating slots done.
100% Installing done.
idle
Installing `/mnt/rauc_test/update.raucb` succeeded
# reboot to check
* RAUC updates the inactive side, but it relies on U-Boot to actually change the "active" flag during the next boot.
Make the raucb file for stream
# cat /media/nice/TRANSCEND/rauc_test/contents/manifest.raucm
[update]
compatible=stm32mp257f-dk
version=2026.02.23
[bundle]
format=verity
[image.rootfs]
sha256=0516ac54a13c6f409c0fa86205b0211b18cdc3cd5a2c27a1d8743c9830e73d48
size=157286400
filename=rootfs.img
# date -s "2026-02-25 15:10:00"
# rauc bundle --keyring dev-cert.pem --cert dev-cert.pem --key dev-key.pem contents/ update_stream.raucb
# rauc install http://192.168.111.111:8000/update_stream.raucb
installing
0% Installing
0% Determining slot states
10% Determining slot states done.
10% Checking bundle
10% Verifying signature
20% Verifying signature done.
20% Checking bundle done.
[ 1703.006535] nbd0: detected capacity change from 0 to 89360
20% Checking manifest contents
30% Checking manifest contents done.
[ 1703.035211] device-mapper: verity: sha256 using implementation "sha256-arm64-neon"
30% Determining target install group
40% Determining target install group done.
40% Updating slots
40% Checking slot rootfs.1
46% Checking slot rootfs.1 done.
46% Copying image to rootfs.1
47% Copying image to rootfs.1
...
...
99% Copying image to rootfs.1 done.
99% Updating slots done.
[ 1763.146710] block nbd0: NBD_DISCONNECT
[ 1763.149663] block nbd0: Disconnected due to user request.
[ 1763.150225] block nbd0: shutting down sockets
[ 1763.158534] block nbd0: NBD_DISCONNECT
[ 1763.159151] block nbd0: Send disconnect failed -32
100% Installing done.
Installing `http://192.168.43.137:8000/update_stream.raucb` succeeded
server.py (The data update.raucb transfer process keeps showing an error message)
#$ uv init
$ uv add range-httpserver
import os
import http.server
# This is a more complete standalone version
class RangeRequestHandler(http.server.SimpleHTTPRequestHandler):
def send_head(self):
path = self.translate_path(self.path)
if os.path.isdir(path):
return super().send_head()
ctype = self.guess_type(path)
try:
f = open(path, 'rb')
except OSError:
self.send_error(404, "File not found")
return None
range_header = self.headers.get('Range')
if not range_header or not range_header.startswith('bytes='):
return super().send_head()
try:
size = os.fstat(f.fileno()).st_size
ranges = range_header.split('=')[1].split('-')
start = int(ranges[0])
end = int(ranges[1]) if ranges[1] else size - 1
except (ValueError, IndexError):
return super().send_head()
if start >= size or end >= size:
self.send_error(416, "Requested Range Not Satisfiable")
f.close()
return None
self.send_response(206)
self.send_header('Content-Type', ctype)
self.send_header('Accept-Ranges', 'bytes')
self.send_header('Content-Range', f'bytes {start}-{end}/{size}')
self.send_header('Content-Length', str(end - start + 1))
self.end_headers()
f.seek(start)
return f
if __name__ == '__main__':
http.server.test(HandlerClass=RangeRequestHandler, port=8000)
沒有留言:
張貼留言