April 23, 2017

Network booting an Orange Pi, U-Boot setup

Network booting using DHCP is definitely the way to do things, and better than how I used to do things with an explicit TFTP setup, as detailed below.

You will first need to set up and configure a DHCP server (not to mention a TFTP server). You will need the MAC address for your Orange Pi. You can get this by starting U-Boot, interrupting it and typing:

=> printenv ethaddr
ethaddr=02:20:a1:5a:xx:yy
I load Kyu to the start of ram at 0x40000000 using the following U-boot environment variable settings:
setenv bootaddr 0x40000000
setenv boot_kyu "echo Booting Kyu via dhcp ; dhcp ${bootaddr}; go ${bootaddr}"
setenv bootcmd "run boot_kyu"
saveenv
That is it!! This lets the DHCP server supply the filename, IP addresses, and all that.

You can safely ignore all of what follows.

Orange PI - customizing U-Boot - the old way (December, 2016)

I am working with an Orange Pi PC board with the H3 chip. This is an "executive course" intended to help someone who just wants to quickly get this done (set up an Orange Pi for network booting).

Connect a serial console. Insert an SD card with U-Boot and the SPL on it. Power it up and interrupt U-boot when it offers to let you do so.

U-Boot should have already obtained some information via DHCP, if you have a working DHCP server set up and if it has an entry for this particular MAC address. If this is the case, you should see values for variables, like the following. (If you have not yet set up your DHCP server, you can at least get the MAC address from the "ethaddr" value and do so, then come back and repeat all this.

=> printenv ethaddr
ethaddr=02:20:a1:5a:xx:yy
=> printenv ipaddr
ipaddr=192.168.0.69
=> printenv serverip
serverip=192.168.0.5
=> printenv bootfile
bootfile=orange
Now we want to set some values like this:
setenv bootaddr 0x40000000
setenv boot_kyu "echo Booting via tftp (${bootfile}); tftpboot ${bootaddr} ${bootfile}; go ${bootaddr}"
saveenv
After this, power cycle the board and use printenv to verify that these new variables retain their settings. On the Orange Pi PC I am working with, it tells me:
saveenv
Saving Environment to MMC...
Writing to MMC(0)... done
Now we are going to modify a preexisting variable, so it is worth copying down the default setting just in case it is of interest to restore it someday.
printenv bootcmd
bootcmd=run loadsplash; run distro_bootcmd

setenv bootcmd run boot_kyu
saveenv
And there you go, you have an Orange Pi PC set up to tftpboot a vanilla binary image from a TFTP server. This is much nicer than what I did with U-Boot previously on a BBB. In that case I added commands to a uEnv.txt file inside of a filesystem and I had to "wire in" specific IP addresses for the target and the server, as well as the filename. Here, all the boot parameters (except the load address) are obtained via DHCP.

Where on MMC does U-boot save the environment info?

I used to see this message when U-Boot started.
MMC:   SUNXI SD/MMC: 0
*** Warning - bad CRC, using default environment
Now I completely understand this. With a blank SD card, the block of information that U-Boot reads to find a saved environment just has a bunch of zeros (or who knows what), so U-Boot computes a CRC and rejects it, as it should.

We don't really need to know (or care) where U-Boot sticks the environment information when you do a saveenv, but it is interesting to find out.

Take a look in the U-Boot sources at include/configs/sunxi-common.h There is lots of interesting stuff here, but:

#define CONFIG_ENV_IS_IN_MMC
#define CONFIG_ENV_OFFSET               (544 << 10) /* (8 + 24 + 512) KiB */
#define CONFIG_ENV_SIZE                 (128 << 10)     /* 128 KiB */
So, these are byte offsets (the shift by 10 takes 1K block offsets to byte offsets). And if we believe this, the env stuff starts 544K along in the SD card. So, U-boot has to fit before that. So lets contemplate the SD card layout. So there is plenty of room for the savenv block and the space would be wasted in any event. Don't feel guilty about wasting space on the eMMC. If you do feel guilty, consider reducing the offset of that first filesystem, but frankly -- who cares?

Consider this message when you do a printenv:

Environment size: 4557/131068 bytes
128 * 1024 = 131072 -- so 4 bytes goes someplace (maybe the CRC).

To verify all of this:

dd if=/dev/sdc of=env.bin bs=1024 skip=544 count=10
odx env.bin | more
00000000 1629 7d95 6172 6368 3d61 726d 0062 6175    )} arch=arm bau
00000010 6472 6174 653d 3131 3532 3030 0062 6f61   drate=115200 boa
00000020 7264 3d73 756e 7869 0062 6f61 7264 5f6e   rd=sunxi board_n
00000030 616d 653d 7375 6e78 6900 626f 6f74 5f61   ame=sunxi boot_a
That sure looks like the environment information with a 32 bit checksum in the lead to me.


Have any comments? Questions? Drop me a line!

Tom's electronics pages / tom@mmto.org