U-Boot Update Mechanism (sweup)¶
The stock bootloader can install a complete firmware image from a USB stick, without any help from Linux. This is the most reliable way to change firmware — it works when the running system is broken, refuses to update, or will not boot at all.
Restore stock firmware covers the button-only procedure for end users. This page documents the underlying command, its parameters, and exactly what each one writes, for use from a serial console.
Warning: Every mode erases and rewrites NAND. The
ubootparameter rewrites the bootloader itself, which is the only step that can leave the device unrecoverable. Do not interrupt power during an update.
Preparing the USB stick¶
- Format the drive as FAT32, with the image in the first partition
(the bootloader loads from
usb 0:1). - Copy the firmware file to the root of the drive, named exactly
Update.stu, unmodified and by itself. - Insert it in the setup port before powering on.
Not every USB stick enumerates. If the bootloader stalls at
scanning bus for devices, try a different drive — smaller, older, USB 2.0
sticks work best. This is a bootloader USB-stack limitation, not a fault in the
image.
The sweup command¶
From the U-Boot prompt (see Serial console):
sweup [both] [preserve] [uboot]
Its built-in help:
sweup - Read the software update image from properly prepared USB stick
[both] - update both Ping and Pong (default is just Pong)
[preserve] - update both Ping and Pong, but preserve persistent data
[uboot] - update both Ping and Pong, reset persistent data, update uboot
The device keeps two complete copies of the kernel and root filesystem, called Ping and Pong. Updating only one leaves the other as a fallback.
Parameters¶
| Invocation | Kernel + rootfs | Persistent data | Bootloader | Console message |
|---|---|---|---|---|
sweup |
Pong only | kept | untouched | — |
sweup both |
Ping and Pong | reset | untouched | Updating both partitions... |
sweup preserve |
Ping and Pong | kept | untouched | Updating both partitions, preserving persistent data... |
sweup uboot |
Ping and Pong | reset | rewritten | Updating both partitions AND uboot, save PersistentData = 0 |
sweup uboot preserve |
Ping and Pong | kept | rewritten | Updating both partitions AND uboot, save PersistentData = 1 |
Parameters combine: uboot preserve is a distinct, valid mode, and it is the
one the device's own emergency key combination uses.
"Persistent data" is the /mnt/nv area — settings, presets, account
association and logs. When kept, the bootloader prints
Preserving persistent data areas.
Which mode to use
sweup preserve— the normal choice. Both slots updated, settings kept, bootloader left alone, so your working recovery path is untouched.sweup uboot preserve— required when the new firmware needs a newer bootloader (see When the bootloader must change).sweup both/sweup uboot— same, but also factory-reset settings.sweupwith no argument — updates only the inactive slot; useful for a cautious test, since the other slot still holds the previous firmware.
What it does¶
Start eUpdate
Opened USB device
Update Header : hdrsize=20 sig=BOSE ver=... sectionhdrsize=... chksum=...
Update Section : type=... 'linuxPatched' size=... crc=0x...
Parsed Update.stu
Found the kernel image at <addr>, size <n> crc=0x<crc>
Found the filesystem image at <addr>, size <n> crc=0x<crc>
...
eUpdate DONE
It reads Update.stu from the FAT partition, walks its section table, locates
the linuxPatched (kernel), ubi.img (rootfs) and — with uboot — the MLO
and u-boot.img sections, then verifies each payload's CRC32 before writing
NAND:
Kernel image CRC is 0x<crc>
Kernel image CRC mismatch : 0x<a> != 0x<b> : aborting update !
Filesystem image CRC mismatch : 0x<a> != 0x<b> : aborting update !
MLO image CRC mismatch : 0x<a> != 0x<b> : aborting update !
uboot image CRC mismatch : 0x<a> != 0x<b> : aborting update !
A CRC failure aborts before anything is erased, so a corrupt or truncated
Update.stu cannot damage the device.
NAND regions written¶
| Region | Address | Size | Written by |
|---|---|---|---|
| MLO / SPL (+3 backups) | 0x0 |
0x20000 |
uboot only |
| U-Boot | 0x80000 |
0x1e0000 |
uboot only |
| U-Boot environment | 0x260000 |
0x20000 |
erased by uboot |
| Kernel Ping | 0x280000 |
0x500000 |
both/preserve/uboot |
| Kernel Pong | 0x780000 |
0x500000 |
always |
| Filesystem Ping | 0xc80000 |
0x6000000 |
both/preserve/uboot |
| Filesystem Pong | 0x6c80000 |
0x6000000 |
always |
| Persistent storage | — | — | erased unless preserve |
Addresses are the stock *_nand_address / *_nand_size environment values.
Triggering it without a console¶
The bootloader samples the keypad at power-on and maps certain combinations to
sweup invocations, so a device with no serial console can still be recovered:
Emergency Update <variant> from USB - preserve... -> sweup uboot preserve ; reset
Emergency Update M/S/T from USB - factory reset... -> sweup uboot ; reset
Binky - factory default... -> binky_setupap ; reset
Holding any key also stretches bootdelay to 3 seconds. An unrecognised
combination prints Unmapped keymask = <mask> for variant <variant>, no action
and boots normally.
The exact button combinations are model-specific; see
Restore stock firmware for the documented ones.
Related environment variables are bootdelaykey, bootdelaykey2, bootstopkey
and bootstopkey2, with bootdelay=1.
Every one of these erases the U-Boot environment, because they all run
sweup … uboot. Anything you stored there — theusbbootandusbbootargsdefinitions used for USB development boot, and anybootcmdyou set — is lost and has to be written again.
The kernel signature and the "boot next" flag¶
Each kernel image in NAND carries a five-character signature in its uImage name field, and the bootloader uses it to decide which slot to boot:
| Signature | Meaning |
|---|---|
Linux… |
the current, known-good kernel (Linux-3.14.43+ on stock 15.00.20 and later) |
Linxt… |
boot this slot next — set on a slot that has just been updated |
Linpv… |
the previous kernel, still bootable |
Linub… |
installed but not yet booted; also what sweup … preserve writes |
Linem… |
the same, for sweup's factory-reset modes |
Anything other than Linux also invalidates the image header checksum, which is
what fixsig repairs — in RAM, after the image has been loaded and before
bootm — so every nand_boot command ends …; fixsig; bootm ….
An update installs into the slot that is not running and flags it Linxt.
After that slot has booted, the system clears the flag to Linux and demotes
the slot it replaced to Linpv, so exactly one slot is ever Linux.
The check runs before bootcmd and can replace it:
| Signatures (Ping / Pong) | Autoboot runs |
|---|---|
Ping Linxt… |
run nand_boot, after printing Force boot from Primary partitions... |
Pong Linxt… |
run nand_boot2, silently |
Linux / Linpv — resting on Ping |
bootcmd |
Linpv / Linux — resting on Pong |
run nand_boot2, silently |
both Linux…, or neither |
bootcmd |
whichk reports the state. Commands typed at the prompt are never overridden —
only autoboot is.
When the bootloader must change¶
Stock firmware 15.00.20 switched to booting with a device tree. The older bootloader loads the kernel and jumps straight to it:
nand_boot=... nboot.e ${kloadaddr} 0 ${kernel0_nand_address}; fixsig; bootm ${kloadaddr}
The newer bootloader mounts the root filesystem and loads a device tree first:
nand_boot=... ubi part NAND.File-System-Ping 2048; ubifsmount ubi0;
ubifsload ${loadaddr} /boot/${variant}_${module_type}.dtb;
fdt addr ${loadaddr}; ... bootm ${kloadaddr} - ${loadaddr}
The Linux 3.14 kernel shipped from 15.00.20 onward requires that device tree, so
crossing this boundary requires sweup uboot preserve — plain
sweup preserve installs a kernel the old bootloader cannot boot.
Once across, sweup keeps identical parameters, so recovery still works
afterwards. Updating between any two releases from 15.00.20 onward does not
cross the boundary at all.
Where the change happened¶
The switch happens at 15.00.20, with no intermediate step — bootloader, kernel and boot command all change at once, and nothing before it uses a device tree:
| Version | Bootloader | Kernel | Device tree |
|---|---|---|---|
| 02.01.51 | U-Boot 2012.10-04327 | Linux 3.2.0 | no |
| 03.01.20, 04.00.14 | U-Boot 2012.10-04330 | Linux 3.2.0 | no |
| 05.00.23 | U-Boot 2012.10-04331 | Linux 3.2.0 | no |
| 06.00.39 | U-Boot 2012.10-04333 | Linux 3.2.0 | no |
| 06.02.01, 07.00.37, 07.02.21 | U-Boot 2012.10-04334 | Linux 3.2.0 | no |
| 09.00.41 | U-Boot 2013.01.01-05705 | Linux 3.2.0 | no |
| 10.00.11 | U-Boot 2013.01.01-05706 | Linux 3.2.0 | no |
| 12.00.09 | U-Boot 2013.01.01-05719 | Linux 3.2.0 | no |
| 13.00.09, 14.00.15, 14.00.33 | U-Boot 2013.01.01-05721 | Linux 3.2.0 | no |
| 15.00.20 | U-Boot 2014.07-05722 | Linux 3.14.43 | yes |
| 16.00.09 … 27.00.06 | U-Boot 2014.07-05722 | Linux 3.14.43 | yes |
The bootloader introduced in 15.00.20 is then unchanged through 27.00.06 —
every release from 15.00.20 onward carries U-Boot 2014.07-05722-g93f9891.
Updating between any two of them does not change the bootloader in practice,
even though UbootUpdate still runs.
The table covers both hardware platforms. For every version released for both,
the MLO, u-boot.img and kernel images are identical — only the root
filesystem differs per product — so one boot-method timeline applies to every
device.
Version numbers are not comparable across product lines. Each product family has its own release train, so a higher number does not always mean a newer bootloader. The SoundTouch adapter's 06.00.91, for example, carries U-Boot 2012.10-04331 — the same build as ST20/30's 05.00.23, and older than ST20/30's 06.00.39. Versions 08 and 11 do not appear at all.
To settle it for any particular device, check its bootloader directly:
printenv nand_bootIf it contains
ubifsload/fdt addr, that build boots with a device tree; if it ends atbootm ${kloadaddr}, it does not.
Alternative: writing loose files¶
The environment also carries commands that install individual files rather than
an Update.stu container. These expect uImage, ubi.img, MLO and
u-boot.img on the FAT partition:
| Command | Effect |
|---|---|
run update_kfs |
kernel + filesystem, both slots |
run update_kernel |
kernel only, both slots |
run update_kernel0 / update_kernel1 |
one kernel slot |
run update_fs |
filesystem, both slots |
run update_fs0 / update_fs1 |
one filesystem slot |
run update_uboot |
MLO + U-Boot, then erase the environment |
run update_all |
everything, including the bootloader |
These perform no CRC verification — sweup is preferred wherever possible.
Related commands¶
| Command | Purpose |
|---|---|
whichk |
Report which kernel slot carries the "boot next" flag (see above) |
fixsig |
Restore the Linux signature in a kernel image already in RAM |
buttons |
Sample the keypad state |
leds [on/off/flash] |
Set the indicator LEDs |
run nand_boot / nand_boot2 |
Boot from Ping / Pong explicitly |
If it goes wrong¶
Keep a FAT32 stick with a known-good Update.stu on hand before any bootloader
update; re-running sweup preserve from a working bootloader is the fastest way
back. If the bootloader itself no longer starts, see
Unbrick a device — note the warning there that USB-RNDIS recovery
is confirmed only on SM2 hardware.
The console messages, parameters and NAND addresses quoted on this page are
those of the stock bootloader and its environment. Check the values on your own
device with printenv before relying on them.