January 5, 2021

EBAZ4205 Bitcoin miner board - bare metal programming

My board runs linux from the NAND flash and I have reset the root password, so that linux install that came with the board is actually useful. However, we are going to abandon that, and reconfigure U-Boot to do what we want, namely load and run images from the network.

I have done this before with other boards (such as the Orange Pi) and I am relying on things I learned while working with those boards. My process for doing this on the Orange Pi boards is here:

Set up a DHCP server

This makes everything a lot easier. We need the MAC address of the "miner" board, which U-Boot will give us. We power up the board, type "d" to interrupt the boot sequence and get the U-Boot prompt, and then:
zynq-uboot> printenv ethaddr
ethaddr=00:0a:35:00:01:xx
Now I do two things on the linux desktop I will be using for development. I add a line like this to my /etc/hosts file:
# EBAZ4205 bitcoin miner board
192.168.0.80	bitcoin
Then I add a section like this to my /etc/dhcp/dhcpd.conf file:
   host bitcoin {
                    hardware ethernet 00:0a:35:00:01:xx;
                    fixed-address 192.168.0.80;
                    option host-name "bitcoin";
                    server-name "trona";
                    filename "bitcoin.bin";
            }
Then I do this:
service dhcpd restart
Redirecting to /bin/systemctl restart dhcpd.service
I already have dhcpd and a tftp service running from other projects, and I won't go into detail here about setting them up, other than to remind you that you may have to open up certain ports on your firewall.

tftpboot setup

On my fedora system, the tftpboot server works out of the /var/lib/tftpboot directory. Since this is a notorious security hole, I keep this owned by root. I create individual files as needed, making them writeable by me (tom) as follows:
su
cd /var/lib/tftpboot
cp orange.bin bitcoin.bin
chown tom:tom bitcoin.bin
Here I am copying some old image for the Orange Pi, just to test this network boot setup. I don't expect it to do anything useful or even predictable when loaded and booted on the "miner", but it will suffice to check out the network booting setup.

U-Boot environment modifications

The heart of the issue is to override the value of "bootcmd", which is set like so before I begin meddling:
zynq-uboot> printenv bootcmd
bootcmd=run $modeboot
I add the following variables:
setenv bootaddr 0x20000000
setenv boot_kyu "echo Booting Kyu via dhcp ; dhcp ${bootaddr}; go ${bootaddr}"
setenv bootcmd "run boot_kyu"
saveenv
The value for "bootaddr" is sort of a guess at this point and may need to be revised as I learn more about the hardware. I am just making lazy guesses looking at values used in the existing U-Boot environment settings. I will note in passing that U-Boot uses a lower value of 0x2000000 for some things. You probably can't see it, but there is one less zero in this address than the one I am using. I am guessing this is some on-chip static ram that is available before U-Boot sets up the clocks and such to talk to the DDR ram, but we will learn more later.

So I do this. However when I give the "saveenv" command, I get:

Saving Environment to SPI Flash...
Invalid bus 0 (err=-1)
*** Warning - spi_flash_probe() failed, using default environment
So, it fails to set my values and resets the enviroment. This is unfortunate. So I try just doing a one time boot after setting the values:
zynq-uboot> setenv bootaddr 0x20000000
zynq-uboot> setenv boot_kyu "echo Booting Kyu via dhcp ; dhcp ${bootaddr}; go ${bootaddr}"
zynq-uboot> setenv bootcmd "run boot_kyu"
zynq-uboot> boot
Booting Kyu via dhcp
No ethernet found.
## Starting application at 0x20000000 ...
This is even worse. However this seems to have been just an odd error and subsequent experiments with DHCP worked OK.

Next, I try the following and get much more encouraging results:

tftpboot 0x100000 bitcoin.bin
Gem.e000b000 Waiting for PHY auto negotiation to complete...... done
Gem.e000b000----100----4047----
Using Gem.e000b000 device
TFTP from server 192.168.0.104; our IP address is 192.168.0.115
Filename 'bitcoin.bin'.
Load address: 0x100000
Loading: T T T T
This is based on the following settings, which we can certainly reset.
ipaddr=192.168.0.115
serverip=192.168.0.104
So next we try this:
setenv serverip 192.168.0.5
tftpboot 0x100000 bitcoin.bin

Gem.e000b000:0 is connected to Gem.e000b000.  Reconnecting to Gem.e000b000
Gem.e000b000 Waiting for PHY auto negotiation to complete...... done
Gem.e000b000----100----4047----
Using Gem.e000b000 device
TFTP from server 192.168.0.5; our IP address is 192.168.0.115
Filename 'bitcoin.bin'.
Load address: 0x100000
Loading: T #############
	 35.2 KiB/s
done
Bytes transferred = 185104 (2d310 hex)
Cool!! That worked. And 185104 is the size of the bitcoin.bin file. Now let's try it to the address I originally intended to use:
zynq-uboot> tftpboot 0x20000000 bitcoin.bin
Gem.e000b000:0 is connected to Gem.e000b000.  Reconnecting to Gem.e000b000
Gem.e000b000 Waiting for PHY auto negotiation to complete...... done
Gem.e000b000----100----4047----
Using Gem.e000b000 device
TFTP from server 192.168.0.5; our IP address is 192.168.0.115
Filename 'bitcoin.bin'.
Load address: 0x20000000
Loading: #############
	 3.3 MiB/s
done
Bytes transferred = 185104 (2d310 hex)
This also works. So I am left with two questions. Why does the "DHCP command in U-Boot tell me "No ethernet found." ? And more importantly, why does the saveenv command fail?

I should point out that we have the capability I want, it is just not very convenient to have to type all this configuration in each time. Using the "DHCP" command is certainly nicer than using "tftpboot", but either is quite adequate.


Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org