07 February 2024 - 13:40
| |
Version 32
|
JedAlthouse
| A10, Development Kit, Flash, Flash Programming, NAND, QSPI, SD, SDMMC, TFTP, bad block, eMMC
Introduction
This page presents a script that uses the DS-5 debugger and U-Boot to program the NAND and QSPI flash on an Arria 10 Development board.

This script can be useful for the following purposes:
- Increased programming speed as compared to HPS Flash Programmer (quartus_hps) that is intended only for programming small files
- Dealing with NAND bad block tables (current 16.1 version of quartus_hps does not manage and can overwrite NAND bad block tables)
- Programming SD cards remotely, when they cannot be removed from the socket and programmed with an USB adapter
- Programming eMMC boot cards
The script also supports QSPI, SD and eMMC and support for additional SoCs and boards can be relatively easily added.
The script supports downloading the image through JTAG or TFTP. TFTP is several times faster than JTAG.
It is highly recommended to use TFTP image transfer when programming large eMMC or SD images.
Prerequisites
The following are required in order to run the script
- Arria 10 Development Kit rev. B and C with
- Arria 10 NAND Bootcard - for NAND operation
- Arria 10 QSPI Bootcard - for QSPI operation
- Arria 10 Micro SD Bootcard - for SD operation
- Customer-provided Arria 10 eMMC Bootcard - for eMMC operation
- SoC EDS 16.1, including the optional Quartus Prime Programmer
- ARM DS-5 license - required because the script uses the debugger to download an instrumented version of the bootloader to the board and automate it
The deliverables includes the precompiled hardware designs and bootloaders necessary for the script operation. If these need to be modified to fit another board and/or recompiled, the following are also required:
- Quartus Prime 16.1 - for compiling the hardware design
- SoC EDS 16.1 - Linux version for compiling the bootloader
Operation
This section presents details on how to use the script.
A few important notes are:
- The script needs to be executed from an Embedded Command Shell, both on Windows and Linux
- The script assumes a single USB Blaster cable is connected to the host
- Error detection in the script can be improved
- The script tries to output as much information as possible about what it is doing:
- Output of different commands: displayed in gray or magenta
- Error messages: displayed in red
- Bootloader console messages: displayed in yellow
- The script creates the following temporary files:
- ___tmp_quartus_hps.script - script used to detect the soc and flash memory by using quartus_hps
- ___tmp_ds5-debugger-script.ds5 - ds-5 script used to automate u-boot loading and operation
- ___tmp_ds5_uboot_console.txt - U-Boot console output
Installation
The script is delivered as an archive attached to this page. The archive needs to be extracted, then the script can be ran from an Embedded Command Shell. Th archive contains the following:
Item |
Description |
---|
a10_sdmmc_devkit_revb_design |
A10 SDMMC programmer support binaries for Rev B DevKit |
a10_sdmmc_devkit_revc_design |
A10 SDMMC programmer support binaries for Rev C DevKit |
a10_nand_devkit_revb_design |
A10 NAND programmer support binaries for Rev B DevKit |
a10_nand_devkit_revc_design |
A10 NAND programmer support binaries for Rev C DevKit |
a10_qspi_devkit_revb_design |
A10 QSPI programmer support binaries for Rev B DevKit |
a10_qspi_devkit_revc_design |
A10 QSPI programmer support binaries for Rev B DevKit |
flash_programmer.py |
Python programmer script |
The following commands can be used on a Linux host machine:
cd~
wget https://rocketboards.org/foswiki/pub/Documentation/Arria10NANDFlashProgramming/flash_programmer.tgz
tar xzf flash_programmer.tgz
cd flash_programmer
~/altera/16.1/embedded/embedded_command_shell.sh
./flash_programmer.py --help
Use equivalent commands on a Windows host machine.
Basic Usage
The basic usage of the script is as follows:
# start an Embedded Command Shell
~/intelFPGA/16.1/embedded/embedded_command_shell.sh
# change current folder to the flash programmer folder
cd ~/flash_programmer
# call the programmer script
./flash_programmer.py \
[--board=board_name] \
[--soc=a10] \
[--flash=nand|qspi|sdmmc] \
--operation=operation \
[--address=hex_address] \
[--size=hex_size] \
[--file=file_to_be_flashed] \
[--help]
Parameter |
Description |
---|
--board |
Target board. Currently defaults to 'devkit_revc' - the only board that is supported |
--soc |
Target SoC. Currently only 'a10' is supported. The script will auto-detect the soc if not supplied |
--flash |
Target flash. The 'nand', 'qspi' and 'sdmmc' are supported. The script will autodetect the flash based on BSEL if not supplied |
--operation |
Requested operation: a combination of letters 's' - display flash information and exit, 'e' - erase, 'p' - program, 'v' - verify, 'E' - erase NAND using clean option, 'P' - program NAND using trimffs option |
--address |
Target flash address: hexadecimal number, starting with '0x' |
--size |
Target flash size: hexadecimal number, starting with '0x' |
--file |
File to be used |
--help |
Display help message |
Important Notes:
- 'size' can be omitted, and in that case the actual file size will be used
- 'size' can be greater than the actual file size. In this case the programmer with pad the image with '0xff'.
- 'address' can be omitted if beginning of flash is targeted (it defaults to '0x0')
TFTP Usage
Instead of downloading the flash image through JTAG, it can also be downloaded with the aid of a TFTP server, which is several times faster. The TFTP usage requires the following:
- Installing or running a TFTP server on the local machine
- Configuring the local firewall to allow TFTP connections
- Additional local ethernet drop or local network switch
- Existence of local network DHCP server
The following additional flash_programmer.py parameters need to be used to enable TFTP image transfer:
Parameter |
Description |
---|
--use-tftp |
Use 'yes' or 'true' to tell script to use TFTP |
--tftp-sever |
IP Address of the local machine, where TFTP server runs |
--tftp-folder |
Local folder where the TFTP serves the files from |
--mac-address |
MAC address to be used by the board |
Usage Examples
Example |
Description |
---|
./flash_programmer.py --flash=nand --operation=e |
Erase the whole NAND flash chip. Targets thes default 'devkit_revc' board |
./flash_programmer.py --flash=sdmmc --operation=pv --file=c:/emmc_image.img \ --use-tftp="yes" --tftp-server="192.168.10.105" --tftp-folder="c:/tftproot" \ --mac-address="B4:B5:2F:A0:93:4D" |
Write image to eMMC Card, transferring image through TFTP. Targets the default 'devkit_revc' board |
./flash_programmer.py --board=devkit_revb --flash=nand --operation=epv \ --address=0x100000 --size=0x2000000 \ --file=ghrd_10as066n2.rbf.mkimage |
Erase 0x2000000 bytes (32MB) of NAND starting at address 0x100000 then write the file ghrd_10as066n2.rbf.mkimage padded with 0xff to 16MB, then read back and verify the result. Targets the 'devkit_revb' board |
Here are some screenshots when the script is used to erase NAND flash as described in the first example above:
1. Command being issued, script detecting JTAG connection and which soc is used, then programming the FPGA:

