Board Bring-Up of the i.MX6 Saber Lite

I received a bricked Saber Lite board as a gift. Before I could do anything useful with it, I had to get it to boot.

I’ve always been attracted to new bright shiny things. And there’s nothing like a fresh technical challenge to get me fired up. In this instance, a colleague at the office handed me a Boundary Devices Saber Lite demo board to play with – the only problem is, it was completely bricked. It would not boot at all. When I plugged it in, the 5V DC LED would light up, but nothing else happened. No output came from the serial port. Even the reset button would not work. It seemed like it was dead! My undertaking was to see if I could get it to boot, and then do some interesting things with it – using SourcePoint to debug source/symbols is one thing to try. We also have some JTAG-based ScanWorks test and programming tools that work with the i.MX6 CPU on this board. The fun part about this is that I could use the same tools to test and debug the board as well as play with it. And at the same time learning more about embedded development, U-boot, Arm firmware, and other technical topics. So, I got started right away!

The Saber Lite board is an older kit. I think that it dates back to 2012 or so. The documentation on it seems to be not as thorough as what I’ve seen, for example, on the MinnowBoard. And, to make matters worse, it goes by several names: Saber Lite, Sabre Lite, BD-SL-i.MX6 (this is the Boundary Devices version of the board), etc.; and it is part of the NXP Nitrogen6 family of boards. I bring this up because Googling information on other peoples’ experiences with the board is quite difficult. Google does a good job of helping me find what I’m looking for, but I could be missing some key material by not putting in the right search terms. That’s what happens when the marketing branding police run amok.

But, be that as it may. It’s a pretty cool design nonetheless. It comes equipped with a four-core NXP i.MX6Quad processor, 1GB DDR3, 2MB SPI NOR flash, and Ethernet, USB, SATA and HDMI. Here’s what it looks like, top view:

Saber Lite picture

And the block diagram is below:

SABER Lite Block diagram

Given that the board is bricked and will not boot or output anything to the console, I had no idea what might be wrong. There could be a board hardware problem; maybe the bootROM in the CPU is corrupted; maybe the SPI flash somehow got blown; maybe the serial port is defective and won’t output anything; it could be anything. So, I decided to go through a methodical board bring up approach, to isolate the fault, and get the board up ASAP so I could play with it.

So, the first thing I did was to connect our SourcePoint JTAG-based debugger, and halt the i.MX6 CPU as it was sitting there powered up. I saw the following:

SourcePoint Sabre Lite another halt

I can see that the i.MX6 CPU is operational. It is fetching instructions, and in a tight loop near the reset vector, not too far from the x’00000000’ bootROM start address.

I single-stepped the code to see what it was doing. In fact, the CPU is in a tight loop that I’ve reconstructed below:

00000FB8 2000       MOVS      R0,#00

