Recovering i.MX platforms using UUU
Published on March 30, 2020
This blog post will introduce the Universal Update Utility (UUU) from NXP.
Introduction
For many years, Freescale provided MFGTools / sb_loader binaries in order to flash empty devices leveraging the USB recovery feature of the i.MX family. However these tools were only meant for Windows Host. Therefore Boundary Devices decided, back in 2010, to develop its own Linux-based tool called imx-usb-loader. This latter has been used by many for years, maintained by us with the help of the community. But in 2018, NXP decided to unify their tools, creating a new one from scratch called UUU. Let's see the benefits of using that new tool and how it compares to ours.
UUU Advantages
First of all, UUU provides the same features as imx-usb-loader:
- Loading bootloader / recovering devices over USB recovery (SDP) protocol
- Loading any binary in RAM over USB for flashing purposes
But it also includes some new features:
- Advanced scripting supported to flash any media
- Fastboot protocol support in both U-Boot and OS (with imx-uuc)
Note that this blog post will focus on the recovery process part, flashing will be covered in another blog post. We also see the following advantages in using it:
- Tool maintained by NXP
- Already supports next generation SoC
- Tool works the same on Linux and Windows
- MAC OS should work too, hasn't been tested
- Aligning our flashing procedure with NXP
- Easier for customers
- Still an open-source project
- NXP accepts community contributions
What about imx-usb-loader?
As of this writing, Boundary Devices will no longer actively maintain imx-usb-loader. We will now be focusing on using and contributing to UUU. That being said, if the community still sees a need for imx-usb-loader, we will still accept pull-requests.
How to recover using UUU?
If you are reading this, it most likely means that your platform is not booting any longer. This procedure will help you recover it by using the NXP USB recovery SDP protocol:
Make sure your board is booting in Recovery mode.
All our platforms have a DIP switch which allows to override the normal boot flow and force a boot to the USB recovery mode (OTG port). You can either read the manual of your device or look at our previous post on the subject to locate the switch: Unbricking your Boundary Devices platform For i.MX6/7 devices it should look like:
$ lsusb | grep -E 'Freescale|NXP'
Bus 001 Device 079: ID 15a2:0061 Freescale Semiconductor, Inc. i.MX 6Solo/6DualLite SystemOnChip in RecoveryMode
For i.MX8 devices, it should look like:
$ lsusb | grep -E 'Freescale|NXP'
Bus 001 Device 080: ID 1fc9:012b NXP Semiconductors i.MX 8M Dual/8M QuadLite/8M Quad Serial Downloader
Download latest UUU binary
Pre-built binaries for both Windows and Linux are available on the Github project page: https://github.com/NXPmicro/mfgtools/releases As of this writing, latest release is v1.3.154 so the binaries are: https://github.com/NXPmicro/mfgtools/releases/download/uuu_1.3.154/uuu for Linux https://github.com/NXPmicro/mfgtools/releases/download/uuu_1.3.154/uuu.exe for Windows
Setup your environment
- Windows 10: please install VS2017 Redistribute Package
- Windows 7: please follow the following guide: UUU Win7 User Guide
- Linux: just make sure your udev rules are setup properly, the tool actually tells you what to do:
~/Downloads$ chmod +x uuu
~/Downloads$ ./uuu -udev
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="012f", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="0129", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="0147", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="004f", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="013e", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="0146", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="0076", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="0054", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="0061", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="0063", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="0071", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="007d", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="15a2", ATTRS{idProduct}=="0080", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="0128", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="0126", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="0135", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="0134", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1fc9", ATTRS{idProduct}=="012b", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0525", ATTRS{idProduct}=="b4a4", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0525", ATTRS{idProduct}=="b4a4", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0525", ATTRS{idProduct}=="b4a4", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="3016", ATTRS{idProduct}=="1001", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="3016", ATTRS{idProduct}=="1001", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="066f", ATTRS{idProduct}=="9afe", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="066f", ATTRS{idProduct}=="9bff", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0525", ATTRS{idProduct}=="a4a5", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="0d02", MODE="0666"
1: put above udev run into /etc/udev/rules.d/99-uuu.rules
sudo sh -c "uuu -udev >> /etc/udev/rules.d/99-uuu.rules"
2: update udev rule
sudo udevadm control --reload-rules
Download latest U-Boot binary
Our build server automatically builds latest U-Boot version and shares every binary at this address: http://linode.boundarydevices.com/u-boot-images/ The naming should be explicit enough, for instance the Nitrogen8M board needs the u-boot.nitrogen8m binary. If unsure, please contact us, we will be happy to tell you which binary to use.
Run UUU to recover your device
You can simply run the tool with the binary as its only argument in order to send the bootloader to the device. Here is an example for Nitrogen6x:
~/Downloads$ ./uuu u-boot.nitrogen6q
uuu (Universal Update Utility) for nxp imx chips -- libuuu_1.3.154-0-g47ddef5
Success 1 Failure 0
1:13 2/ 2 [Done ] SDP: done
For i.MX8MQ/M/N, the tool first loads the SPL bootloader, then this latter re-enumerates itself with different USB identifiers. So you can either run the same command twice, or use the tool as a daemon which will automatically detect what to do depending on the USB IDs. Here is an example for Nitrogen8M:
~/Downloads$ ./uuu -d u-boot.nitrogen8m
uuu (Universal Update Utility) for nxp imx chips -- libuuu_1.3.154-0-g47ddef5
Success 2 Failure 0
1:13 3/ 3 [Done ] SDPV: done
Now that your board is booting U-Boot properly, you can then follow this blog post to flash U-Boot into NOR/eMMC: How to Upgrade U-Boot Note that with recent U-Boot (2022.04 and newer), the device will go directly into fastboot mode. At this stage you can either use fastboot to flash your bootloader (for i.MX 8 platforms):
~/Downloads$ fastboot flash bootloader u-boot.nitrogen8m
For Windows users, you can follow this guide on how to setup fastboot. Or you can press Ctrl+C to regain control of the serial prompt to enter any U-Boot you want. As always, let us know your experiences by contacting us or on NXP Community Forum.