2. DS-5 script being created, and DS-5 debugger being invoked to execute that script:

3. U-Boot console messages shown in yellow:

4. U-Boot NAND erase complete and script exit:
The following table presents the duration of several programming scenarios, to allow the user to assess suitability for their particular scenario:
Flash |
Size |
Verification |
Transfer |
Duration |
---|
QSPI |
128MB |
yes |
JTAG |
35min |
^ |
^ |
^ |
TFTP |
9min |
NAND |
80MB |
yes |
JTAG |
13min |
^ |
^ |
^ |
TFTP |
9min |
SDMMC |
2GB |
no |
JTAG |
2h30min |
^ |
^ |
yes |
^ |
2h40min |
^ |
^ |
no |
TFTP |
34min |
^ |
^ |
yes |
^ |
44min |
It is highly recommended to use TFTP image transfer when programming large eMMC or SD images.
Known Issues
These are the known issues:
- In some situations the script can fail (for example due to incorrect parameters). In such cases the execution can be interrupted with the CTRL-C sequence
- When the script was forcefully interrupted with CTRL-C, the console text color can remain set to the last color used by the script. This can typically be remedied by using the 'reset' terminal command.
- On Windows, when the script was forcefully interrupted with CTRL-C, some of the temporary files may remain opened. If this happens, trying to run the script again will signal the error that the temporary file cannot be created. In such a case, the Embedded Command Shell window needs to be closed, and another one opened.
Rebuilding the Script Binaries
The script relies on pre-compiled versions of the Hardware Design and Bootloaders targeting A10 DevKit revisions B & C, NAND and QSPI.
The script determines the location of the pre-compiled binaries by concatenating the following items, with underscores in between:
For the provided configurations, these folder names are:
Folder |
Description |
---|
a10_sdmmc_devkit_revb_design |
A10 SDMMC programmer support binaries for Rev B DevKit |
a10_sdmmc_devkit_revc_design |
A10 SDMMC programmer support binaries for Rev C DevKit |
a10_nand_devkit_revb_design |
A10 NAND programmer support binaries for Rev B DevKit |
a10_nand_devkit_revc_design |
A10 NAND programmer support binaries for Rev C DevKit |
a10_qspi_devkit_revb_design |
A10 QSPI programmer support binaries for Rev B DevKit |
a10_qspi_devkit_revc_design |
A10 QSPI programmer support binaries for Rev B DevKit |
For each configuration the following files are needed:
File |
Description |
---|
output_files/ghrd_10as066n2.sof |
FPGA configuration file |
software/bootloader_extcfg_semihosting/devicetree.dtb |
Bootloader device tree binary |
software/bootloader_extcfg_semihosting/uboot-socfpga/u-boot |
Bootloader executable |
This section presents the complete instructions on how the binaries were obtained, in case modifications are needed, for example for targeting another board.
NAND
The commands for re-creating the NAND binaries for
rev C board are listed below:
# Start an embedded command shell
~/intelFPGA/16.1/embedded/embedded_command_shell.sh
mkdir -p ~/flash_programmer
cd ~/flash_programmer
# Create NAND hardware design
mkdir a10_nand_devkit_revc_design
cd a10_nand_devkit_revc_design
tar xvzf ~/intelFPGA/16.1/embedded/examples/hardware/a10_soc_devkit_ghrd/tgz/*.tar.gz
make scrub_clean
sed -i 's/HPS_BOOT_DEVICE := SDMMC/HPS_BOOT_DEVICE := NAND/g' Makefile
make generate_from_tcl
# Build NAND hardware design
make sof
# Generate and build bootloader
mkdir -p software/bootloader_extcfg_semihosting
bsp-create-settings --type uboot --bsp-dir software/bootloader_extcfg_semihosting --preloader-settings-dir "hps_isw_handoff" --settings software/bootloader_extcfg_semihosting/settings.bsp --set uboot.external_fpga_config true
sed -i 's/BOOT_DEVICE := SDMMC/BOOT_DEVICE :=NAND/g' software/bootloader_extcfg_semihosting/config.mk
make -C software/bootloader_extcfg_semihosting
make -C software/bootloader_extcfg_semihosting clean
sed -i 's/#undef CONFIG_SEMIHOSTING/#define CONFIG_SEMIHOSTING/g' software/bootloader_extcfg_semihosting/uboot-socfpga/include/configs/socfpga_arria10.h
sed -i "s/putc('#');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
sed -i 's/puts("\\n\\t ');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
make -C software/bootloader_extcfg_semihosting
The commands for re-creating the NAND binaries for
rev B board are listed below:
# Start an embedded command shell
~/intelFPGA/16.1/embedded/embedded_command_shell.sh
mkdir -p ~/flash_programmer
cd ~/flash_programmer
# Create NAND hardware design
mkdir a10_nand_devkit_revb_design
cd a10_nand_devkit_revb_design
tar xvzf ~/intelFPGA/16.1/embedded/examples/hardware/a10_soc_devkit_ghrd/tgz/*.tar.gz
make scrub_clean
sed -i 's/HPS_BOOT_DEVICE := SDMMC/HPS_BOOT_DEVICE := NAND/g' Makefile
sed -i 's/QUARTUS_DEVICE := 10AS066N3F40E2SG/QUARTUS_DEVICE := 10AS066N3F40E2SGE2/g' Makefile
sed -i 's/set FPGA_DEVICE 10AS066N3F40E2SG/set FPGA_DEVICE 10AS066N3F40E2SGE2/g' design_config.tcl
sed -i 's/set FPGA_DEVICE 10AS066N3F40E2SG/set FPGA_DEVICE 10AS066N3F40E2SGE2/g' ip/diffin/construct_diffin.tcl
sed -i 's/set_global_assignment -name DEVICE 10AS066N3F40E2SG/set_global_assignment -name DEVICE 10AS066N3F40E2SGE2/g' synth_v2.qsf
make generate_from_tcl
# Build NAND hardware design
make sof
# Generate and build bootloader
mkdir -p software/bootloader_extcfg_semihosting
bsp-create-settings --type uboot --bsp-dir software/bootloader_extcfg_semihosting --preloader-settings-dir "hps_isw_handoff" --settings software/bootloader_extcfg_semihosting/settings.bsp --set uboot.external_fpga_config true
sed -i 's/BOOT_DEVICE := SDMMC/BOOT_DEVICE :=NAND/g' software/bootloader_extcfg_semihosting/config.mk
make -C software/bootloader_extcfg_semihosting
make -C software/bootloader_extcfg_semihosting clean
sed -i 's/#undef CONFIG_SEMIHOSTING/#define CONFIG_SEMIHOSTING/g' software/bootloader_extcfg_semihosting/uboot-socfpga/include/configs/socfpga_arria10.h
sed -i "s/putc('#');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
sed -i 's/puts("\\n\\t ');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
make -C software/bootloader_extcfg_semihosting
QSPI
The commands for creating the QSPI binaries for
revc C board are listed below:
# Start an embedded command shell
~/intelFPGA/16.1/embedded/embedded_command_shell.sh
mkdir -p ~/flash_programmer
cd ~/flash_programmer
# Create QSPI hardware design
mkdir a10_qspi_devkit_revc_design
cd a10_qspi_devkit_revc_design
tar xvzf ~/intelFPGA/16.1/embedded/examples/hardware/a10_soc_devkit_ghrd/tgz/*.tar.gz
make scrub_clean
sed -i 's/HPS_BOOT_DEVICE := SDMMC/HPS_BOOT_DEVICE := QSPI/g' Makefile
make generate_from_tcl
# Compile QSPI hardware design
make sof
# Generate and build bootloader
mkdir -p software/bootloader_extcfg_semihosting
bsp-create-settings --type uboot --bsp-dir software/bootloader_extcfg_semihosting --preloader-settings-dir "hps_isw_handoff" --settings software/bootloader_extcfg_semihosting/settings.bsp --set uboot.boot_device QSPI --set uboot.external_fpga_config true
make -C software/bootloader_extcfg_semihosting
make -C software/bootloader_extcfg_semihosting clean
sed -i 's/#undef CONFIG_SEMIHOSTING/#define CONFIG_SEMIHOSTING/g' software/bootloader_extcfg_semihosting/uboot-socfpga/include/configs/socfpga_arria10.h
sed -i "s/putc('#');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
sed -i 's/puts("\\n\\t ');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
make -C software/bootloader_extcfg_semihosting
The commands for re-creating the QSPI binaries for
rev B board are listed below:
# Start an embedded command shell
~/intelFPGA/16.1/embedded/embedded_command_shell.sh
mkdir -p ~/flash_programmer
cd ~/flash_programmer
# Create QSPI hardware design
mkdir a10_qspi_devkit_revb_design
cd a10_qspi_devkit_revb_design
tar xvzf ~/intelFPGA/16.1/embedded/examples/hardware/a10_soc_devkit_ghrd/tgz/*.tar.gz
make scrub_clean
sed -i 's/HPS_BOOT_DEVICE := SDMMC/HPS_BOOT_DEVICE := QSPI/g' Makefile
sed -i 's/QUARTUS_DEVICE := 10AS066N3F40E2SG/QUARTUS_DEVICE := 10AS066N3F40E2SGE2/g' Makefile
sed -i 's/set FPGA_DEVICE 10AS066N3F40E2SG/set FPGA_DEVICE 10AS066N3F40E2SGE2/g' design_config.tcl
sed -i 's/set FPGA_DEVICE 10AS066N3F40E2SG/set FPGA_DEVICE 10AS066N3F40E2SGE2/g' ip/diffin/construct_diffin.tcl
sed -i 's/set_global_assignment -name DEVICE 10AS066N3F40E2SG/set_global_assignment -name DEVICE 10AS066N3F40E2SGE2/g' synth_v2.qsf
make generate_from_tcl
# Compile QSPI hardware design
make sof
# Generate and build bootloader
mkdir -p software/bootloader_extcfg_semihosting
bsp-create-settings --type uboot --bsp-dir software/bootloader_extcfg_semihosting --preloader-settings-dir "hps_isw_handoff" --settings software/bootloader_extcfg_semihosting/settings.bsp --set uboot.boot_device QSPI --set uboot.external_fpga_config true
make -C software/bootloader_extcfg_semihosting
make -C software/bootloader_extcfg_semihosting clean
sed -i 's/#undef CONFIG_SEMIHOSTING/#define CONFIG_SEMIHOSTING/g' software/bootloader_extcfg_semihosting/uboot-socfpga/include/configs/socfpga_arria10.h
sed -i "s/putc('#');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
sed -i 's/puts("\\n\\t ');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
make -C software/bootloader_extcfg_semihosting
SDMMC
The commands for creating the SDMMC binaries for
revc C board are listed below:
# Start an embedded command shell
~/intelFPGA/16.1/embedded/embedded_command_shell.sh
mkdir -p ~/flash_programmer
cd ~/flash_programmer
# Create SDMMC hardware design
mkdir a10_sdmmc_devkit_revc_design
cd a10_sdmmc_devkit_revc_design
tar xvzf ~/intelFPGA/16.1/embedded/examples/hardware/a10_soc_devkit_ghrd/tgz/*.tar.gz
make scrub_clean
make generate_from_tcl
# Compile SDMMC hardware design
make sof
# Generate and build bootloader
mkdir -p software/bootloader_extcfg_semihosting
bsp-create-settings --type uboot --bsp-dir software/bootloader_extcfg_semihosting --preloader-settings-dir "hps_isw_handoff" --settings software/bootloader_extcfg_semihosting/settings.bsp --set uboot.boot_device SDMMC --set uboot.external_fpga_config true
make -C software/bootloader_extcfg_semihosting
make -C software/bootloader_extcfg_semihosting clean
sed -i 's/#undef CONFIG_SEMIHOSTING/#define CONFIG_SEMIHOSTING/g' software/bootloader_extcfg_semihosting/uboot-socfpga/include/configs/socfpga_arria10.h
sed -i "s/putc('#');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
sed -i 's/puts("\\n\\t ');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
make -C software/bootloader_extcfg_semihosting
The commands for creating the SDMMC binaries for
revc B board are listed below:
# Start an embedded command shell
~/intelFPGA/16.1/embedded/embedded_command_shell.sh
mkdir -p ~/flash_programmer
cd ~/flash_programmer
# Create SDMMC hardware design
mkdir a10_qspi_devkit_revb_design
cd a10_sdmmc_devkit_revb_design
tar xvzf ~/intelFPGA/16.1/embedded/examples/hardware/a10_soc_devkit_ghrd/tgz/*.tar.gz
make scrub_clean
sed -i 's/QUARTUS_DEVICE := 10AS066N3F40E2SG/QUARTUS_DEVICE := 10AS066N3F40E2SGE2/g' Makefile
sed -i 's/set FPGA_DEVICE 10AS066N3F40E2SG/set FPGA_DEVICE 10AS066N3F40E2SGE2/g' design_config.tcl
sed -i 's/set FPGA_DEVICE 10AS066N3F40E2SG/set FPGA_DEVICE 10AS066N3F40E2SGE2/g' ip/diffin/construct_diffin.tcl
sed -i 's/set_global_assignment -name DEVICE 10AS066N3F40E2SG/set_global_assignment -name DEVICE 10AS066N3F40E2SGE2/g' synth_v2.qsf
make generate_from_tcl
# Compile SDMMC hardware design
make sof
# Generate and build bootloader
mkdir -p software/bootloader_extcfg_semihosting
bsp-create-settings --type uboot --bsp-dir software/bootloader_extcfg_semihosting --preloader-settings-dir "hps_isw_handoff" --settings software/bootloader_extcfg_semihosting/settings.bsp --set uboot.boot_device SDMMC --set uboot.external_fpga_config true
make -C software/bootloader_extcfg_semihosting
make -C software/bootloader_extcfg_semihosting clean
sed -i 's/#undef CONFIG_SEMIHOSTING/#define CONFIG_SEMIHOSTING/g' software/bootloader_extcfg_semihosting/uboot-socfpga/include/configs/socfpga_arria10.h
sed -i "s/putc('#');/{}/g" software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
sed -i 's/puts("\\n\\t ");/{}/g' software/bootloader_extcfg_semihosting/uboot-socfpga/net/tftp.c
make -C software/bootloader_extcfg_semihosting
Adding Boards and/or SoCs
The script was designed to support additional Boards and SoCs (AV/CV/A10). The Python script should need no changes, but updated binaries must be provided.
Example 1: Add NAND write capabilities for A10 board named 'acme'. The following are needed:
Example 2: Add QSPI write capabilities for CV board named 'thunder'. The following are needed: