Sometimes it is handy to have the CPU program the FPGA using a file stored on an SD card. This post shows you how this can be quickly done with Quartus and a Cyclone V-based board.

Using Quartus Prime, convert the generated .sof file into .rbf without compression (menu: Convert programming files). Next, place the .rbf file thus created on the FAT32 partition of the SD card.

U-Boot requires a boot script (u-boot.scr) that can be generated from a regular text file (u-boot.txt) with the help of the mkimage tool available in the SoC EDS shell.
The u-boot.txt file should contain:

fatload mmc 0:1 $fpgadata soc_system.rbf; fpga load 0 $fpgadata $filesize; run bridge_enable_handoff;

This text file can be transformed into the boot script file u-boot.scr file using the SoC EDS shell:

mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "My script" -d u-boot.txt u-boot.scr

The generated u-boot.scr file has to be placed on the FAT32 partition of the SD card.

The FPGA will be configured by the CPU when U-Boot is looking for the u-boot.scr file, and thereafter the boot sequence will continue normally, either by booting GNU/Linux using zImage (no additional changes are required, just ensure that both zImage and the .dtb file are on the SD card), or by a fatload app.bin for the baremetal use case.

This latter case requires you to remove the zImage file from the SD card and to generate the .bin file of your application by either adding at the end of your Makefile:

$(BIN): $(ELF)
$(OC) -O binary $(ELF) $(BIN)
$(MKI) -A arm -O u-boot -T standalone -C none -a 0x00100040 -e 0x00100040 -n "baremetalapp" -d $(BIN) $(BIN).img

or by typing in the shell:

mkimage -A arm -O u-boot -T firmware -C none -a 0x00100040 -e 0x00100040 -n 'baremetalapp' -d baremetalapp.bin baremetalapp.bin.img

The u-boot.txt file requires two additional lines:

fatload mmc 0:1 0x00100040 baremetalapp.bin;
go 0x00100040;

and the binary file of your application has to be copied to the FAT32 partition. If all operations have been performed correctly, at boot the serial console should display:

Hit any key to stop autoboot: 0
reading u-boot.scr
237 bytes read in 4 ms (57.6 KiB/s)
## Executing script at 02000000
reading soc_system.rbf
7007204 bytes read in 352 ms (19 MiB/s)
' - try 'help'd '
## Starting application at 0x3FF795A4 ...
## Application terminated, rc = 0x0
' - try 'help'd '
reading baremetalapp.bin
83568 bytes read in 10 ms (8 MiB/s)
' - try 'help'd '
## Starting application at 0x00100040 ...

One the steps listed above are performed, should you need to change the bitstream, only the .rbf  file will have to be regenerated and copied to the SD card.