uBoot 2014

By default the iMX6 Rex board comes with the default 2009 uBoot. This is now quite old and I had trouble getting certain OS’s to boot. For that and other reasons, its best to upgrade your uBoot to the newest (currently 2014) uBoot.

Content

References

Original Rex uBoot and uImage binaries
http://www.voipac.com/downloads/imx/iMX6_Rex/Module/bin/

Rex Carrier board documents
http://www.voipac.com/downloads/imx/iMX6_Rex/BaseBoard/doc/

iMX6 Rex SOM documents
http://www.voipac.com/downloads/imx/iMX6_Rex/Module/doc/


Booting uBoot from bricked device

As a precursor step, or in case you mess up your upgrade, I will start with the steps to run a uBoot file on your Rex board even if your board is bricked from a bad flash. If you have a usable uBoot that you can get into from your board, you can just skip this step.

Aquiring uBoot image

The first thing you need to do to boot a uBoot image is to get the uBoot image. There are currently 2 I know of.

  1. Original 2009 – Download the binary from http://www.voipac.com/downloads/imx/iMX6_Rex/Module/bin/. Just select the 512MB or 1GB to suit whichever board you have.Optional download: https://www.fasetto.com/file/preview/78d4c3fc420d44c5ae3586332765d5e5
  2. New 2014 – You can either download and build the image from here following the guide here https://github.com/voipac/imx6tinyrex_uboot_v2014_10, or optionally download the pre-built image here https://www.fasetto.com/file/preview/a4968084fc2641848ca1e5ce9b6ce9fd

Preparing USB connector
By default the carrier board has the USB connceted to the main Type A plugs via a USB hub. As most cables are MicroUSB to USB A (like your phone charger) you need to desolder 2 resistors and move them to another location. Alternatively you can just use a USB A to A cable.

  1. Change resistors: Remove the SOM from the carrier board to access the USB0 resistors. Move the resistors over to the left side (closest to the CR coin cell battery) as shown in the manual (http://www.imx6rex.com/download/design-files/imx6_rex__development_baseboard/v1i1/docs/iMX6%20Rex%20Development%20Baseboard%20Manual%20v0.2a.pdf).
  2. Alternative (untested): Get a USB cable that connects to the standard USB-A Plug at both ends so you can connect to the USB stacked connector, such as this http://www.amazon.co.uk/Lindy-31982-Cable-Type-Black/dp/B004V74C02/ref=sr_1_2?ie=UTF8&qid=1441652168&sr=8-2&keywords=usb+a+to+usb+a. I’ve not done it this way so the USB hub may cause issues but I think it will work just fine.

Aquiring the Freescale software
In order to flash directly to the SOM without a working board, you need to use Freescales MfgTools software.

Download MfgTools for iMX6 from http://www.freescale.com/products/arm-processors/i.mx-applications-processors-based-on-arm-cores/i.mx-6-processors/i.mx6qp/i.mx-6-series-software-and-development-tool-resources:IMX6_SW under Manufacturing Tools, or download the fully patched software including all required uBoot images and configuration files from https://www.fasetto.com/file/preview/d69ebd561b1c44aa9828810c8623ddd1
Setting up MfgTools
If you downloaded the patched software you can skip all of these steps.

  1. Extract the MFGTools software and extract it
  2. Copy your desired uBoot image (the 2009 u-boot.bin or the 2014 u-boot.imx) to Profiles/Linux/OS Firmware folder.
  3. Edit the Profiles/Linux/OS Firmware/ucl2.xml file and add a new <LIST> section. It is easy enough to copy and paste eMMC <List> and change the data. In short, you want to a) load uBoot, b) load kernel (zImage), c) load initramfs, d) load device tree and e) jump to the OS image.The only thing that is different from the copy/paste of the eMMC section is you delete all the commands (<CMD> sections) after the Jump to OS command, delete the commands that are not your board (where ifdev isnt the SOM you have, such as ifdev=”MX6SL” is not the Quad core as “MX6Q” is, so I keep the commands that had ifdev=”MX6Q”), then remove the ifdev attributes from the remaing commands.Finally change the location of the first command (the BootStrap command) to the filename of the uBoot image you copied in step 1.Remember to change the name=”" value to a name that makes sense, like RexuBoot-2014.
    <LIST name="RexuBoot-2014" desc="Only boot u-Boot.bin">
        <CMD state="BootStrap" type="boot" body="BootStrap" file ="u-boot-2014.imx" >Loading U-boot</CMD>
    	<CMD state="BootStrap" type="load" file="firmware/zImage" address="0x12000000" loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE">Loading Kernel.</CMD>
    
    	<CMD state="BootStrap" type="load" file="firmware/fsl-image-mfgtool-initramfs-imx6qdlsolo.cpio.gz.u-boot" address="0x12C00000"
    		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE">Loading Initramfs.</CMD>
    
    	<CMD state="BootStrap" type="load" file="firmware/zImage-imx6q-%board%.dtb" address="0x18000000"
    		loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE">Loading device tree.</CMD>
    
    	<CMD state="BootStrap" type="jump" > Jumping to OS image. </CMD>
    </LIST>
    
  4. Whatever name you gave above, in this example RexuBoot-2014, change the name= value inside the cfg.ini file inside the root of the MFGTools folder to that name.
    [profiles]
    chip = Linux
    
    [platform]
    board = SabreSD
    
    [LIST]
    name = RexuBoot-2014
    
    [variable]
    board = sabresd
    mmc = 0
    sxuboot=17x17arm2
    sxdtb=17x17-arm2
    ldo=
    

    I would recommend if you are first recovering from a total brick to flash the original uBoot on, then you can always flash the newer uBoot in the next step.

