In our never ending quest to handle the question of “How do I program this thing”, we’ve added a new tool to U-Boot. A new routine and command has just been acked by the U-Boot community, we’ll very soon have support for gzwrite() (which stands for gunzip and write) in our boot loaders.
The purpose of the utility is to allow filesystems to be programmed quickly to block devices in an environment where removal of the device is impractical. Of course, this applies most directly to eMMC or other soldered-on storage, but also may apply in environments where an SD card slot is not exposed, but a USB Host or OTG port is available.
The routine and command act on a gzip-compressed image in memory and allow it to be decompressed and written to a block device in one pass. This often allows a typical 4 GiB storage device to be programmed entirely from RAM, even on boards with only 1GiB. In fact, every one of the images listed in our i.MX6 builds page can fit within RAM on a Nitrogen6X or BD-SL-i.MX6 (SABRE Lite) board.
For the impatient
If you have a file named my.img.gz on SD card mmc 0, you can load it into RAM and program it to the eMMC on a Nitrogen6_Max like so:
U-Boot > load mmc 0 10008000 my.img.gz U-Boot > gzwrite mmc 1 10008000 0x$filesize 100000 0
The parameters to the command are:
|mmc 0||defines the block device|
|10008000||address of the gzipped source image|
|0x$filesize||size of the gzipped source|
|100000||write buffer size (default 1MiB). The decompress operation will allocate buffer this size and flush to the block device when filled.|
|0||start offset in bytes on the block device|
The last parameter can be used to decompress multiple parts of an image piecewise if the source is too big to fit into RAM.
U-Boot and its’ stack and heap live at the tail-end of memory as described here, so images have to be pretty big before we worry about that. (You can likely program a gzipped image up to DDR size-20 MiB)
The gzwrite command has been enabled for all of our boards on the staging branch of our Github repository with commits like this one for Nitrogen6x, but will become a standard feature in all future releases.
If you want to test things out before then, we placed a package with our current staging binaries on-line here:
U/I and Customization
The gzwrite() routine supports the use of call-backs to represent progress, so you can customize things to provide something fancy. Extracting a 4GiB image to eMMC generally should take under 6 minutes, but that’s a long time to wait without letting a user know that things are moving forward.
The default implementation will write the number of bytes written and total during every fourth write to the destination.
If your display is supported by U-Boot, you’ll probably want this on the screen, and can accomplish that by setting the stdout variable:
U-Boot > setenv stdout serial,vga
Use in a boot script
Wrapping this up in a boot script is very straightforward. If you paste this into our on-line boot script compiler, you’ll get a binary that you can place onto a USB stick or SD card that will automagically program my.img.gz to eMMC (or the top SD card slot
setenv stdout serial,vga load mmc 0 10008000 my.img.gz && gzwrite mmc 1 10008000 $filesize 400000 && echo "eMMC programmed" && setenv stdout serial && exit ; echo "Error loading image or programming eMMC";
Note the judicious use of exit on success and the use of the double-ampersands && to proceed only when the previous step succeeds.