June 13, 2012

Running Linaro Ubuntu on i.MX6 (Sabre Lite and Nitrogen6X)

As mentioned in our post about BSPs for i.MX, there is a lot of motion on a number of projects in the i.MX world.

In this post, we’ll give a primer on how to get started with a Linaro Ubuntu image on a Sabre Lite or Nitrogen6X board.

For the impatient:

I’ll elaborate below, but if you want to boot a Linaro image on a Sabre Lite or Nitrogen6X, you can follow these simple steps:

On your host machine, grab the latest copies of the mx6 hardware pack and a filesystem image and use linaro-media-create to program your SD card:

~/linaro$ wget http://releases.linaro.org/latest/ubuntu/precise-hwpacks/hwpack_linaro-lt-mx6_20120525-101_armhf_supported.tar.gz
...
`hwpack_linaro-lt-mx6_20120525-101_armhf_supported.tar.gz' saved [26644843/26644843]

~/linaro$ wget http://releases.linaro.org/latest/ubuntu/precise-images/ubuntu-desktop/linaro-precise-ubuntu-desktop-20120524-177.tar.gz
...
`linaro-precise-ubuntu-desktop-20120524-177.tar.gz' saved [517238017/517238017]

~/linaro$ sudo linaro-media-create --mmc /dev/mmcblk0 --dev mx6qsabrelite 
          --hwpack hwpack_linaro-lt-mx6_20120525-101_armhf_supported.tar.gz 
          --binary linaro-precise-ubuntu-desktop-20120524-177.tar.gz
[sudo] password for user:
...
I see...
Device           Mount point      Size
/dev/mmcblk0     none             3823MB
/dev/mmcblk0p1   none             3MB
/dev/mmcblk0p2   none             52MB
/dev/mmcblk0p3   none             3767MB
/dev/sda         none             476940MB
/dev/sda1        /                230039MB
/dev/sda2        none             8432MB
/dev/sda3        /olddrive        238464MB
/dev/sda5        none             8432MB
/dev/sr0         none             0MB
Are you 100% sure, on selecting [/dev/mmcblk0] (y/n)? y
...
WARNING: The following packages cannot be authenticated!
  libnl-3-200 libnl-genl-3-200 wireless-regdb crda wireless-crda linux-image-3.2.1-42-linaro-lt-mx6 devio flash-kernel linux-firmware linux-image-linaro-lt-mx6
  linux-headers-3.2.1-42-linaro-lt-mx6 linux-headers-linaro-lt-mx6 hwpack-linaro-lt-mx6 iw u-boot-tools uboot-mkimage
Install these packages without verification [y/N]? y
...
Populating rootfs partition
Be patient, this may take a few minutes

... long time passes...

Updating /etc/network/interfaces

Done creating Linaro image on /dev/mmcblk0

Insert this into mmc 0 (top slot of a Nitrogen6X or the bottom full-sized slot on a Sabre Lite) and abort the boot through the serial console.

Enter these commands to set the boot mode to SDHC3 (mmc 0) and reset:

U-Boot> mw.l 0x020d8040 0x3040 && mw.l 0x020d8044 0x10000000
U-Boot> reset

The details

The first difficulty you’re likely to encounter is that the Linaro team creates an SD card image that’s inconsistent with what we ship. In particular, they create SD card images that have an unformatted first partition to hold a U-Boot image and a boot script named boot.scr in partition number 2.

The second difficulty is that the kernels Linaro is shipping are configured to support a device tree, which is not supported in the Freescale (or Boundary Devices) U-Boot releases. This part will be remedied as soon as we make the switch to main-line U-Boot. Stay tuned for updates.

In other words, in order to launch the Linaro build, we need to run Linaro’s U-Boot instead of booting first to serial EEPROM. On the Linaro Sabre Lite Wiki Page, they describe one method of getting around this, but it’s a bit intrusive. It suggests that you re-program your serial EEPROM with a shim.

An easier way

Thankfully, Troy found an easy work-around while creating a U-Boot command rstmode (or rsmode).

It turns out that with just a couple of register writes, you can set the boot mode (overriding the fuse settings) and force a boot to SD card, USB, NAND, et cetera.

The following is a rather lengthy example run on a Nitrogen6X. I aborted the initial boot of 2009.08-00495-g10adc6d by hitting the any key, then issued a command line with a couple of register writes (mw), followed by a reset.

U-Boot 2009.08-00495-g10adc6d (Apr 24 2012 - 13:27:04)

