Writing a system image using u-boot and TFTP

Published on August 5, 2016

Archived Notice

This article has been archived and may contain broken links, photos and out-of-date information. If you have any questions, please Contact Us.


Many of our customers have requested help in writing an initial file system to eMMC.

For a small file system, this previous post works well.

But for larger images, ram cannot hold the entire image at once. This post seeks to address this issue.

If you need help setting up a tftpserver, try these posts.

TFTP For Windows users

TFTP For Linux users

For the impatient

Grab the image you want to program. A reference to our latest images can be found here

 I'll be using this 

Then run the script to break it into small chunks

  ~$ mv 20160330-nitrogen-3.14.52_1.1.0_ga-trusty-en_US-lxde_armhf.img.gz trusty.img.gz ~$ ./split-for-gzwrite.sh trusty.img.gz ~$ sudo cp trusty.img.gz.* /tftpboot/ ~$ sudo cp net_upgrade_fs /tftpboot/

Then from the u-boot prompt run

=> dhcp 10008000 net_upgrade_fs && source 10008000

A little more detail

If your file system is small, you may not need to run the split.sh script. Since gzwrite decompresses and writes 1MB at a time, only the compressed file needs to fit into memory.  In this case, just copy your mybase.img.gz to mybase.img.gz.0 in the tftpboot directory.  Or perhaps you want to split the file into chunks other than 512MB(default), either because your ram size is only 512MB or you desire fewer files. This can be accomplished by passing a size parameter to the split script. The following will split the gz file into chunks of a maximum size of 1GB when decompressed.

  ~$ ./split-for-gzwrite.sh trusty.img.gz 1024

The net_upgrade_fs script defaults to trusty.img.gz as the base  filename to program.

You can change this by using 

=> setenv upgrade_file mybase.img.gz
=> dhcp 10008000 net_upgrade_fs && source 10008000

Here's the file if you want to change the default.

Compile it like a normal bootscript

  ~$ mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "boot script" \ -d net_upgrade_fs.txt net_upgrade_fs

The net_upgrade_fs script also defaults to "mmc 1" for the device to be used. This can also be changed.

=> setenv upgrade_device "mmc 0"
=> dhcp 10008000 net_upgrade_fs && source 10008000

So, you say you have no ethernet. Well, that isn't a problem if you use your usb on-the-go port.

=> run usbnetwork; tftpboot 10008000 net_upgrade_fs && source 10008000

If your older u-boot does not have "usbnetwork", here's how it should be defined.

=> setenv usbnet_devaddr "00:19:b8:00:00:02"
=> setenv usbnet_hostaddr "00:19:b8:00:00:01"
=> setenv usbnetwork "setenv ethact usb_ether; setenv ipaddr; setenv netmask; setenv serverip;"

This assumes you have a server at on the usbotg port. To help my usbotg port come up, I have this in /etc/network/interfaces of my desktop PC.

auto enx0019b8000001
iface enx0019b8000001 inet static


Upgrading u-boot using tftp

I often upgrade u-boot using tftp so that I don't have to copy the new u-boot file to an sd card. Our local network builds u-boot for all of our boards/memory configurations and places the result in the tftp server's directory whenever our u-boot repo has a commit pushed. So, this will always grab the latest u-boot when connected to the local network.


First, grab the appropriate u-boot from here.

For nitrogen6_max, this would be u-boot.nitrogen6_max or u-boot.nitrogen6_max_4gr0 (memory has rank of 0 bits.) Since version v2015.07, you can find the appropriate extension by

=> print uboot_defconfig

And the upgrade script from here

And the compiled version,

Then copy to your tftp server's directory

  ~$ sudo cp u-boot.nitrogen6_max /tftpboot/ ~$ sudo cp net_upgradeu /tftpboot/

Then from the u-boot prompt run

=> run net_upgradeu

Or for an older u-boot

=> setenv uboot_defconfig myboard_config
=> dhcp 10008000 net_upgradeu && source 10008000

So, you want to upgrade both u-boot and the file system by changing your bootscript file ? Well that is still easy. Here's what the boot script file should contain.

And the compiled version,

This begins by clearing the environment section of the SPI-nor flash,  upgrades u-boot if needed, and if u-boot is up-to-date, then the file system will be written. If the file system is written successfully, then the /6x_bootscript from that file system will load and run. By default this will update whichever device from which the bootscript loads. If this is loaded over the network, it will write to "mmc 1."


The memory address listed above "10008000" is not valid for imx6sx, or imx7d based boards. For them it should be "80008000".