Program NAND Flash Memory
Use Xilinx program_flash (part of Vivado / Vitis) to write the Yocto
boot images directly to on-board NAND flash. The workflow is identical to
Program QSPI Flash Memory; only the -flash_type argument and the image.ub
offset differ.
Prerequisites
Vivado / Vitis installed with
program_flashonPATH.JTAG cable connected and board powered on.
A board that actually has NAND flash. Check for a NAND controller node in the design’s device tree before flashing; the SLAC RFMC carrier, for example, exposes only QSPI and SD.
A completed Yocto build. Boot images are located at:
firmware/build/YoctoProjects/<your-target-dir>/linux/For the scripted recipe: the packaged Yocto tarball at
firmware/targets/<your-target-dir>/images/<full-name>.linux.tar.gz
Note
Set the correct boot mode before or after flashing using XSCT (see Change Boot Mode via XSCT in this how-to section).
Note
BuildYoctoProject.sh packages the FSBL built from the design’s own
.xsa as linux/zynqmp_fsbl.elf, so both the linux/ build output
and the tarball carry one, and the scripted recipe picks it up with no
-e. Pass it to the manual recipe as -fsbl linux/zynqmp_fsbl.elf.
Warning
NAND has no fallback when that FSBL is absent. Unlike QSPI, Vitis bundles
no NAND FSBL at all: its
data/xicom/cfgmem/cfgmem_util/cfgmem_fsbl.zip ships only
zynqmp_qspi_*_fsbl.elf variants, and those are unusable here both for
the wrong flash type and because they carry a reference PS/DDR
configuration that hangs on a custom carrier. On a tarball produced before
the FSBL was packaged, program_flash therefore refuses outright, and you
must pass -e pointing at
<YoctoProject>/build/tmp/deploy/images/zynqmp-user/fsbl-zynqmp-user.elf.
Note
-flash_density is not needed here. program_flash lists it as
required only for the QSPI / OSPI dual configurations, not for NAND, so
the recipes below omit it and program_nand_flash.sh has no -d
option.
Manual recipe
# Go to the Yocto project output directory
cd firmware/build/YoctoProjects/<your-target-dir>
# Define default parameters for NAND
default_parameter="\
-flash_type nand-x8-single \
-blank_check -verify"
# Program each boot image at its partition offset
program_flash -f linux/BOOT.BIN -offset 0x0000000 $default_parameter
program_flash -f linux/boot.scr -offset 0x3E80000 $default_parameter
program_flash -f linux/image.ub -offset 0x4180000 $default_parameter
Note
The image.ub offset differs between NAND (0x4180000, from
NAND_FIT_IMAGE_OFFSET) and QSPI (0x4000000). BOOT.BIN and
boot.scr sit at the same offsets on both; U-Boot reads boot.scr
from CONFIG_BOOT_SCRIPT_OFFSET regardless of flash type.
Warning
shared/Yocto/zynqmp-user.conf overrides only the QSPI_* FIT image
variables, so NAND inherits the meta-xilinx default
NAND_FIT_IMAGE_SIZE = 0x6400000 (100 MiB) while QSPI_FIT_IMAGE_SIZE
is raised to 192 MiB. An image.ub larger than 100 MiB is written to
flash correctly but truncated by the nand read that the generated
boot.scr issues, and bootm then fails on the incomplete FIT.
Before relying on NAND boot, check the offsets and sizes in the generated
boot.scr against your image.ub size and add NAND_FIT_IMAGE_SIZE
/ NAND_FIT_IMAGE_OFFSET overrides for the machine if needed.
Scripted recipe (program_nand_flash.sh)
The program_nand_flash.sh script, provided in the
scripts/program_nand_flash.sh of the platform repository, automates
the recipe above. Instead of a Yocto build directory it takes the packaged
.linux.tar.gz, extracts it to a scratch directory, and programs each
image at its partition offset.
firmware/submodules/axi-soc-ultra-plus-core/scripts/program_nand_flash.sh \
-f firmware/targets/<your-target-dir>/images/<full-name>.linux.tar.gz
Replace <full-name> with the timestamped artifact name produced by
the Yocto build (schema:
<TargetName>-<PRJ_VERSION>-<YYYYMMDDHHMMSS>-<user>-<git-short-SHA>).
Options:
-f PATH– path to the.linux.tar.gz(required).-t FLASH_TYPE– value passed to-flash_type(defaultnand-x8-single). Must be anand-*type; the script rejectsqspi-*types and points atprogram_qspi_flash.sh, since theimage.uboffset it programs is fixed at the NAND one.-e PATH– FSBL.elfpassed to-fsbl. Defaults tolinux/zynqmp_fsbl.elffrom the tarball, whichBuildYoctoProject.shpackages, so this is normally not needed. Required only for tarballs that predate that packaging, because NAND has no bundled fallback (see the FSBL warning under Prerequisites).-n– skip the-blank_check -verifyQA/QC pass, which is on by default.-verifyreads the payload back and compares it against the image, the only positive proof the data landed where it belongs. The cost has not been measured on NAND, and on QSPI it varied by roughly two orders of magnitude between Vitis releases (see the throughput warning in Program QSPI Flash Memory), so measure before planning around it. Whatever the NAND rates turn out to be,-acosts far more than the default image set either way, sinceimage.ubis roughly 60x larger thanBOOT.BIN.-c– accepted for compatibility and now redundant, since the checks it used to enable are the default. Use-nto turn them off.-F– program even if anhw_serveris already running. By default the script stops, becauseprogram_flashwould attach to that session and share its JTAG cable. Note thatkillVivadodoes not reaphw_server.-J– skip the JTAG boot mode step and flash the board as-is.-H– show the help text.
Boot mode handling
Identical to Program QSPI Flash Memory, except for the value you write afterwards.
The script puts the device into JTAG boot mode first (0x0100 to
0xff5e0200, then rst -system), using xsdb rather than the disabled
xsct, and leaves the board in JTAG boot mode. Afterwards, either
power-cycle to fall back to the M[3:0] straps (0b0100 = NAND), or
write 0x4100 to 0xff5e0200 and rst -system to switch without a
power-cycle. Do not do both: a POR clears the override you just wrote. The
script prints this reminder when it finishes. Pass -J to skip the step.
The two cosmetic program_flash warnings documented in Program QSPI Flash Memory
apply here as well: [Xicom 50-100] The current boot mode is ... reports the
M[3:0] straps rather than the 0xff5e0200 override and does not mean the
override failed, and it must not be read as the cause of a later
[Xicom 50-331] Timed out while waiting for FSBL to complete, which is
almost always the wrong FSBL.
After flashing
Switch the board to boot from the newly programmed flash using XSCT (Change Boot Mode via XSCT in this how-to section), then power-cycle the board.