CPU:   Freescale i.MX 6 family 0.0V at 792 MHz
Temperature:   can't get valid data!
mx6q pll1: 792MHz
mx6q pll2: 528MHz
mx6q pll3: 480MHz
mx6q pll8: 50MHz
ipg clock     : 66000000Hz
ipg per clock : 66000000Hz
uart clock    : 80000000Hz
cspi clock    : 60000000Hz
ahb clock     : 132000000Hz
axi clock   : 264000000Hz
emi_slow clock: 29333333Hz
ddr clock     : 528000000Hz
usdhc1 clock  : 200000000Hz
usdhc2 clock  : 200000000Hz
usdhc3 clock  : 200000000Hz
usdhc4 clock  : 200000000Hz
nfc clock     : 24000000Hz
Board: MX6Q-SABRELITE:[ POR]
Boot Device: I2C
I2C:   ready
DRAM:   1 GB
MMC:   FSL_USDHC: 0,FSL_USDHC: 1
JEDEC ID: 0xbf:0x25:0x41
Reading SPI NOR flash 0xc0000 [0x2000 bytes] -> ram 0x276009b8
SUCCESS

In:    serial
Out:   serial
Err:   serial
Checking for recovery command file...
** Bad partition 6 **
Card did not respond to voltage select!
** Bad partition 6 **
MMC Device 2 not found
MMC Device 2 not found
** Block device MMC 2 not supported
Net:   got MAC address from IIM: 00:19:b8:00:eb:59
FEC0 [PRIME]
Hit any key to stop autoboot:  0
MX6Q SABRELITE U-Boot >
MX6Q SABRELITE U-Boot >
MX6Q SABRELITE U-Boot >
MX6Q SABRELITE U-Boot > mw.l 0x020d8040 0x3040 && mw.l 0x020d8044 0x10000000
MX6Q SABRELITE U-Boot > reset
resetting ...

U-Boot 2011.12 (Apr 08 2012 - 04:54:32)

CPU:   Freescale i.MX61 family rev1.0 at 792 MHz
Reset cause: unknown reset
Board: MX6Q-Sabre Lite
DRAM:  1 GiB
WARNING: Caches not enabled
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   FEC
Hit any key to stop autoboot:  0
MX6QSABRELITE U-Boot >
MX6QSABRELITE U-Boot >

After the reset, you should notice that we’re actually running the Linaro version of U-Boot 2011.12 (Apr 08 2012 - 04:54:32).

In this example, I hit the any key. If I hadn’t, the Linaro startup would have continued to boot the nano image I had loaded in the top SD card slot of my Nitrogen6X.

In order to boot the bottom slot, I need to set different values:

U-Boot 2009.08-00495-g10adc6d (Apr 24 2012 - 13:27:04)

CPU:   Freescale i.MX 6 family 0.0V at 792 MHz
Temperature:   can't get valid data!
...
Environment size: 1101/8188 bytes
MX6Q SABRELITE U-Boot > mw.l 0x020d8040 0x3840 && mw.l 0x020d8044 0x10000000
MX6Q SABRELITE U-Boot > reset
resetting ...

U-Boot 2011.12 (Apr 08 2012 - 04:54:32)

CPU:   Freescale i.MX61 family rev1.0 at 792 MHz
Reset cause: unknown reset
Board: MX6Q-Sabre Lite
DRAM:  1 GiB
WARNING: Caches not enabled
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
MMC init failed
Using default environment
...

MX6QSABRELITE U-Boot > set hello world
MX6QSABRELITE U-Boot > savee
Saving Environment to MMC...
MMC init failed
MX6QSABRELITE U-Boot >

Note that the Linaro U-Boot expects to store its’ environment variables on SDHC3, or mmc 0 in U-Boot naming. This is the top slot on a Nitrogen6X and the bottom (full-sized) SD card slot on a Sabre-Lite, so we received two error messages (MMC init failed) when U-Boot tried to load and save the environment.

Also note that the boot mode is somewhat sticky. If you use U-Boot’s reset command or reboot from Linux, you won’t see the 2009.08 version of U-Boot execute. In order to get back to the original, use the power-key or reset button.

While we’re working to get to mainline and pushing the rstmode patch through the process, we added a couple of convenience commands to our local U-Boot tree.

This makes the process much simpler:

MX6Q SABRELITE U-Boot > run bootsd0
resetting ...

U-Boot 2011.12 (Apr 08 2012 - 04:54:32)

CPU:   Freescale i.MX61 family rev1.0 at 792 MHz
Reset cause: unknown reset
Board: MX6Q-Sabre Lite
DRAM:  1 GiB
...