summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2026-02-10 15:54:09 -0600
committerTom Rini <[email protected]>2026-02-10 15:54:09 -0600
commit6f7fe31bf6d934f0240da74f06a5b42689a2ac7f (patch)
tree01b4f552f2a58a49f9a2115f5ab695396f0ec0a2 /doc
parentaf3b0be9cb0d891a0d23df6b8247dedac5a1b809 (diff)
parenta672456d4b2bd216dcfe9d09fb5fbce2b013735a (diff)
Merge patch series "am335x: failsafe bootloader update"
Rasmus Villemoes <[email protected]> says: Make it possible to update the (whole) bootloader on am335x robustly, i.e. so that a power failure or random OOM killing of the update process or other interruptions do not result in a bricked board. The order the trial bits gets set is somewhat odd, but is clearly what happens, and somebody else trying to reverse engineer the ROM code has observed the same thing: See the TracingVectors.ods in https://github.com/sjgallagher2/am335xbootrom . Link: https://lore.kernel.org/r/[email protected]
Diffstat (limited to 'doc')
-rw-r--r--doc/board/ti/am335x_evm.rst80
1 files changed, 80 insertions, 0 deletions
diff --git a/doc/board/ti/am335x_evm.rst b/doc/board/ti/am335x_evm.rst
index b14ba41917e..904881b4146 100644
--- a/doc/board/ti/am335x_evm.rst
+++ b/doc/board/ti/am335x_evm.rst
@@ -481,3 +481,83 @@ bind with it:
misc 0 [ + ] ti-musb-wrapper | |-- usb@47400000
usb 0 [ ] ti-musb-peripheral | | |-- usb@47401000
usb 0 [ ] ti-musb-host | | `-- usb@47401800
+
+Failsafe bootloader update
+--------------------------
+
+As indicated above, the ROM code on the AM335x supports loading SPL
+from one of several different locations. It looks at offsets 0,
+128KiB, 256KiB and 384KiB (sectors 0, 0x100, 0x200, 0x300) for a
+sector containing a valid "TOC structure" (see the reference manual
+for details).
+
+This can be used to implement a scheme for updating SPL which is
+robust against power failure or other interruptions: Suppose we store
+copies of SPL (wrapped in the "MLO" image, which is what includes that
+TOC structure) at offsets 128KiB and 256KiB, and let us refer to those
+two locations as slot 1 and slot 2.
+
+The whole procedure maintains the invariant that at any time, at
+least one of the slots contains a complete and valid MLO image. In
+order to update SPL:
+
+(1) Determine a slot X containing a valid image (by having a proper
+ TOC structure in the first sector). Designate the other
+ slot Y. Since the TOC is always the same 512 bytes (see section
+ 26.1.11 in the reference manual), checking for a valid image can
+ be done using something like
+
+.. code-block:: bash
+
+ if cmp -s -n 512 MLO /path/to/SPL-1 ; then
+ X=1
+ Y=2
+ elif cmp -s -n 512 MLO /path/to/SPL-2 ; then
+ X=2
+ Y=1
+ else
+ # invariant broken, fatal error, refuse update...
+ fi
+
+(2) Ensure Y will be deemed invalid by the ROM code by writing all
+ zeroes to the first sector of Y, for example using
+
+.. code-block:: bash
+
+ dd if=/dev/zero of=/path/to/SPL-Y bs=512 count=1 conv=fsync
+
+(3) Write everything but the first sector of the MLO image to slot Y:
+
+.. code-block:: bash
+
+ dd if=MLO of=/path/to/SPL-Y bs=512 skip=1 seek=1 conv=fsync
+
+(4) Write the TOC structure to slot Y:
+
+.. code-block:: bash
+
+ dd if=MLO of=/path/to/SPL-Y bs=512 count=1 conv=fsync
+
+(5) Repeat steps (2)--(4) for slot X.
+
+Now, this procedure only accounts for safely updating SPL. If U-Boot
+proper is only stored in a single location, there is no way to update
+that which is safe against powercut during the update. However, by
+selecting the configuration option CONFIG_SPL_AM33XX_MMCSD_MULTIPLE,
+you can tell SPL to load U-Boot proper from a location which depends on
+where SPL itself was loaded from. Hence, one can for example put
+copies of u-boot.img at offsets 512KiB and 1536KiB, and set
+
+::
+
+ CONFIG_SPL_AM33XX_MMCSD_MULTIPLE=y
+ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_128K=0x400
+ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR_256K=0xc00
+
+and amend the step (3) above by
+
+ Write U-Boot proper to the location corresponding to slot Y:
+
+.. code-block:: bash
+
+ dd if=u-boot.img of=/path/to/U-BOOT-Y bs=512 conv=fsync