Pushing uBoot to device
With MfgTools setup you are ready to push your desired uBoot file to the SOM.

  1. Open up MfgTool2.exe and plug in the USB cable to the computer from the carrier board.
  2. Move the jumper from JP1 to JP2 on the carrier board. This tells the USB to act as a device (because JP1 is now open) and tells the board to go into boot loader mode (because JP2 is now closed). Take a look at the manual http://www.imx6rex.com/download/design-files/imx6_rex__development_baseboard/v1i1/docs/iMX6%20Rex%20Development%20Baseboard%20Manual%20v0.2a.pdf for the location.The JP1 is the jumper with the black jumper connected to it to the left of the CR coin battery directly below 2 3-pin black headers.JP2 is the one below that. So just remove the jumper from JP1 and put it on JP2.
  3. Plug in the USB cable from the carrier board to the computer. The MfgTool should detect it as a HID device.
  4. Have the RS232 DB9 cable connected to the board and PC with a serial terminal open so you can control the uBoot when it starts, as well as see any progress and error messages.
  5. Click Start on MfgTools and it will start to go through the steps. While that is running get ready and monitor the serial port for the uBoot messages. When it gives you the countdown on the serial terminal press any key to stop it so you can type uBoot commands.
  6. Once successfully back into uBoot, first go back to MfgTool and click Stop, or unplug the USB, otherwise when the device reboots MfgTools will instantly start reflashing uBoot to the RAM.

Congratulations! You now have a usable uBoot running on your device. Proceed to the next step to permanently flash a new uBoot to the devices SPI memory.

Flashing a new uBoot to SPI Memory

To flash the uBoot to the on SPI memory of the Rex so its always there without having to repeat these steps, you use the same uBoot file as above, but now you have to program the SPI memory.

Every tutorial I found used a complicated Tftp method meaning you had to have the carrier board, an Ethernet cable, a router, Tftp software installed and configured on your PC, and a lot more time than the method I now use.

I will start with the super fast method which means you need nothing more than a microSD card.

Method 1: Flashing via SD

Both methods use the same steps, except for one, which is loading the uBoot data into the RAM so it can be copied over to the SPI memory. I’ll explain what each line of code does as I go.

