Writing a system image using u-boot and TFTP
Published on August 5, 2016
Objective
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 10.0.0.2; setenv netmask 255.255.255.0; setenv serverip 10.0.0.1;" |
This assumes you have a server at 10.0.0.1 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
address 10.0.0.1
netmask 255.255.255.0
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."
Caveat
The memory address listed above "10008000" is not valid for imx6sx, or imx7d based boards. For them it should be "80008000".