00000FBA f8d1 1144  LDR.W     R1,[R1,#144]

00000FBE 0649       LSLS      R1,R1,#19

00000FC0 d500       BPL       00000fc4

00000FC4 4770       BX        LR

00000CFC 2801       CMP       R0,#01

00000CFE d100       BNE       00000d02

00000D02 4620       MOV       R0,R4

00000D04 bd10       POP       {R4,PC}

0000270E 2801       CMP       R0,#01

00002710 d1fb       BNE       0000270a

0000270A f7fe faf3  BL        00000cf4

00000CF4 b510       PUSH      {R4,LR}

00000CF6 2400       MOVS      R4,#00

00000CF8 f000 f95d  BL        00000fb6

00000FB6 49ae       LDR       R1,00001270 (02184000)

The last LDR instruction resumes the loop back at address 00000fb8.

Now, I have a workingman’s knowledge of x86b assembler, but Arm assembler is still somewhat new to me. I think that I’m somewhere in the on-chip ROM, based on the reference from https://community.nxp.com/thread/328204:

I think the semi-official method on the i.MX6 series is to force the device into serial bootloader mode (BOOT_MODE0 == 1, BOOT_MODE1 == 0), leaving the USB port unconnected.  When halt finally takes effect, the PC will be in the on-chip ROM waiting for a USB connection.

So, I’m guessing here, but I think that’s what it’s doing. In any event, I’m reassured that at least the CPU is operational.

I next decide to try to load u-boot on the platform. By hooking up to the serial port with PuTTY, I’ll be able to see what’s going on; maybe the board is working fine, but the SPI flash contains nothing useful.

Rather than use one of the pre-fabricated u-boot images, I wanted to build it myself. Good instructions are here, but they are incomplete. Here are the steps I used on my Linux (Ubuntu 16.04 LTS) machine:

$ sudo apt-get install gcc-arm-linux-gnueabihf bison flex

$ git clone https://github.com/boundarydevices/u-boot-imx6 \

    -b boundary-v2018.07

$ cd u-boot-imx6

~/u-boot-imx6$ sudo apt-get install crossbuild-essential-armhf

~/u-boot-imx6$ export ARCH=arm

~/u-boot-imx6$ export CROSS_COMPILE=arm-linux-gnueabihf-

~/u-boot-imx6$ make nitrogen6q_defconfig

~/u-boot-imx6$ make -j2

That filled the u-boot-imx6 directory with the needed binaries:

Uboot needed binaries

I did some homework and realized that the u-boot.imx file is the key one to use.

Here is where it got a little tricky. There are several ways to u-boot the Saber Lite:

  1. From the SPI flash.
  2. From the SD card.
  3. From the USB OTG port.

Obviously, #1 isn’t working, otherwise the board would be booting already. So, I decided to try #2. But, the documentation is a little fuzzy here (at least, I thought it was). The Saber Lite has a slot for a full-size SD card on the bottom of the board, but there’s also a MicroSD slot that has the label “SD4/BOOT” next to it. I decided to use the latter (probably a good choice!), and burned the image onto a MicroSD card using:

$ sudo dd if=/home/alan/u-boot-imx6/u-boot.imx of=dev/sdf1 bs=1k seek=1 conv=fsync

Note: I had to use the Linux “lsblk” command to determine which “sdx” device (in this case sdf1) the USB port to write to – being very careful of course! Also, I placed the MicroSD card within a MicroSD Adapter card, and plugged that in turn to an SD-to-USB adapter so I could write to the card.

Alas, when I tried to boot from the MicroSD card, it didn’t work! Nothing came out of the serial console.

I’m probably doing something wrong. For future reference, the DIP switch settings which determine “boot mode” are a little ambiguous. If you look carefully at the board, you see two tiny switches:

Saber Lite DIP switch

And the settings are:

00 FUSES

01 USB OTG

10 INTERNAL

I’m not clear if ‘00’ or ‘10’ cause the board to boot from the MicroSD card. I tried them both – or, at least I think I did, with no luck. I probably did something wrong – perhaps the image did not burn properly – I’ll be trying this again later.

In the meantime, I decided to try #3 above. I set the switches to 01. This boots from the USB OTG port – a little MicroUSB jack on the side of the board.

On my Linux machine, I entered these commands:

~$ git clone git://github.com/boundarydevices/imx_usb_loader

~$ cd imx_usb_loader/

~/imx_usb_loader$ make

And the make was successful. The imx_usb executable was created, which is used to load the u-boot image over the USB OTG interface into RAM.

I then copied the u-boot.imx image file that I built earlier into the imx_usb_loader directory, and then, with my PC USB cabled up to the MicroUSB OTG port, typed:

~/imx_usb_loader$ sudo ./imx_usb u-boot.imx

And that worked too! Here’s the output:

Imx usb loader

And, simultaneously, PuTTY displayed the u-boot being loaded into RAM (actually On-Chip Memory (OCM) I think) and executing:

U-boot on PuTTY

It works! This made me very happy.

Next time, I will update the SPI flash, if possible, so I don't have to load in the image over the USB OTG connection every time.

Want to learn more about u-boot and how to eliminate its requirement for board bring-up? Larry Osborn’s blog Using u-boot as a production test strategy – Really? is a good read.

Alan Sguigna