fastboot

FastBoot protocol is a tool developed for Android, which allows for communicating with bootloaders over USB or Ethernet.

U-Boot configuration

U-Boot fastboot documentation suggests to set CONFIG_USB_GADGET_(VENDOR_NUM|PRODUCT_NUM|MANUFACTURER). Note that USB_GADGET_VENDOR_NUM and USB_GADGET_PRODUCT_NUM is not related to your actual board, rather it is some dummy id of device which is compatible with fastboot. In this case it is CelkonA88 device from Google.

Fastboot client

Install fastboot (on Debian-based distros): sudo apt install fastboot. Installation for other popular distros should be straightforward as well.

First test – U-Boot from SD card

The purpose is to confirm that fastboot command is there and that we can establish a connection with fastboot client. U-Boot fastboot Documentation suggests that we only need to execute fastboot command in U-Boot prompt. Notice that now this command requires a parameter:

USB_controller parameter is not that well documented, but it looks like that it is USB controller number. What is odd is that providing any character as this parameter results in no error message and allows to establish successful connection:

After running fastboot on HB, you should see new USB device enumerated on host:

We can add another udev rule at this point in order to use fastboot command without the need of root privileges:

Following command should return available fastboot devices:

output:

This one should return bootloader version:

output:

Second test – U-Boot from DRAM

In order to enable fastboot support I needed to change USB_GADGET VID / PID in U-boot configuration. It means that our imx_usb_loader configuration files needs an adjustment. imx_usb.conf file needs following content:

Above change is introduced in this commit. Notice that PID in the second entry is not the same as was set in U-Boot configuration. This is the same issue as presented in case of SDP USB gadget device: detected PID in SPL mode is a little bit different than the one set in the configuration.

However, once U-boot gets loaded and we enter fastboot 0 in prompt, it gets back to the correct one:

Let’s try if communication over fastboot protocol is working in this case as well:

output:

Enter fastboot mode by default

To automate things, we should force U-Boot to enter fastboot mode automatically on boot. At first, fast and easy way that came to mind mind was to edit distro_bootcmd variable content:

A more elegant way would be to set BOOTCOMMAND config options in configs/mx6cuboxi_fastboot_defconfig instead:

To speed things up, it is worth to reduce boot delay to 0 by setting configuration option:

Using fastboot flash command

By default fastboot uses GPT partition name as a parameter. Antoine from Bootlin in his post provides an U-Boot patch with workaround which allows to pass eMMC offset address instead.

It’s been a while since it was published and it no longer applies due to the changes in U-Boot source code. I have decided to update it and it can be found in the 3mdeb fork of U-Boot.

Summary

  • I’ve also run into some inconsistencies in U-Boot code vs documentation. I will try to see what’s going in the code and update the doc if possible.
  • U-Boot target configuration for Hummingboard Edge with fastboot support as described above is available in 3mdeb fork of U-Boot.

Booting from eMMC

eFUSE settings

Note that, in order to boot from eMMC, you need either unfused SoM or fused to boot from eMMC. Jumper settings for boot selection can be found at Edge/Gate Boot Jumpers section of SolidRun Hummingboard wiki page. Fusing instructions to boot from eMMC can be found at Blowing fuses to from eMMC (HummingBoard2 eMMC or MicroSOM rev 1.5 on-SOM eMMC) section of SolidRun wiki eFuses page.

You can check fusing settings with:

In above example, it is fused to boot from uSD card, and cannot be overwritten by GPIO settings. It means that this particular SoM cannot be set to boot from eMMC anymore.

In my case SoM on HummingBoard2 is fused to boot from uSD card, so I will not be able to present booting from eMMC on HummingBoard2 at the moment, but we have Vitro Crystal boards, which is based on the same SoC. It’s not fused, so I will continue with this board, but process is the same on HummingBoard2. As I said, this board is not fused and below values confirms it.

Image flashing

I’m mostly using Yocto for the builds. Thanks to wic I can get one output image file with already created desired partition layout.

We should also keep in mind that a single file send via fastboot protocol cannot be larger that the buffer size. Size of the buffer is set via CONFIG_FASTBOOT_BUF_SIZE U-Boot configuration option. In our case it was set to 512 MB. Of course it needs to fit into device’s memory.

Regarding that we have modified fastboot to take eMMC offset as an argument, I can see two potential ways of flashing an image.

Image decomposition

We can send each of the components one by one. An example could look like: MBR sector, bootloader, rootfs 1, data partition.

We can extract MBR from image file:

We can verify it’s MBR by looking at it’s hexdump: hexdump mbr.img

dump output:

For example, in this case the fist partition is marked as boot partition (0x80 as first byte of partition description):

The others are not (0x00 instead).

Each MBR should also end with two bytes (0x55AA):

Let’s check the partition table on the eMMC by booting from uSD card before flashing the mbr.img:

Like you can see above, there are no partitions yet. Let’s flash mbr.img on eMMC using fastboot:

host output:

target output:

Now let’s verify the partition table on the eMMC again:

We can see that MBR was flashed correctly to eMMC:

Now we should continue with flashing U-Boot and partitions.

The drawbacks I can see are:

  • We would need to decompose disk image which is already assembled by the build system.
  • We would need to compute offset of each component to pass as a fastboot command argument. They may change over time.
  • Partitions size may be grater than possible buffer size.

Image splitting and flashing

The other idea is to split whole image file into data chunks of size not grater than the fastboot buffer size. This way we can keep all the image layout information exclusively in the build system. We can use split tool for this:

In this case, size of core-image-minimal.wic is about 620M, so there will be two chunks only: image.00 and image.01

flash first chunk:

host output:

flash second chunk:

target output:

host output:

System booting from eMMC

Booting from eMMC has been successfully completed 🙂 Like you can see below root filesystem is mounted on /dev/mmcblk1p2:

The flashing and booting output log you can see below:

asciicast

Issues

I’ve run into following error a few times during downloading U-Boot over SDP. Power cycle of the board solved the issue.

host log:

target log:

Summary

  • eMMC flashing with imx_usb_loader required some work, but finally ended successfully

Newsletter

If you need support in U-Boot, fastboot or eMMC feel free to book a call with us or drop us email contact@3mdeb.com. If you enjoying this type of content feel free to sing up to our newsletter!

Leave a comment!

Did you like this post? Do you have any questions? Please leave a comment and if you find the article valuable – share it with your friends ? It would be nice if more people read it. See you on our social media: facebook, twitter, linkedin