Firstly, insert the microSD card into your PC and copy the desired uBoot file (the .bin or .imx) onto the SD card. The card should be ext2 formatted. As a quick guide on how to do this, if you are running linux on your actual PC with the SD card inserted do this:

  1. Find which device the SD card is via lsblk. It should be something like /dev/sdb. You can tell by the size of the device, or by removing the device, running lsblk, plugging the SD card back in and running it again to see what appears.
  2. Format the SD card and create a single ext2 partition. REMEMBER: Change sdb to the correct device found from step 1. Entering the wrong value here can wipe your entire machine.
    $ parted /dev/sdb
    (parted) mklabel msdos
    (parted) mkpart primary 1MiB 100%
    (parted) quit
    $ mkfs.ext3 /dev/sdb1
    
  3. Mount the new partition to a folder of your choice (in this case a new folder I made inside of /mnt called root) and copy the uBoot file over to it. Note my uBoot image is stored in my Home directory in this example (~ is a shortcut to your home folder)
    sudo mkdir /mnt/root
    sudo mount /dev/sdb1 /mnt/root
    sudo cp ~/u-boot-2014.imx /mnt/root
    sudo sync
    sudo umount /mnt/root
    

    Now you have an Ext3 formatted SD card with the uBoot image on.

Next, insert the microSD card containing your desired uBoot file into the carrier board and boot your board up into uBoot.

Type all of the below into the uBoot terminal:

First, fill the RAM with 0xFF’s for 512kb (0×80000 = 524288 bytes), at the location 0×10800000. We use this location in RAM to store the uBoot. I think this location could vary, but this is what is used on the official website so we will stick to that.

mw.b 0x10800000 0xFF 0x80000

Next, we load the uBoot data into memory from the microSD card. If you currently have the 2009 uBoot running then you want to use mmc 1, however if you are running the 2014 uBoot you want mmc 0. The below example presumes you are currently running 2009 uBoot.

ext2load tells uBoot to load data from an ext2 formatted device (the ext3 partition we made is fine as its backwards compatible) into the RAM, at location 0×10800000, from the mmc device 1 (or 0 if you are running uBoot 2014 already), and to read the data into RAM at 0×10800000. The data comes from a file on partition 1 of that device named u-boot-2014.imx.

mmc dev 1
ext2load mmc 1 0x10800000 u-boot-2014.imx

We have the RAM containing our uBoot image, we need to write it to the SPI memory. To do that first select the 2MB section of RAM where uBoot should be flashed. If you are running uBoot 2009 then it is section 3:2, if you are running 2014 it is section 2:2.

sf probe 3:2

Erase the current contents of the memory for 512kb (0×80000) starting at location 0 (0×0) (once you run this step, if you power off or restart you will have a bricked device so would have to follow the steps above for recovery).

sf erase 0x0 0x80000

Finally, write the new uBoot data from RAM that is stored at 0×10800000 into the SPI memory.

If you are flashing the 2009 uBoot (u-boot-2009.bin), you write it at 0 offset (0×0) and a length of the full 512kb (0×80000). If you are flashing the newer 2014 uBoot (u-boot-2014.imx) then you write it at offset 1kb (0×400) and for 511kb (0x7fcc00).

If 2009:
sf write 0x10800000 0x0 0x80000

If 2014:
sf write 0x10800000 0x400 0x7fc00

To confirm it went ok, just reset the device by typing reset or just toggling the power. If all went well, you should now have your new uBoot on the device.

NOTE: If you updated to 2014 uBoot from the 2009, there are a few notes:

  • Before you can boot any kernel you must update the boards machine ID. The 2009 uBoot was built for the imx6sabresd machine ID (?), whereas the uBoot for 2014 is built for the imx6rex machine ID (f8c).So to update the machine ID run the following just once. If you do not do this then all boots will hang at the “Starting Kernel…” stage.
    setenv machid f8c
    saveenv
    reset
    
  • The first time you reboot you will get an SF: error message regarding a bad CRC in memory. This is just because there has not been any environment data saved yet. Simply type saveenv and the error will no longer occur.
  • If you access the uBoot SPI memory location from now on it is sf probe 2:2, instead of sp probe 3:2.
  • If you access mmc the location is now mmc 0 instead of mmc 1

If anything went wrong you will likely have to start from the recovery steps above to get back to a uBoot and try again.

Method 2: Flashing via Tftp

There is really no reason to use the Tftp to flash the uBoot image when the USB steps above are much shorter. However if you still want to use Tftp here is how.

TODO