i.mx USB loader A white paper by Tristan Lelong Introduction This document aims to explain the serial downloader feature of i.mx SoCs on Linux (available across i.mx family starting with i.mx23). This process can be challenging for newcomers and this whitepaper intends to give a detailed explanation of how to leverage this functionality describing the work happening on both the host and target side. This document will also provide ready-to-use examples as well as typical use cases. These directions apply to the i.mx6q SABRE Lite platform but can be easily adapted to any other hardware design with little to no modification. Serial downloader mode on SoC The i.mx SoC includes a specific boot mode called serial downloader. In this mode, the internal ROM code is able to enumerate over the USB OTG port as a Freescale device in recovery mode and receive commands from an external application. On windows, the Manufacturing tool uses this feature to flash the bootloader and operating system images on the board s internal memory. On Linux, the imx_usb_loader open-source project can be used to achieve a similar goal. Boot modes of IMX The i.mx SoC can boot from various media: internal NOR (WEIM) / NAND (GPMI) serial ROM (I2C / SPI) external emmc / SD card / HDD / SDD Serial Downloader Those boot modes are selected using a value which is flashed in a specific fuse (no modification is allowed afterwards), or using GPIO boot pins otherwise (typically available through boot switches). Please refer to the appropriate i.mx SoC reference manual for more information regarding all available configurations. Serial downloader protocol Your system may be configured to boot on a particular media which may not contain a valid boot image (possible due to a flashing error or memory corruption for instance). In this scenario, it might be hard or impossible to get your device to boot again without having to use a JTAG probe. This is one case where the serial downloader mode becomes particularly handy. When configured correctly, the ROM code will poll for a connection on the USB OTG port (for 32 seconds only, if watchdog is enabled within fuses), and enumerate itself as a "Freescale Semiconductor, Inc" device (VendorID 0x15A2) as
soon as a USB host is connected. Once a connection is made on the USB OTG port, the ROM exports 4 HID endpoints described in the table below: Id Type Size Description 1 Control 17 bytes Commands form host to device 2 Control 1025 bytes Data associated with commands 3 Interrupt 5 bytes HAB security configuration 4 Interrupt 65 bytes Target answer The serial downloader protocol (SDP) describes several commands: Read register (0x0101) Write register (0x0202) Write file (0x0404) Error status (0x0505) DCD write (0x0A0A) Jump to address (0x0B0B) We will focus here on the Write file, DCD write, and Jump to address commands since these are the ones responsible for loading and booting the board. For those specific commands, the protocol requires an address (internal / external RAM) and a data count (not used for Jump to address). Boot modes on SABRE Lite The SABRE Lite board exposes 2 boot switches allowing for 4 different boot modes: 00: Boot from fuses: selects the boot media from fuses only 01: Serial downloader 10: Internal boot: load the system from GPIO pin configuration or boot fuses if these are burnt. 11: Reserved In order to use the serial downloader, these boot switches need to be set to 01. Once set up, plug a micro USB cable into the USB OTG connector and run the lsusb command on your host machine:
$ lsusb [...] Bus 002 Device 008: ID 15a2:0061 Freescale Semiconductor, Inc. [...] Imx_usb_loader Project Imx_usb_loader The imx_usb_loader project is developed by Boundary Devices and provided under the GPLv3 license and is available as a source package on github: https://github.com/boundarydevices/imx_usb_loader/https://github.com/boundarydevices/imx_usb_loa der This program is composed of a single C source file called imx_usb.c. This application will parse various configuration files and generate command packets following the SDP. The communication part relies on libusb to interface with the 4 endpoints exported by the i.mx SoC, therefore imx_usb_loader requires libusb-dev as a dependency. After installing libusb-dev on your system, proceed with the following commands to get and compile imx_usb_loader: $ git clone https://github.com/boundarydevices/imx_usb_loader.git $ cd imx_usb_loader $ make [edit configuration files] $ sudo./imx_usb To edit configuration files, refer to section 3.2 Configuration files. Upon starting, imx_usb will identify your device using the matching VendorID/ProductID pair, and load the corresponding configuration file which depends on the master configuration file called imx_usb.conf. The application will then parse the specific configuration file to build and send commands to the target. Configuration files The configuration files use a set of commands which maps to the SDP. Some of the provided files are commented and may help understanding the role of these commands. SDP command Read register imx_usb command read
Write register Write file Error status DCD write Jump to address modify load N/A dcd jump The configuration file parser will ignore empty lines or comments (the # sign is used to comment a full line). The first valid line of the configuration file should start with the name of the USB board attached - this is used only for debugging purposes and this string can be specified as any identifier (with a maximum of 63 bytes). The second line is a comma separated list of parameters that must describe the board: type: hid / bulk header: old_header [this parameter is optional and is used for i.mx51 and earlier SoCs] packet size: maximum size of data packets (default is 1024) RAM description: up to 8 RAM areas described with <ram start address>,<ram size> Example: # Board ID Sabrelite # Board Description hid,1024,0x10000000,1g,0x00907000,0x31000 Commands can be added after the device description - the next section describes the syntax of these commands. RAM initialization dcd command This line should start with the name of the file containing the DCD table, followed by a colon sign and the dcd keyword. When working with u-boot, the DCD table is usually present in the header of the u-boot binary: u-boot.bin:dcd Uploading binary files This line should start with the name of the file to upload to the board, followed by a colon sign, the load keyword, and the target RAM address to load the file into.
u-boot.bin:load 0x27000000 Jumping to an address This line should start with a file to load and to jump to, and takes one of the following as an argument: header: uses the first IVT header header2: uses the second IVT header nnn: the offset in the file to jump to Since the jump command can load any file, you may use this command to load a bootloader, initialize memory (granted it contains a DCD table such as u-boot for instance), and start execution. u-boot.bin:dcd,jump header Note: The u-boot binary for i.mx SoCs is compiled with an embedded IVT header embedded (sometimes padded) describing the DCD address, the load address, the entry point and several other pieces required by the boot ROM. Typical Usage & examples Automated "factory" flashing Choosing the right technologies to flash a complete system during manufacturing is not always straightforward - for instance, flashing each board with a JTAG can be time consuming. The serial downloader feature can therefore be put to good use and make this process very efficient. Even when fuses are programmed to boot from internal memory (for security reasons), the initial boot can be configured to use the serial downloader to load a single piece of software which will be responsible for flashing the entire device (maybe using a custom u-boot with the appropriate bootcmd for this task). u-boot.flash environment : flash_linux=nand write 0x10A00000 kernel 0x400000 flash_uboot=nand write 0x10800000 bootloader 0x40000 bootcmd=run flash_uboot; run flash_linux; reset; mx6_usb_work.conf : # Load the target u-boot u-boot.bin:load 0x10800000 # Load the target uimage uimage:load 0x10A00000 # Load and jump on the u-boot flasher u-boot.flash:dcd,jump header
Development process The serial downloader mode can also be useful for kernel / bootloader development. As a matter of fact, one just needs to modify the appropriate configuration file to target the output of their builds and the target will automatically boot and download the latest version of the binaries produced with no further action needed other than running the imx_usb tool. This process significantly decreases the testing time required for flashing new binaries to a board, thus increasing overall development productivity. If a board becomes unusable or "bricked", this also becomes an extremely valuable tool as it only relies on the ROM code execution. About Adeneo Embedded Adeneo Embedded provides system integration, design, support and training services to companies seeking world-class expertise in embedded solutions using high-performance architectures. For over 10 years, Adeneo Embedded has helped clients, in all stages of development; create profitable, feature-rich products that incorporate software and hardware solutions based on Android, Embedded Linux, Windows Embedded or Windows Mobile operating systems. Close working partnerships with industry-leading silicon and software vendors allow Adeneo Embedded to apply its experience to a wide range of embedded solutions for the automotive, industrial, medical, multi-media, navigation, networking, mobile and wireless markets. Adeneo Embedded has a global sales and support network backed by engineering offices in North America and Europe.
ADENEO EMBEDDED NEWS RELEASE June 14 th, 2012 Further information For more information about Adeneo Embedded competences, products and services around Windows Embedded technologies: visit Adeneo Embedded dedicated web site www.adeneo-embedded.com Adeneo Embedded General sales contact sales@adeneo-embedded.com For a local contact in Europe, please contact Jeremy Delicato America, please contact Mike Ruiz jdelicato@adeneo-embedded.com mruiz@adeneo-embedded.com Adeneo Press Contacts Valerie Cote Executive Assistant, Adeneo Embedded (EU) Phone +33 426-492-539 E-mail vcote@adeneo-embedded.com Kathleen Wright Office Manager, Adeneo Embedded (USA) Phone +1 (425) 749-4335 E-mail kwright@adeneo-embedded.com End