Unbrick a Device (currently only SM2)¶
A device whose bootloader is damaged can still be recovered, because the AM335x BootROM tries the Micro-USB setup port before it tries NAND. Whatever is written in the flash, a board with a host on that port boots what the host offers it. That is what makes the rest of this page safe to get wrong.
Boot the device over USB RNDIS and rewrite the bootloader partitions from the U-Boot prompt, over the same USB link that brought U-Boot in. Nothing else is needed on the device: the recovery U-Boot reads and writes NAND by itself, so the recovery Linux root filesystem never has to come up.
Warning: This only applies to SM2 devices and out of these it is only confirmed for
spotty_sm2. For SCM devices there currently is no easy way to unbrick them. If you bricked your SCM device, what you have to do is force it to boot from UART (either by changing boot order or by forcing reads from NAND to fail), then boot MLO and U-Boot via UART. From there you then have to write MLO/U-Boot to flash, after possibly transferring another "clean" copy via UART (XMODEM/YMODEM). This is not only difficult to set up but also very time-consuming.
1. Boot the recovery U-Boot¶
Set the host up and boot the device as described in USB RNDIS network boot. Only the DHCP and TFTP services from that page are needed here; the NFS root is not used.
Press a key when the device offers to stop autoboot, to get a prompt:
Hit any key to stop autoboot: 0
=>
Check that the recovery U-Boot can see the flash before going any further:
=> nand info
Device 0: nand0, sector size 128 KiB
Page size 2048 b
OOB size 64 b
Erase size 131072 b
If this prints nothing, stop. Without a working NAND there is nothing to recover onto, and the writes below would not do what this page says.
2. Put the replacement images where the device can fetch them¶
Copy the MLO and u-boot.img you intend to restore into the TFTP directory
the device already booted from. These are normally the ones from the stock
firmware for your device; obtaining them is outside the scope of this guide.
The MLO and u-boot.img built from this project work too, and are what a
development device runs.
Warning: The steps below erase and rewrite the bootloader partitions. Make sure the two files are the ones you mean to write.
3. Load and check the images¶
Give the device an address, then fetch both files into RAM:
=> setenv autoload no
=> dhcp
=> tftpboot 0x82000000 MLO
=> tftpboot 0x84000000 u-boot.img
Two things here bite people:
- The command is
tftpboot. There is notftp; it fails withUnknown command, and if you do not read the output you will go on to write whatever happened to be in RAM already. - Load to
0x82000000and0x84000000. Higher addresses run into memory U-Boot has reserved for itself, and the transfer stops withTFTP error: trying to overwrite reserved memory.
Check every transfer before writing anything. A successful one ends with a byte count:
Bytes transferred = 65200 (feb0 hex)
If that line is missing, the load failed. Do not continue.
4. Write the bootloader partitions¶
The bootloader lives at the bottom of the flash:
| Offset | Size | Partition |
|---|---|---|
0x000000 |
0x20000 |
NAND.SPL — the copy the BootROM tries first |
0x020000 |
0x20000 |
NAND.SPL.backup1 |
0x040000 |
0x20000 |
NAND.SPL.backup2 |
0x060000 |
0x20000 |
NAND.SPL.backup3 |
0x080000 |
0x1e0000 |
NAND.U-Boot |
0x260000 |
0x20000 |
NAND.U-Boot-Env |
Write MLO to the first slot and u-boot.img to the U-Boot partition. The
write lengths are rounded up to whole flash pages, which is why they are
larger than the files:
=> nand erase 0x0 0x20000
=> nand write 0x82000000 0x0 0x10000
=> nand erase 0x80000 0x1e0000
=> nand write 0x84000000 0x80000 0xb0000
Writing only the first slot leaves the three backups as they were, so the
BootROM still has something to fall back on if that copy ever becomes
unreadable. To replace them as well, repeat the two MLO commands at
0x20000, 0x40000 and 0x60000.
5. Verify what landed in the flash¶
Read each region back and compare it against the file. crc32 over the length
of the original file must match what the same file gives on the host:
=> nand read 0x82000000 0x0 0x10000
=> crc32 0x82000000 0xfeb0
CRC32 for 82000000 ... 8200feaf ==> 10149634
On the host:
python3 -c 'import zlib,sys; print("%08x" % zlib.crc32(open(sys.argv[1],"rb").read()))' MLO
Use the exact byte length of the file, not the rounded-up write length. If the two do not match, write it again; do not power the device off believing it is fixed.
6. Clear the U-Boot environment (optional)¶
An environment stored by the previous installation survives a bootloader rewrite and can send the new U-Boot somewhere unexpected. To discard it:
=> nand erase 0x260000 0x20000
Erase nothing else for this step.
7. Boot from the flash¶
Remove the USB host — unplug the Micro-USB cable, or power its port down — and power cycle the device. With no host on that port the BootROM falls through to NAND and runs what you just wrote.
If it does not come up, reconnect USB and start again from step 1. The recovery path does not depend on anything in the flash, so it is still there.