Introduction
Starting with the v19.1 Standard Edition (v19.1 Std) / v19.3 Pro Edition (v19.3 Pro) of the SoC FPGA Embedded Development Suite (SoC EDS), the bootloader generation flow has changed.
- As noted in the release notes, the bootloader source tree that was bundled with SoC EDS prior to SoC EDS v18.1 is no longer included.
- Starting with SoC EDS v19.1 Std / v19.3 Pro, users will need to obtain the bootloader source tree from GitHub at
. This allows the latest boot loader to be used and easily adaptable to updates. - The modified bootloader generation flow can be found on the following Rocketboards.org page
Reference: Building Bootloader for Cyclone V and Arria 10
This article describes how to build U-Boot with the following configuration
| Device | Quartus Version | U-Boot Branch | Linux Branch |
| Arria® 10 SoC | 22.4 Pro | 2022.07 | 5.15.70-lts |
Note:
The above is the device/tools compatibility table as of March 1, 2023 (content will be updated
with each release).
This article describes the old and new bootloader build flow for the Arria® 10 SoC and the steps to build the bootloader.
Reference:
The official SoC FPGA U-Boot repository can be found at https://github.com/altera-opensource/u-boot-socfpga.
Branches labeled "RC" are for internal active development and Customer Early Access without official customer support .
The latest stable branch (without RC label) is strongly recommended for non-Intel development and production use at.
For Quartus® and device support, see doc/README.socfpga.
1. Build flow for Arria® 10 SoC
For the Arria® 10 SoC, the handoff information created by the Quartus® compilation is provided in the form of C source code, XML, or a binary file.
BSP-Editor converts this handoff information into the source code used to build the Uboot.
For SoC EDS versions older than v20.3 Pro, the BSP Editor could be used.
However, v20.3 Pro or later introduces a new procedure that does not use the BSP Editor.
1-1. Flow before SoC EDS v18.1
In SoC EDS v18.1 and earlier, the following flow was used to build the U-Boot:
Figure 1. Boot Loader Generation Flow in SoC EDS v18.1 and earlier
- Key user options (boot source, enable ECC scrubbing, watchdog, etc.) were set via the bsp-editor GUI or equivalent command line.
- U-Boot source code was included with SoC EDS.
- The Makefile created by bsp-editor allowed the bootloader to be built with a single 'make' command.
1-2. Flow of SoC EDS v19.1 Std / v19.3 Pro to v20.1
The build flow for SoC EDS v19.1 Std / v19.3 Pro to v20.1 is different as shown below:
Figure 2. Boot Loader Generation Flow for SoC EDS v19.1 Std / v19.3 Pro - v20.1
The main differences are as follows:
- All user options defined in bsp-editor no longer apply. They will still be configurable in bsp-editor, but will have no effect.
- All custom user settings must be done directly in U-Boot (device tree, configuration, and source code).
- The Makefile generated by bsp-editor will not build the U-Boot. Instead, use the Makefile included in the U-Boot source tree to make.
- Binary conversion or conversion to an image file can be done by following the instructions on page of Building Bootloader for Cyclone V and Arria 10 on Rocketboards.org.
- The U-boot source code must be obtained by the user from GitHub.
- A tool called qts_filter (part of U-Boot) must be called to convert the handoff files and the files generated by bsp-editor into the format required by the new U-Boot version.
1-3. Flow for v20.3 Pro and later after SoC EDS is discontinued
The boot flow for v20.3 Pro and later is as shown in the figure below.
There are some changes due to the discontinuation of SoC EDS:
Figure 3. Boot Loader Generation Flow from v20.3 Pro and later
The main differences are as follows:
- With the discontinuation of SoC EDS, bsp-editor (bsp-create-settings) is no longer in the flow. Instead, the qts-filter-a10.sh included in the U-boot source tree is used.
- With the change from bsp-editor (bsp-create-settings) to qts-filter-a10.sh, the file included in the U-boot Generic Source Code has changed from Device Tree to Device Tree Handoff File (.h) file that is included in the U-boot Generic Source Code.
2. How to execute the build
2-1. Prerequisites
■ The following environment is used in this article (the environment used here is just an example):
-
- Host machine running Linux. In this article we used VirtualBox + Ubuntu 20.04 LTS.
- An internet connection to download tools and clone the U-Boot git tree from GitHub. If you have a firewall or proxy, you will need to allow the system administrator access to the git tree.
- SoC FPGA development kit with desired device: Arria® 10 SoC
- Development tool: Quartus® Prime v22.4 Pro (for Arria® 10 SoC) (to compile GHRD)
■ If you have a proxy, such as an internal network, the following proxy settings are required:
On your Linux host machine, open the /etc/apt/apt.conf file using a text editor (such as gedit),
write the proxy settings as shown below, and save it.
$ sudo gedit /etc/apt/apt.conf
Acquire::http::proxy "http://proxy.address:proxy.port";
Acquire::https::proxy "https://proxy.address:proxy.port";
Acquire::ftp::proxy "ftp://proxy.address:proxy.port";
* In the above proxy settings, proxy.address means the proxy address, and proxy.port means the proxy port number.
Please set the appropriate settings according to the user's network environment.
On your Linux host machine, open the .bashrc file in a text editor (such as gedit),
add the following proxy to the last line, and then save the file.
$ gedit ~/.bashrc
export http_proxy="http://proxy.address:proxy.port"
export https_proxy="https://proxy.address:proxy.port"
export ftp_proxy="ftp://proxy.address:proxy.port"
* In the above proxy settings, proxy.address means the proxy address, and proxy.port means the proxy port number.
Please set the appropriate settings according to the user's network environment.
On the Linux host machine, open the ~/.curlrc file with a text editor (such as gedit),
and append the following proxy to the last line of and save it.
$ gedit ~/.curlrc
proxy=http://proxy.address:proxy.port
* In the above proxy settings, proxy.address means the proxy address, and proxy.port means the proxy port number.
Please set the appropriate settings according to the user's network environment.
Close the terminal on your Linux host machine and then start it again.
■ Open the terminal and enter the following command to update the package information:
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install curl ← Install the packages necessary to run make generate_from_tcl
$ sudo apt install device-tree-compiler ← Install packages required to run tools/mkimage
$ sudo apt install mtd-utils ← Install the packages required to run mkfs.jffs2
■ If you have a proxy such as an internal network, it is necessary to configure proxy settings by using the following git config --global command (please configure the appropriate settings for your network environment):
$ git config --global http.proxy http://proxy.address:proxy.port
$ git config --global https.proxy https://proxy.address:proxy.port
■ Download and set up the toolchain:
$ wget https://developer.arm.com/-/media/Files/downloads/gnu/11.2-2022.02/binrel/gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf .tar.xz
$ tar xf gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf.tar.xz
$ rm gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf.tar.xz
$ export PATH='pwd'/gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf/bin:$PATH
$ export ARCH=arm
$ export CROSS_COMPILE=arm-none-linux-gnueabihf-
■ This article boots Linux from a boot loader; to boot Linux, you need the Linux kernel, the Linux device tree, and the Root Filesystem ("RootFs").
Please refer to the following related article for the procedure to create Linux binaries.
Note:
This article assumes that the following Linux binary files have already been generated under the $LINUX_BIN/a9 folder, as built in the related articles above.
Table 1. Linux binary files pre-built in the $LINUX_BIN/a9 folder
| File | Description |
| zImage | Compressed kernel image |
| Image | Uncompressed kernel image |
| socfpga_arria10_socdk_sdmmc.dtb | Device tree blob for SD/MMC boot for Arria® 10 SoC |
| socfpga_arria10_socdk_qspi.dtb | Device tree for QSPI boot for Arria® 10 SoC blob |
| socfpga_arria10_socdk_nand.dtb | Device tree for NAND boot for Arria® 10 SoC blob |
| core-image-minimal-arria10.tar.gz |
RootFs for Arria® 10 SoC (tar archive format) |
2-2. Arria® 10 SoC Boot Loader Build (for SD card boot)
2-2-1. Setup
(1) Create a Top folder:
$ sudo rm -rf a10_example.sdmmc
$ mkdir a10_example.sdmmc
$ cd a10_example.sdmmc
$ export TOP_FOLDER='pwd'
(2) Get the hardware design from GitHub and compile it. Delete the already compiled software folder in it:
$ cd $TOP_FOLDER
$ rm -rf ghrd-socfpga-QPDS22.4_REL_GSRD_PR QPDS22.4_REL_GSRD_PR.zip a10_soc_devkit_ghrd
$ wget https://github.com/altera-opensource/ghrd-socfpga/archive/refs/tags/QPDS22.4_REL_GSRD_PR.zip
$ unzip QPDS22.4_REL_GSRD_PR.zip
$ mv ghrd-socfpga-QPDS22.4_REL_GSRD_PR/a10_soc_devkit_ghrd_pro a10_soc_devkit_ghrd
$ rm -rf ghrd-socfpga-QPDS22.4_REL_GSRD_PR QPDS22.4_REL_GSRD_PR.zip
$ cd a10_soc_devkit_ghrd
$ make clean && make scrub_clean && rm -rf software
$ ~/intelFPGA_pro/22.4/nios2eds/nios2_command_shell.sh \
make generate_from_tcl
$ ~/intelFPGA_pro/22.4/nios2eds/nios2_command_shell.sh \
make rbf
2-2-2. Build U-Boot
(1) Clone the git tree and check out the supported branches to get the U-Boot source code:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/
$ mkdir -p software/bootloader
$ cd software/bootloader/
$ git clone https://github.com/altera-opensource/u-boot-socfpga
$ cd u-boot-socfpga
# If you are using the latest U-Boot branch, comment out the following line
# $ git checkout -b test -t origin/socfpga_v2022.07
(2) Convert the hps.xml handoff file to the include file used in the device tree:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga
$ ./arch/arm/mach-socfpga/qts-filter-a10.sh \
../../../hps_isw_handoff/hps.xml \
arch/arm/dts/socfpga_arria10_socdk_sdmmc_handoff.h
(3) Configure and build U-Boot:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga
$ export CROSS_COMPILE=arm-none-linux-gnueabihf-
$ make socfpga_arria10_defconfig
$ make -j 48
Table 2. Files generated by the build
| File | Description |
| spl/u-boot-splx4.sfp | Bootable image containing 4 SPL binaries in the format required by BootROM |
| u-boot.img | U-Boot image |
(4) Create a FIT image containing the FPGA programming file that SPL uses to configure the FPGA. This will create the fit_spl_fpga.itb file:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga
$ ln -s ../../../output_files/ghrd_10as066n2.core.rbf .
$ ln -s ../../../output_files/ghrd_10as066n2.periph.rbf .
$ tools/mkimage -E -f board/altera/arria10-socdk/fit_spl_fpga.its fit_spl_fpga.itb
2-2-3. Prepare SD card image
(1) Create sd_card folder and get SD card script:
$ cd $TOP_FOLDER/
$ sudo rm -rf sd_card && mkdir sd_card && cd sd_card
$ wget https://releases.rocketboards.org/2021.04/gsrd/tools/make_sdimage_p3.py
$ chmod +x make_sdimage_p3.py
(2) Create a folder for FAT partition and collect files:
$ cd $TOP_FOLDER/sd_card
$ mkdir sdfs && cd sdfs
$ export set LINUX_BIN=~/linux-bin ← export the path to LINUX_BIN
$ cp $LINUX_BIN/a9/zImage .
$ cp $LINUX_BIN/a9/socfpga_arria10_socdk_sdmmc.dtb .
$ cp ../../a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga/fit_spl_fpga.itb .
$ cp ../../a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga/u-boot.img .
$ mkdir extlinux
$ echo "LABEL Arria10 SOCDK SDMMC" > extlinux/extlinux.conf
$ echo " KERNEL ../zImage" >> extlinux/extlinux.conf
$ echo " FDT ../socfpga_arria10_socdk_sdmmc.dtb" >> extlinux/extlinux.conf
$ echo " APPEND root=/dev/mmcblk0p2 rw rootwait earlyprintk console=ttyS0,115200n8" >> extlinux/extlinux.conf
(3) Create a folder for the RootFs partition:
$ cd $TOP_FOLDER/sd_card
$ mkdir rootfs && cd rootfs
$ sudo tar xf $LINUX_BIN/a9/core-image-minimal-arria10.tar.gz
$ sudo rm -rf lib/modules/*
(4) Import the SPL binaries:
$ cd $TOP_FOLDER/sd_card
$ cp ../a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga/spl/u-boot-splx4.sfp .
(5) Prepare the SD card image. This will create the file $TOP_FOLDER/sd_card/sdcard_a10.img:
$ cd $TOP_FOLDER/sd_card
$ sudo python3 ./make_sdimage_p3.py -f \
-P u-boot-splx4.sfp,num=3,format=raw,size=10M,type=A2 \
-P sdfs/*,num=1,format=fat32,size=32M \
-P rootfs/*,num=2,. format=ext3,size=32M \
-s 80M \
-n sdcard_a10.img
(6) Write the generated SD card image sdcard_cv.img to the SD card (using Win32DiskImager, etc.).
2-3-4. Booting from SD card
(1) Make sure that the Arria® 10 SoC Development Kit is equipped with an SD daughter card and that SD card boot is available at. Then insert the card into the SD card slot.
(2) Power on the Arria® 10 SoC Development Kit again to boot Linux. Log in without a password, using "root" as the user name:
U-Boot SPL 2022.07-23045-g123cc7934a (Apr 03 2023 - 16:28:24 +0900)
FPGA: Checking FPGA configuration setting . .
FPGA: Start to program peripheral/full bitstream . .
FPGA: Early Release Succeeded.
FPGA: Checking FPGA configuration setting . .
FPGA: Start to program peripheral/full bitstream . .
FPGA: Early Release Succeeded.
U-Boot SPL 2022.07-23045-g123cc7934a (Apr 03 2023 - 16:28:24 +0900)
DDRCAL: Success
DDRCAL: Scrubbing ECC RAM (1024 MiB).
DDRCAL: SDRAM-ECC initialized success with 333 ms
FPGA: Checking FPGA configuration setting ...
FPGA: Start to program core bitstream ...
Full Configuration Succeeded.
FPGA: Enter user mode.
WDT: Started watchdog@ffd00300 with servicing (10s timeout)
Trying to boot from MMC1
U-Boot 2022.07-23045-g123cc7934a (Apr 03 2023 - 16:28:24 +0900)socfpga_arria10
CPU: Altera SoCFPGA Arria 10
BOOT: SD/MMC Internal Transceiver (3.0V)
Model: Altera SOCFPGA Arria 10
DRAM: 1 GiB
Core: 77 devices, 20 uclasses, devicetree: separate
WDT: Started watchdog@ffd00300 with servicing (10s timeout)
MMC: dwmmc0@ff808000: 0
Loading Environment from MMC... *** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Model: Altera SOCFPGA Arria 10
Net:
Warning: ethernet@ff800000 (eth0 ) using random MAC address - 9e:a2:6b:5b:cf:c9
eth0: ethernet@ff800000
Hit any key to stop autoboot: 0
Failed to load 'u-boot.scr'
15000828 bytes read in 797 ms (17.9 MiB/s)
fpga - loadable FPGA image support
Usage:
fpga [operation type] [device number] [image address] [image size]
fpga operations:
dump [dev] [address] [size] Load device to memory buffer
info [dev] list known device information
load [dev] [address] [size] Load device from memory buffer
loadb [dev] [address] [size] Load device from bitstream buffer (Xilinx only)
loadmk [dev] [address] Load device generated with mkimage
For loadmk operating on FIT format uImage address must include
subimage unit name in the form of addr:<subimg_uname>
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found /extlinux/extlinux.conf
Retrieving file: /extlinux/extlinux.conf
1: Arria10 SOCDK SDMMC
Retrieving file: /extlinux/../zImage
append: root=/dev/mmcblk0p2 rw rootwait earlyprintk console=ttyS0,115200n8
Retrieving file: /extlinux/../socfpga_arria10_socdk_sdmmc.dtb
Kernel image @ 0x1000000 [ 0x000000 - 0x55cbc0 ]
## Flattened Device Tree blob at 02000000
Booting using the fdt blob at 0x2000000
Loading Device Tree to 09ff6000, end 09fff451 ... OK
Starting kernel ...
Deasserting all peripheral resets
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 5.15.70-153198-gf87aaa2c4d7c-dirty ( ubuntu@ubuntu1804) (arm-none-linux-gnueabihf-gcc (GNU Toolchain for the Arm Architecture 11.2-2022.02 (arm-11.14)) 11.2.1 20220111, GNU ld (GNU Toolchain for the Arm Architecture 11.2-2022.02 (arm-11.14)) 2.37.20220122) #1 SMP Tue Mar 14 09:48:08 JST 2023
[ 0.000000] CPU: ARMv7 Processor [414fc 091] revision 1 (ARMv7), cr=10c5387d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] OF: fdt: Machine model: Altera SOCFPGA Arria 10
- omitted -
[ 17.902723] random: crng init done
[ 17.906132] random: 2 urandom warning(s) missed due to ratelimiting
Starting OpenBSD Secure Shell server: sshd
generating ssh RSA host key...
generating ssh ECDSA host key...
generating ssh ED25519 host key...
done.
Starting syslogd/klogd: done
Poky (Yocto Project Reference Distro) 4.0.8 arria10 /dev/ttyS0
arria10 login: root
root@arria10:~#
We have confirmed that Linux boots with the boot loader for the SD card generated above.
2-3. Building Arria® 10 SoC Boot Loader (for QSPI boot)
2-3-1. Setup
(1) Create a Top folder:
$ sudo rm -rf a10_example.qspi
$ mkdir a10_example.qspi
$ cd a10_example.qspi
$ export TOP_FOLDER='pwd'
(2) Get the hardware design from GitHub, update it for QSPI, and build it. Delete the already compiled software folder in it:
$ cd $TOP_FOLDER
$ rm -rf ghrd-socfpga-QPDS22.4_REL_GSRD_PR QPDS22.4_REL_GSRD_PR.zip a10_soc_devkit_ghrd
$ wget https://github.com/altera-opensource/ghrd-socfpga/archive/refs/tags/QPDS22.4_REL_GSRD_PR.zip
$ unzip QPDS22.4_REL_GSRD_PR.zip
$ mv ghrd-socfpga-QPDS22.4_REL_GSRD_PR/a10_soc_devkit_ghrd_pro a10_soc_devkit_ghrd
$ rm -rf ghrd-socfpga-QPDS22.4_REL_GSRD_PR QPDS22.4_REL_GSRD_PR.zip
$ cd a10_soc_devkit_ghrd
$ make clean && make scrub_clean && rm -rf software
$ sed -i 's/HPS_BOOT_DEVICE .= .*/HPS_BOOT_DEVICE := QSPI/g' Makefile
$ ~/intelFPGA_pro/22.4/nios2eds/nios2_command_shell.sh \
make generate_from_tcl
$ ~/intelFPGA_pro/22.4/nios2eds/nios2_command_shell.sh \
make rbf
2-3-2. Build U-Boot
(1) Clone the git tree and check out the supported branches to get the U-Boot source code:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/
$ mkdir -p software/bootloader
$ cd software/bootloader
$ git clone https://github.com/altera-opensource/u-boot-socfpga
$ cd u-boot-socfpga
# If you are using the latest U-Boot branch, comment out the following line
# $ git checkout -b test-bootloader -t origin/socfpga_v2022.07
(2) Convert the hps.xml handoff file to the include file used in the device tree at. This creates the arch/arm/dts/socfpga_arria10_socdk_qspi_handoff.h file:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga
$ . /arch/arm/mach-socfpga/qts-filter-a10.sh \
../../../hps_isw_handoff/hps.xml \
arch/arm/dts/socfpga_arria10_socdk_qspi_handoff.h
(3) Configure and build U-Boot:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga
$ export ARCH=arm
$ export CROSS_COMPILE=arm-none-linux-gnueabihf-
$ make socfpga_arria10_qspi_defconfig
$ make -j 48
This will build the following files in the $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga folder:
Table 3. Files generated by the build
| File | Description |
| spl/u-boot-splx4.sfp | Bootable image containing 4 SPL binaries in the format required by BootROM |
| u-boot.img | U-Boot image |
(4) Create a FIT image containing the FPGA programming file that SPL uses to configure the FPGA. This will create the fit_spl_fpga.itb file:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga
$ cp ../../../output_files/ghrd_10as066n2.core.rbf .
$ cp ../../../output_files/ghrd_10as066n2.periph.rbf .
$ tools/mkimage -E -f board/altera/arria10-socdk/fit_spl_fpga.its fit_spl_fpga.itb
(5) Create a FIT image of U-Boot. This will generate the fit_uboot.itb file:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga
$ tools/mkimage -E -f board/altera/arria10-socdk/fit_uboot.its fit_uboot.itb
(6) Create a FIT image of the Linux kernel and device tree. This will generate the kernel.itb file:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga
$ export LINUX_BIN=~/linux-bin ← export the path of LINUX_BIN
$ cp $LINUX_BIN/a9/Image .
$ cp $LINUX_BIN/a9/socfpga_arria10_socdk_qspi.dtb .
$ tools/mkimage -f board/altera/arria10-socdk/fit_kernel_qspi.its kernel.itb
2-3-3. Prepare QSPI binaries
(1) Create a qspi_bin folder and import the binary files created so far:
$ cd $TOP_FOLDER/
$ rm -rf qspi_bin && mkdir qspi_bin && cd qspi_bin
$ cp ../a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga/spl/u-boot-splx4.sfp .
$ cp ../a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga/fit_uboot.itb .
$ cp ../a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga/fit_spl_fpga.itb .
$ cp ../a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga/kernel.itb .
(2) Prepare JFFS2 rootfs image to boot Linux from QSPI:
$ cd $TOP_FOLDER/qspi_bin/
$ sudo rm -rf core-image-minimal-arria10-rootfs
$ mkdir core-image-minimal-arria10-rootfs
$ cd core-image-minimal-arria10-rootfs
$ tar xf $LINUX_BIN/a9/core-image-minimal-arria10.tar.gz
$ sudo rm -rf lib/modules/*
$ cd ..
$ sudo mkfs.jffs2 -r core-image-minimal-arria10-rootfs -s 256 -e 64KiB --squash -o core-image-minimal-arria10-rootfs.jffs2
$ sudo chown $USER:$USER core-image-minimal-arria10-rootfs.jffs2
$ sudo rm -rf core-image-minimal-arria10-rootfs
(3) At this point, the following binaries are stored in $TOP_FOLDER/qspi_bin:
Table 4. Files used for Linux boot
| File | Description |
| spl_w_dtb-mkpimage.bin | Four SPL binaries with BootROM header |
| fit_spl_uboot.itb | U-Boot image |
| fit_spl_fpga.itb | FPGA configuration file |
| kernel.itb | Linux kernel and device tree |
| core-image-minimal-arria10-rootfs.jffs2 | RootFs for Arria® 10 SoC in jffs2 format |
2-3-4. Boot from QSPI
(1) Make sure your Arria 10 SoC Development Kit has a QSPI boot flash daughter card and is QSPI bootable.
(2) Write the binary to the QSPI flash:
Table 5. Correspondence between files and addresses to be written to QSPI Flash
| Address | File | Description |
| 0x0000000 | u-boot-splx4.sfp | Four SPL binaries with BootROM header |
| 0x0100000 | fit_spl_uboot.itb | U-Boot image |
| 0x0200000 | n/a | U-Boot environment |
| 0x0300000 | fit_spl_fpga.itb | FPGA configuration file |
| 0x1200000 | kernel.itb | Linux kernel and device tree |
| 0x2720000 | core-image-minimal-arria10-rootfs.jffs2 | RootFs for Arria® 10 SoC in jffs2 format |
$ cd $TOP_FOLDER/qspi_bin
$ ~/intelFPGA_pro/22.4/nios2eds/nios2_command_shell.sh \
quartus_hps -c 1 -o e
$ ~/intelFPGA_pro/22.4/nios2eds/nios2_command_shell.sh \
quartus_hps -c 1 -o pv -a 0x0000000 u-boot-splx4.sfp
$ ~/intelFPGA_pro/22.4/nios2eds/nios2_command_shell.sh \
quartus_hps -c 1 -o pv -a 0x0100000 fit_uboot.itb
$ ~/intelFPGA_pro/22.4/nios2eds/nios2_command_shell.sh \
quartus_hps -c 1 -o pv -a 0x0300000 fit_spl_fpga.itb
$ ~/intelFPGA_pro/22.4/nios2eds/nios2_command_shell.sh \
quartus_hps -c 1 -o pv -a 0x1200000 kernel.itb
$ ~/intelFPGA_pro/22.4/nios2eds/nios2_command_shell.sh \
quartus_hps -c 1 -o pv -a 0x2720000 core-image-minimal-arria10-rootfs.jffs2
Reference:
Due to the slow processing of the quartus_hps tool, it is recommended to load U-Boot via the Arm® DS (DS-5) debugger, download the file via TFTP, and write it using the U-Boot command.
-
- Erase the QSPI flash using quartus_hps:
$ ~/intelFPGA_pro/22.4/nios2eds/nios2_command_shell.sh \
quartus_hps -c 1 -o E
-
- Copy the binaries to the TFTP folder on the host machine.
- Run U-Boot from the debugger as shown in Arria 10 SoC - Run U-Boot from Debugger.
- Connect U-Boot to the network and specify the IP address of the host machine:
$ setenv autoload no
$ dhcp
$ setenv serverip <your_server_ip>
-
- Download binaries via TFTP in U-Boot and write them to QSPI:
$ sf probe
$ tftp ${loadaddr} u-boot-splx4.sfp;sf write ${loadaddr} 0x0000000 ${filesize}
$ tftp ${loadaddr} fit_uboot.itb; sf write ${loadaddr} 0x0100000 ${filesize}
$ tftp ${loadaddr} fit_spl_fpga.itb; sf write ${loadaddr} 0x0300000 ${filesize}
$ tftp ${loadaddr} kernel.itb; sf write ${loadaddr} 0x1200000 ${filesize}
$ tftp ${loadaddr} core-image-minimal-arria10-rootfs.jffs2 ;sf write ${loadaddr} 0x2720000 ${filesize}
(3) Power on the Arria® 10 SoC Development Kit again and boot Linux. To log in, use "root" as the user name and no password:
U-Boot SPL 2022.07 (Jan 06 2023 - 03:46:57 +0000)
FPGA: Checking FPGA configuration setting ...
FPGA: Start to program peripheral/full bitstream ...
FPGA: Early Release Succeeded.
FPGA: Checking FPGA configuration setting ...
FPGA: Start to program peripheral/full bitstream ...
FPGA: Early Release Succeeded.
U-Boot SPL 2022.07 (Jan 06 2023 - 03:46:57 +0000)
DDRCAL: Success
DDRCAL: Scrubbing ECC RAM (1024 MiB).
DDRCAL: SDRAM-ECC initialized success with 332 ms
FPGA: Checking FPGA configuration setting ...
FPGA: Start to program core bitstream ...
Full Configuration Succeeded.
FPGA: Enter user mode.
WDT: Started watchdog@ffd00300 with servicing (10s timeout)
Trying to boot from SPI
U-Boot 2022.07 (Jan 06 2023 - 03:46:57 +0000)socfpga_arria10
CPU: Altera SoCFPGA Arria 10
BOOT: QSPI Flash (1.8V)
Model: Altera SOCFPGA Arria 10
DRAM: 1 GiB
Core: 73 devices, 19 uclasses, devicetree: separate
WDT: Started watchdog@ffd00300 with servicing (10s timeout)
Loading Environment from SPIFlash... SF: Detected n25q00a with page size 256 Bytes, erase size 4 KiB, total 128 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Model: Altera SOCFPGA Arria 10
Net:
Warning: ethernet@ff800000 (eth0) using random MAC address - e2:6b:56:db:60:92
eth0: ethernet@ff800000
Hit any key to stop autoboot: 0
SF: Detected n25q00a with page size 256 Bytes, erase size 4 KiB, total 128 MiB
device 0 offset 0x1200000, size 0x6e00000
SF: 115343360 bytes @ 0x1200000 Read: OK
## Loading kernel from FIT Image at 02100000 ...
Using 'conf' configuration
Trying 'kernel' kernel subimage
Description: Linux Kernel
Type: Kernel Image
Compression: uncompressed
Data Start: 0x021000cc
Data Size: 14376840 Bytes = 13.7 MiB
Architecture: ARM
OS: Linux
Load Address: 0x00008000
Entry Point: 0x00008000
Verifying Hash Integrity ... OK
## Loading fdt from FIT Image at 02100000 ...
Using 'conf' configuration
Trying 'fdt' fdt subimage
Description: Linux DTB
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x02eb60f0
Data Size: 26032 Bytes = 25.4 KiB
Architecture: ARM
Verifying Hash Integrity ... OK
Booting using the fdt blob at 0x2eb60f0
Loading Kernel Image
Loading Device Tree to 09ff6000, end 09fff5af ... OK
Starting kernel ...
Deasserting all peripheral resets
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 5.15.70-153198-gf87aaa2c4d7c-dirty (ubuntu@ubuntu1804) (arm-none-linux-gnueabihf-gcc (GNU Toolchain for the Arm Architecture 11.2-2022.02 (arm-11.14)) 11.2.1 20220111, GNU ld (GNU Toolchain for the Arm Architecture 11.2-2022.02 (arm-11.14)) 2.37.20220122) #1 SMP Thu Apr 13 18:02:02 JST 2023
[ 0.000000] CPU: ARMv7 Processor [414fc091] revision 1 (ARMv7), cr=10c5387d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] OF: fdt: Machine model: Altera SOCFPGA Arria 10
- omitted -
[ 5.201802] socfpga-dwmac ff800000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0
[ 5.222631] dwmac1000: Master AXI performs any burst length
[ 5.228199] socfpga-dwmac ff800000.ethernet eth0: No Safety Features support found
[ 5.235756] socfpga-dwmac ff800000.ethernet eth0: IEEE 1588-2008 Advanced Timestamp supported
[ 5.244458] socfpga-dwmac ff800000.ethernet eth0: registered PTP clock
[ 5.254250] socfpga-dwmac ff800000.ethernet eth0: configuring for phy/rgmii link mode
udhcpc: started, v1.35.0
udhcpc: broadcasting discover
udhcpc: broadcasting discover
udhcpc: broadcasting discover
udhcpc: no lease, forking to background
done.
Starting OpenBSD Secure Shell server: sshd
done.
Starting syslogd/klogd: done
Poky (Yocto Project Reference Distro) 4.0.8 arria10 /dev/ttyS0
arria10 login: root
root@arria10:~#
The above generated boot loader for QSPI was confirmed to boot Linux.
2-4. Arria® 10 SoC boot loader build (for NAND boot)
Note:
* The instructions in this article assume that a standard 1Gb NAND part (part number: MT29F1G08ABBEAH4:E, marking: NW360) is used .
* Newer development kits may use 8Gb NAND parts (part number: MT29F8G08ABBCAH4-IT:C, marking: NQ299) .
If the new 8Gb part number is used, the following changes will be required:
-
- Ensure that all items in the flash are aligned to the new erase block size (256KB).
- Verify that the JFFS2 image uses the new parameters (256KB block erase size, 2048 page size).
- Increase the size of the RootFs partition to use the remaining flash.
2-4-1. Setup
(1) Create a Top folder:
$ sudo rm -rf a10_example.nand
$ mkdir a10_example.nand
$ cd a10_example.nand
$ export TOP_FOLDER='pwd'
(2) Get the hardware design from GitHub, update it for NAND, and build it. Delete the already compiled software folder in it:
$ cd $TOP_FOLDER
$ rm -rf ghrd-socfpga-QPDS22.4_REL_GSRD_PR QPDS22.4_REL_GSRD_PR.zip a10_soc_devkit_ghrd
$ wget https://github.com/altera-opensource/ghrd-socfpga/archive/refs/tags/QPDS22.4_REL_GSRD_PR.zip
$ unzip QPDS22.4_REL_GSRD_PR.zip
$ mv ghrd-socfpga-QPDS22.4_REL_GSRD_PR/a10_soc_devkit_ghrd_pro a10_soc_devkit_ghrd
$ rm -rf ghrd-socfpga-QPDS22.4_REL_GSRD_PR QPDS22.4_REL_GSRD_PR.zip
$ cd a10_soc_devkit_ghrd
$ make clean && make scrub_clean && rm -rf software
$ sed -i 's/HPS_BOOT_DEVICE .= .*/HPS_BOOT_DEVICE := NAND/g' Makefile
$ ~/intelFPGA_pro/22.4/nios2eds/nios2_command_shell.sh \
make generate_from_tcl
$ ~/intelFPGA_pro/22.4/nios2eds/nios2_command_shell.sh \
make rbf
2-4-2. Build U-Boot
(1) Clone the git tree and check out the supported branches to get the U-Boot source code:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/
$ rm -rf software/bootloader
$ mkdir -p software/bootloader
$ cd software/bootloader
$ git clone https://github.com/altera-opensource/u-boot-socfpga
$ cd u-boot-socfpga
# If you are using the latest U-Boot branch, comment out the following line
# $ git checkout -b test-bootloader -t origin/socfpga_v2022.07
(2) Convert the hps.xml handoff file to the include file used in the device tree. This will create arch/arm/dts/socfpga_arria10_socdk_nand_handoff.h:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga
$ .//arch/arm/mach-socfpga/qts-filter-a10.sh \
../../../hps_isw_handoff/hps.xml \
arch/arm/dts/socfpga_arria10_socdk_nand_handoff.h
(3) Configure and build U-Boot:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga
$ export ARCH=arm
$ export CROSS_COMPILE=arm-none-linux-gnueabihf-
$ make socfpga_arria10_nand_defconfig
$ make -j 48
This will build the following files in the $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga folder:
Table 6. Files generated by the build
| File | Description |
| spl/u-boot-splx4.sfp | Bootable image containing 4 SPL binaries in the format required by BootROM |
| u-boot.img | U-Boot image |
(4) Create a FIT image containing the FPGA programming file that SPL uses to configure the FPGA. This will create the fit_spl_fpga.itb file:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga
$ ln -s ../../../output_files/ghrd_10as066n2.core.rbf .
$ ln -s ../../../output_files/ghrd_10as066n2.periph.rbf .
$ tools/mkimage -E -f board/altera/arria10-socdk/fit_spl_fpga.its fit_spl_fpga.itb
(5) Create a FIT image of U-Boot. This will create the fit_uboot.itb file:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga
$ tools/mkimage -E -f board/altera/arria10-socdk/fit_uboot.its fit_uboot.itb
(6) Create a FIT image of the Linux kernel and device tree. This will create the kernel.itb file:
$ cd $TOP_FOLDER/a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga
$ export LINUX_BIN=~/linux-bin ← export the path of LINUX_BIN
$ ln -s $LINUX_BIN/a9/Image .
$ ln -s $LINUX_BIN/a9/socfpga_arria10_socdk_nand.dtb .
$ tools/mkimage -f board/altera/arria10-socdk/fit_kernel_nand.its kernel.itb
2-4-3. Building NAND Binaries
(1) Create nand_bin folder and import all files:
$ cd $TOP_FOLDER/
$ rm -rf nand_bin && mkdir nand_bin && cd nand_bin
$ cp ../a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga/spl/u-boot-splx4.sfp .
$ cp ../a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga/fit_uboot.itb .
$ cp ../a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga/fit_spl_fpga.itb .
$ cp ../a10_soc_devkit_ghrd/software/bootloader/u-boot-socfpga/kernel.itb .
(2) Prepare JFFS2 rootfs image to boot Linux from NAND:
$ cd $TOP_FOLDER/nand_bin
$ rm -rf rootfs
$ mkdir rootfs
$ cd rootfs
$ tar xf $LINUX_BIN/a9/core-image-minimal-arria10.tar.gz
$ rm -rf lib/modules
$ cd ..
$ mkfs.jffs2 -r rootfs -n -p --faketime --output=rootfs.jffs2 --squash -s 2048 -e 128KiB
$ rm -rf rootfs
(3) At this point, the following binaries are stored in $TOP_FOLDER/nand_bin:
Table 7. Files used for Linux boot
| File | Description |
| u-boot-splx4.sfp | Four SPL binaries with BootROM header |
| fit_uboot.itb | U-Boot image |
| fit_spl_fpga.itb | FPGA configuration file |
| kernel.itb | Linux kernel and device tree |
| rootfs.jffs2 | Linux RootFs in jffs2 format |
2-4-4. Booting from NAND
(1) Verify that the Arria® 10 SoC Development Kit is equipped with a NAND boot flash daughter card and that NAND boot is enabled.
(2) Write the binary to the NAND flash:
Table 8. Correspondence between files and addresses to be written to NAND flash
| Address | Size | File | Description |
| 0x0000000 | 0x00100000 | u-boot-splx4.sfp | Four SPL binaries with BootROM header |
| 0x0100000 | 0x00100000 | fit_uboot.itb | U-Boot image |
| 0x0200000 | 0x00100000 | N/A | U-Boot environment |
| 0x0300000 | 0x00F00000 | fit_spl_fpga.itb | FPGA configuration file |
| 0x1200000 | 0x00E00000 | kernel.itb | Linux kernel and device tree |
| 0x0200000 | 0x06000000 | rootfs.jffs2 | Linux RootFs in jffs2 format |
Follow these steps to program the NAND flash with all binaries:
-
- Copy the binaries to the TFTP folder on the host machine.
- Run U-Boot from the debugger as shown in Arria 10 SoC - Run U-Boot from Debugger.
- Connect U-Boot to the network and specify the IP address of the host machine:
$ setenv autoload no
$ dhcp
$ setenv serverip <your_server_ip>
-
- U-Boot downloads binaries via TFTP and writes them to NAND:
$ nand erase clean 0x02000000 0x06000000; tftp ${loadaddr} rootfs.jffs2; nand write.trimffs ${loadaddr} 0x02000000 ${filesize}
$ nand erase 0x01200000 0x00E00000; tftp ${loadaddr} kernel.itb; nand write ${loadaddr} 0x01200000 ${filesize}
$ nand erase 0x00300000 0x00F00000; tftp ${loadaddr} fit_spl_fpga.itb; nand write ${loadaddr} 0x00300000 ${filesize}
$ nand erase 0x00100000 0x00100000; tftp ${loadaddr} fit_uboot.itb; nand write ${loadaddr} 0x00100000 ${filesize}
$ nand erase 0x00000000 0x00100000; tftp ${loadaddr} u-boot-splx4.sfp; nand write ${loadaddr} 0x00000000 ${filesize}
(3) Power on the Arria® 10 SoC Development Kit again and boot Linux. To log in, use "root" as the user name and no password:
FPGA: Early Release Succeeded.
FPGA: Checking FPGA configuration setting ...
FPGA: Start to program peripheral/full bitstream ...
FPGA: Early Release Succeeded.
U-Boot SPL 2022.07-23045-g123cc7934a (Apr 04 2023 - 14:39:15 +0900)
DDRCAL: Success
DDRCAL: Scrubbing ECC RAM (1024 MiB).
DDRCAL: SDRAM-ECC initialized success with 333 ms
FPGA: Checking FPGA configuration setting ...
FPGA: Start to program core bitstream ...
Full Configuration Succeeded.
FPGA: Enter user mode.
WDT: Started watchdog@ffd00300 with servicing (10s timeout)
Trying to boot from NAND
U-Boot 2022.07-23045-g123cc7934a (Apr 04 2023 - 14:39:15 +0900)socfpga_arria10
CPU: Altera SoCFPGA Arria 10
BOOT: NAND Flash (1.8V)
Model: Altera SOCFPGA Arria 10
DRAM: 1 GiB
Core: 72 devices, 18 uclasses, devicetree: separate
WDT: Started watchdog@ffd00300 with servicing (10s timeout)
NAND: 128 MiB
Loading Environment from NAND... *** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Model: Altera SOCFPGA Arria 10
Net:
Warning: ethernet@ff800000 (eth0) using random MAC address - 5a:ce:2b:fe:65:4a
eth0: ethernet@ff800000
Hit any key to stop autoboot: 0
NAND read: device 0 offset 0x1200000, size 0x6e00000
size adjusted to 0x6d80000 (4 bad blocks)
114819072 bytes read: OK
## Loading kernel from FIT Image at 02100000 ...
Using 'conf' configuration
Trying 'kernel' kernel subimage
Description: Linux Kernel
Type: Kernel Image
Compression: uncompressed
Data Start: 0x021000cc
Data Size: 14376840 Bytes = 13.7 MiB
Architecture: ARM
OS: Linux
Load Address: 0x00008000
Entry Point: 0x00008000
Verifying Hash Integrity ... OK
## Loading fdt from FIT Image at 02100000 ...
Using 'conf' configuration
Trying 'fdt' fdt subimage
Description: Linux DTB
Type: Flat Device Tree
Compression: uncompressed
Data Start: 0x02eb60f0
Data Size: 25651 Bytes = 25 KiB
Architecture: ARM
Verifying Hash Integrity ... OK
Booting using the fdt blob at 0x2eb60f0
Loading Kernel Image
Loading Device Tree to 09ff6000, end 09fff432 ... OK
Starting kernel ...
Deasserting all peripheral resets
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 5.15.70-153198-gf87aaa2c4d7c-dirty (ubuntu@ubuntu1804) (arm-none-linux-gnueabihf-gcc (GNU Toolchain for the Arm Architecture 11.2-2022.02 (arm-11.14)) 11.2.1 20220111, GNU ld (GNU Toolchain for the Arm Architecture 11.2-2022.02 (arm-11.14)) 2.37.20220122) #1 SMP Tue Mar 14 09:48:08 JST 2023
[ 0.000000] CPU: ARMv7 Processor [414fc091] revision 1 (ARMv7), cr=10c5387d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] OF: fdt: Machine model: Altera SOCFPGA Arria 10
- omitted -
[ 5.244458] socfpga-dwmac ff800000.ethernet eth0: registered PTP clock
[ 5.254250] socfpga-dwmac ff800000.ethernet eth0: configuring for phy/rgmii link mode
udhcpc: started, v1.35.0
udhcpc: broadcasting discover
udhcpc: broadcasting discover
udhcpc: broadcasting discover
udhcpc: no lease, forking to background
done.
Starting OpenBSD Secure Shell server: sshd
done.
Starting syslogd/klogd: done
Poky (Yocto Project Reference Distro) 4.0.8 arria10 /dev/ttyS0
arria10 login: root
root@arria10:~#
We have confirmed that Linux boots with the boot loader for NAND generated above.
Conclusion
This article described the old and new bootloader build flow in the case of the Arria® 10 SoC and the steps to build a bootloader on the Arria® 10 SoC.
We hope this will be helpful for bootloader generation.
Related Articles
- Altera® SoC FPGA Summary Page - (In Japanese)
- Bootloader generation flow for SoC EDS v19.1 std / v19.3 pro or later (Cyclone® V SoC / Arria® V SoC edition)
- Bootloader generation flow for SoC EDS v19.1 std / v19.3 pro or later (Appendix: Building Linux binaries - Cyclone® V SoC / Arria® 10 SoC edition)