Bricked X96 Max+: diagnosis and recovery over the serial console
A box that shows no LED, no picture and no network is not necessarily dead. This is the story of an X96 Max+ (Amlogic S905X3, 4 GB) that booted Android, that I bricked while trying to install Armbian, and that I recovered.
Where it started
The box ran Android. The goal: an Armbian server with the system on a USB 3.0 SSD. I took the usual route, ophub’s installer (armbian-install).
What broke
The installer, run with its default option (-m no), wrote a bootloader called hk1box-bootloader.img into the user area of the eMMC. That is another box’s bootloader. On this board its memory initialisation crashes, so the first boot stage (BL2) restarts in a loop. On the serial console the same sequence scrolls past: eMMC read, bl2_stage_init, hardware ID, reset.
Why it looked dead
Everything you normally check was silent:
- no LED, because the front display is driven by software;
- no HDMI picture, because the crash happens before u-boot;
- no network;
- no USB fallback mode: the ROM reads the eMMC first, finds it valid at its check (
CHK:0) and never switches to USB.
Proof of life came from the serial console (UART, 3.3 V levels, 115200 8N1): the ROM messages kept looping. One more hint: a red glow in the optical port, meaning the board was powered.
The key: make the eMMC fail
The ROM is “eMMC first”: a rescue SD card is useless while the eMMC answers. So the eMMC has to fail at boot time. I tied one eMMC signal line (CLK, CMD or DAT0) to ground at power-on, using one of the small round pads right at the edge of the BGA package. The larger components around it do nothing.
Warning. This is a last-resort manoeuvre that can damage the board. I am not detailing the pads of this model. Use a mains power supply: USB power alone causes brown-outs that skew everything.
On the UART the message changes: EMMC:1000, then SD:0. The eMMC is seen as faulty, and the ROM falls back to the SD card. The rescue SD holds the original bootloader written at offset 0x200.
The permanent fix
Once Armbian is running, replace the bad bootloader with the right one, the mainline build for this board. It ships with the system as /usr/lib/u-boot/x96maxplus-u-boot.bin.sd.bin. Write it in two passes to keep the partition table (MBR) intact:
sudo dd if=/usr/lib/u-boot/x96maxplus-u-boot.bin.sd.bin of=/dev/mmcblk2 bs=1 count=444 conv=fsync
sudo dd if=/usr/lib/u-boot/x96maxplus-u-boot.bin.sd.bin of=/dev/mmcblk2 bs=512 skip=1 seek=1 conv=fsync
The device name (mmcblk2 here) varies between boards: check it with lsblk before writing. After that, the box boots on its own from the eMMC, then hands over to the SSD system.
Restore. Before any write, back up the complete eMMC (the whole device, plus boot0 and boot1). That is what lets you roll back if the bootloader rewrite goes wrong.
Traps that remain after the fix
- System identity. The SSD I reused still held an older system from another box:
/etc/ophub-releaseand/etc/armbian-releaseclaimed ans905wSoC. I set them back tos905x3and the right model. Rerunning the installer with a wrong label means bricking it again. - USB bridge. The JMicron JMS583 bridge is unstable in UAS mode (resets, slow access). The kernel parameter
usb-storage.quirks=152d:0583:uforces BOT mode and makes the SSD stable at 5000 Mb/s.
End state
Standalone boot from eMMC into the SSD system, no SD card, 4 GB of RAM actually seen by Linux (3.7 GiB), WiFi up.
TODO(nico): attach the UART log of the boot loop and of the successful boot.
What I take from it
- Back up the eMMC before running an installer, not after.
- When a box looks dead, connect the UART before you conclude anything.
- An installer’s default options are not neutral: check which bootloader it will write before you run it.