Introduction
This article describes how to configure the FPGA side of the Cyclone® V SoC / Arria® V SoC for QSPI booting from the U-Boot.
Note: This article is for SoC EDS v19.1 or later (SoC EDS does not come with U-Boot).
The official procedure for generating a bootloader for QSPI boot is described in "Cyclone V SoC - Boot from QSPI" in "Building Bootloader for Cyclone V and Arria 10 | Documentation | RocketBoards.org". However, the procedure assumes that the FPGA configuration is performed independently of the HPS (Hard Processor System) boot, and does not describe how to configure the FPGA from U-Boot.
Therefore, this article provides additional information on how to configure the FPGA from the U-Boot during QSPI boot.
The following environment is used as the system requirements at the time of writing this article.
[Table 1] System Requirements
| No. | Item | Description |
| 1 | Development Tools |
(1) Quartus® Prime v21.1 Standard Edition As for Linux OS, Ubuntu 18.04 LTS or later version is recommended as described on page of Building Bootloader for Cyclone V and Arria 10 |
| 2 | Reference Designs | QPDS-22.1pro-21.1std.zip |
| 3 | U-Boot Branch | u-boot-socfpga_v2022.04 |
| 4 | Linux Branch | linux-socfpga-5.15.60-lts |
| 5 | Tool chain | gcc-arm-11.2-2022.02-x86_64-arm-none-linux-gnueabihf |
Note:
*1: Yocto Project does not support WSL.
*2: Please refer to the following contents for more information on building a WSL environment.
Building Preloader / U-Boot with WSL [Part 1: Environment setup]
1. Bootloader modification and build: .dts file modification
This chapter describes how to add a partition to the .dts file to store FPGA configuration data.
In the default state of the U-Boot Device Tree Source (.dts) file for the Cyclone® V SoC Development Kit, only the bootloader and Linux partitions are defined. A partition for storing FPGA configuration data must be added here.
1-1. Retrieving the U-Boot Source Tree and Reflecting Handoff Information
Before modifying the .dts file, follow the "B. U-Boot" procedure in "Cyclone V SoC - Boot from QSPI" from the beginning to the point where qts-filter.sh is executed (see [Figure 1]). Red frame execute the following procedure in advance.
[Figure 1] Explanation of "B. U-Boot" in "Cyclone V SoC - Boot from QSPI"
1-2. Edit the device tree (add partitions to the definition for QSPI Flash)
Add a partition for storing FPGA configuration data to the .dts file of the U-Boot source tree.
[Target .dts file for Cyclone® V SoC Development Kit]
・ u-boot-socfpga/arch/arm/dts/socfpga_cyclone5_socdk.dts
・ u-boot-socfpga/arch/arm/dts/socfpga_cyclone5_socdk-u-boot.dtsi
[Target .dts file for Arria® V SoC Development Kit]
・ u-boot-socfpga/arch/arm/dts/socfpga_arria5_socdk.dts
・ u-boot-socfpga/arch/arm/dts/socfpga_arria5_socdk-u-boot.dtsi
[Figure 2] Modification of .dts file
Note: The .dts file included in the U-Boot source tree socfpga_arria5_socdk-u-boot.dtsi in the U-Boot source tree does not include a description of the QSPI Flash partition definitions, please write all partitions other than those for storing FPGA configuration data, as in the file for the Cyclone® V SoC Development Kit.
Note: For the Arria® V SoC Development Kit, change the size allocated to the qspi-rootfs partition from the default 120MB to 112MB, and add qspi-fpga as the partition for storing the FPGA Image from start address 0x7800000 to 8 We recommend that you try adding 8 MBytes of definitions to the FPGA image storage partition, starting at address 0x7800000.
Reference: The QSPI memory size of the Cyclone® V SoC / Arria® V SoC Development Kit is as follows
・ Cyclone® V SoC Development Kit ⇒ 64 MByte (512 Mbit)
Cyclone® V SoC FPGA Development Board Reference Manual
[Figure 3] QSPI Memory Size of Cyclone® V SoC Development Kit
・ Arria® V SoC Development Kit ⇒ 128 MByte (1 Gbit)
Arria® V SoC FPGA Development Board Reference Manual
[Figure 4] QSPI Memory Size of Arria® V SoC Development Kit
1-3. Building the U-Boot Binary
After modifying the .dts file, save the file and follow the steps in "B. U-Boot" in " Cyclone V SoC - Boot from QSPI " to build the U-Boot binary.
[Figure 5] Building the U-Boot Binary
Reference: The device tree blob (.dtb) file to be used is selected by the definitions of CONFIG_DEFAULT_DEVICE_TREE and CONFIG_DEFAULT_FDT_FILE specified in the defconfig file.
<< In the case of the Cyclone® V SoC Development Kit >>
・ Example: u-boot-socfpga/configs/socfpga_cyclone5_defconfig
[Figure 6] socfpga_cyclone5_defconfig example
・ Example: u-boot-socfpga/configs/socfpga_cyclone5_qspi_defconfig
[Figure 7] socfpga_cyclone5_qspi_defconfig example
For Arria® V SoC Development Kit, also u-boot-socfpga/configs/socfpga_arria5_defconfig file.
2. Writing boot loader and config data: storing to QSPI flash
In this chapter, we will write the FPGA configuration data to the FPGA configuration partition of the QSPI flash defined in the .dts file.
Reference: The command examples in "Cyclone V SoC - Boot from QSPI" and in this article use the Nios II Command Shell, but the SoC Embedded Command Shell is also supported. If necessary, replace the following commands to support the SoC Embedded Command Shell.
・ ~/intelFPGA/21.1/nios2eds/nios2_command_shell.sh (Nios II Command Shell)
・ ~/intelFPGA/20.1/embedded/embedded_command_shell.sh (SoC Embedded Command Shell)
2-1. Generating FPGA configuration data
FPGA configuration data is generated from .sof (SRAM Object File) to .rbf (RAW Binary File) using the quartus_cpf command line utility.
Performing the procedure (make sof) in "A. Setup" in "Cyclone V SoC - Boot from QSPI" will generate a soc_system.sof file under the cv_soc_devkit_ghrd/output_files directory. Convert this file to soc_system.rbf.
[Figure 8] Compiling the Hardware Design
There are two ways to do this:
(a) After executing the make sof command, execute the following make rbf command to generate the soc_system.rbf file according to the instruction in the Makefile.
cd cv_soc_devkit_ghrd |
(b) Convert soc_system.sof to soc_system.rbf by the following quartus_cpf command line.
The -c option indicates file conversion (convert).
The -o bitstream_compression=on option indicates to generate a compressed .rbf file.
cd cv_soc_devkit_ghrd |
Reference: FAQ: How can I convert SOF files to RBF files without using the Quartus II GUI?
2-2 Storing to QSPI Flash
2-2-1. Copy the file to be written to the working directory
Refer to the “Create qspi_bin folder and bring all the files:” section under “C. QSPI Binaries” in the "Cyclone V SoC - Boot from QSPI" documentation. Copy the soc_system.rbf file to the $TOP_FOLDER/qspi_bin directory.
[Figure 9] Create $TOP_FOLDER/qspi_bin directory and copy files
Copy the soc_system.rbf file to the qspi_bin directory by adding the command in red text below.
cd $TOP_FOLDER/ |
2-2-2. Writing to QSPI Flash
Referring to the description of "Flash the QSPI binaries:" in "D. Boot" of "Cyclone V SoC - Boot from QSPI", use the quartus_hps tool to write various binary files to the QSPI flash memory. Write the various binary files to the QSPI flash memory with the quartus_hps tool.
When writing, the soc_system.rbf file, which is the FPGA configuration data, specifies the start address of the partition storing the FPGA configuration data, as modified in the chapter "1. Bootloader modification and build: .dts file modification". (For the purposes of this article, using the Cyclone® V SoC Development Kit as an example, the data is written to address 0x3C00000)
[Figure 10] Writing a Binary File to QSPI Flash
The red frame in the table below shows that in the case of the Cyclone® V SoC Development Kit, the FPGA configuration data is written to the 0x3C00000 address.
[Figure 11] Address Map of Data to be Written to QSPI Flash
For the Cyclone® V SoC Development Kit, set the BSEL jumper to boot from the 3.3V QSPI device as follows:
・ BSEL2=1 (left)
・ BSEL1=1 (left)
・ BSEL0=1 (left)
Then, use the command in the red text below to write the soc_system.rbf file, which contains the FPGA configuration data, to address 0x3C00000 in the QSPI flash memory.
cd $TOP_FOLDER/qspi_bin |
Note: Writing large files such as soc_system.rbf takes time.
Reference: It is possible to erase the entire QSPI flash with the following command.
~/intelFPGA/21.1/nios2eds/nios2_command_shell.sh quartus_hps -c 1 -o E |
3. Run configuration: check operation by U-Boot command
In this chapter, we will check the operation of FPGA configuration using the U-Boot command in QSPI boot on the Cyclone® V SoC Development Kit.
Reference: The U-Boot commands used to configure the FPGA include the following.
・ Commands to read data from QSPI to RAM (sf probe, sf read)
sf probe initializes the flash device on the specified SPI bus and chip select.
sf read read reads from the start of the 'len' byte or mtd 'partition' starting with 'offset' into the 'addr' memory.
[Figure 12] U-Boot sf command
・ The fpga load command loads the FPGA device from the RAM buffer.
fpga load loads the FPGA configuration data in RAM into the FPGA device.
[Figure 13] U-Boot fpga command
3-1. Checking U-Boot environment variables
First, check the U-Boot's printenv command to check the current U-Boot environment variables. The following yellow text are the environment variables related to boot.
[Figure 14] Confirmation of U-Boot environment variables using the U-Boot printenv command
In the boot-related environment variables in the above figure,
・ bootcmd is the starting point of the boot, executing the bridge enable command and run bootcmd_qspi.
・ bootcmd_qspi executes run qspiload and run qspiboot.
・ qspiload initializes QSPI flash device by sf probe command and reads Linux Kernel and Root Filesystem (jffs2) stored in QSPI flash to RAM by sf read command.
・ qspiboot boots Linux using the data extracted on RAM.
3-2. Editing U-boot Environment Variables
From the U-Boot prompt, enter the command shown in red text below to execute the FPGA configuration. Add `qspifpga` to the U-Boot environment variables and configure it to run `qspifpga` from `bootcmd_qspi` using the `setenv` command.
After configuration, save the settings to the U-Boot environment variables using the `saveenv` command.
=> setenv qspifpga sf probe\; sf read 0x4000000 0x03C00000 0x400000\; fpga load 0 0x4000000 0x400000\; |
Here, if you use the printenv command again to check the contents of the U-Boot environment variables, you should see that qspifpga has been added, as indicated by the green text, and that bootcmd_qspi is configured to execute run qspifpga.
[Figure 15] printenv after changing the U-Boot environment variable
3-3. Operation check (Boot execution)
After confirming that the FPGA configuration description is correctly set in the U-Boot environment variables, verify that the FPGA is configured from U-Boot using the boot command or by turning the power on again. The figure below shows the boot command being executed.
The section highlighted in yellow text in the figure below shows the process of unfolding the FPGA configuration data from QSPI address 0x3C00000 into RAM and loading it into the FPGA.
The section highlighted in green text shows the process of unfolding the Linux kernel image (zImage) file from QSPI address 0x0230000 into RAM.
The blue text section shows the Linux device tree (socfpga_cyclone5_socdk.dtb) being expanded from QSPI address 0x0220000 into RAM.
Ultimately, this sequence leads to Linux booting.
[Figure 16] Booting by boot command and checking FPGA configuration
4. Supplemental: Adding descriptions to the U-Boot source code (Embedding settings in the boot loader)
In the previous chapter, we explained how to perform FPGA configuration by adding the FPGA configuration mechanism to the U-boot environment variables using the setenv / saveenv commands from the U-boot command prompt. However, a more permanent solution may be to generate U-boot by adding the FPGA configuration mechanism to the socfpga_common.h and socfpga_arria5_socdk.h files.
4-1. Cyclone® V SoC QSPI Boot Mechanism in U-Boot
This section first describes the default Cyclone® V SoC Development Kit QSPI boot mechanism in the U-Boot source code.
- In the u-boot-socfpga/configs/socfpga_cyclone5_qspi_defconfig file, the following is written as CONFIG_BOOTCOMMAND. This opens the bridge between HPS and FPGA and executes bootcmd_qspi.
[Figure 17] CONFIG_BOOTCOMMAND definition in socfpga_cyclone5_qspi_defconfig file
- In the u-boot-socfpga/include/configs/socfpga_common.h file, the following is described as BOOTENV_DEV_QSPI. This will cause the bootcmd_qspi will be replaced by the qspiload and qspiboot and qspiboot.
[Figure 18] BOOTENV_DEV_QSPI definition in socfpga_common.h file
- In u-boot-socfpga/include/configs/socfpga_cyclone5_socdk.h file, qspiload and qspiboot are described as follows This expands the Linux kernel and root file system located in QSPI onto RAM for execution.
[Figure 19] Definition of qspiload and qspiboot in socfpga_cyclone5_socdk.h file
4-2. Adding FPGA Configuration Descriptions to the Header File
Let's add FPGA configuration descriptions to the socfpga_common.h and socfpga_cyclone5_socdk.h files described in the previous section.
(1) First, add the statement run qspifpga; to the u-boot-socfpga/include/configs/socfpga_common.h file.
#define BOOTENV_DEV_QSPI(devtypeu, devtypel, instance) \ |
(2) Continue by adding the FPGA configuration description to the u-boot-socfpga/include/configs/socfpga_cyclone5_socdk.h file. (Red text)
|
/* QSPI boot */ #define SOCFPGA_BOOT_SETTINGS \ |
(3) Regenerate U-boot using the modified socfpga_common.h and socfpga_cyclone5_socdk.h files. Then check if the FPGA configuration is executed by U-boot.
Conclusion
This article provided supplementary information on performing FPGA configuration from U-Boot during QSPI boot, as described on the “Building Bootloader for Cyclone V and Arria 10” page at Rocketboards.org.
We hope you find it helpful for FPGA configuration when booting from QSPI.