OSPI and SD Card Boot Flow - Detailed Reference#
Detailed procedures, advanced usage, options, error handling, and verification steps for the OSPI and SD card boot flow. For a quick reference, see OSPI and SD Card Boot Flow.
Section 1: OSPI Programming#
Purpose: Automated OSPI Flash Programming
Note
Vivado Lab Edition is a lite version of Vivado and is sufficient to support hardware download operations.
Step 1: Validate Configuration (Dry Run)#
Before flashing the hardware, validate the configuration:
cd <path to versal_2ve/tools/ospi_sd_flash/>
./vek385-flash-ospi.exp \
--vivado-dir <path to Vivado Lab 2025.2> \
--boot-images /path/to/boot_images \
--dry-run
The dry run validates:
Vivado Lab Edition installation path and
settings64.shavailabilityBoot images directory structure
OSPI image auto-detection
Serial port auto-detection (matches
ID_MODEL=VEK385)Serial port availability (not locked by minicom/screen)
Example output of the OSPI flash dry run:
[INFO] Auto-detected OSPI image: edf-ospi-versal2-vek385-sdt-full.bin
[INFO] OSPI image size: 0x4D0000 (4.8 MB)
[INFO] Auto-detected serial port: /dev/ttyUSB1
========================================================================
VEK385 OSPI Flash Tool
Automates UG1787 (Board Setup)
========================================================================
Vivado: <path to Vivado Lab 2025.2>
Boot images: <path to boot_images>
BOOT.bin: BOOT.bin
OSPI image: edf-ospi-versal2-vek385-sdt-full.bin
Image size: 0x4D0000 (4.8 MB)
Serial port: /dev/ttyUSB1
XSDB port: 3121
Log file: <path>/vek385-flash-ospi_<timestamp>.log
Mode: DRY RUN (no hardware operations)
========================================================================
Dry run complete -- all paths and settings validated
========================================================================
All prerequisites satisfied. Re-run without --dry-run to flash.
Note
The script automatically detects the serial port using udevadm by matching VEK385 USB interface 01. Override with --serial-port /dev/ttyUSBX if needed.
Step 2: Flash OSPI#
After validating the configuration, flash the OSPI:
./vek385-flash-ospi.exp \
--vivado-dir <path to Vivado Lab 2025.2> \
--boot-images /path/to/boot_images
Note
Alternatively, set the VIVADO_INSTALL_DIR environment variable:
export VIVADO_INSTALL_DIR=<path to Vivado Lab 2025.2>
./vek385-flash-ospi.exp --boot-images /path/to/boot_images
Example output after the OSPI flash completes successfully:
========================================================================
OSPI programming complete!
========================================================================
Log file: <path>/vek385-flash-ospi_<timestamp>.log
Next steps:
1. Prepare the SD card (Section 2) using vek385-flash-sdcard.sh
2. Power OFF the board
3. Set SW1 DIP switch to OSPI mode (0001 = ON, ON, ON, OFF)
4. Power ON the board
What the Script Does#
The script performs the following operations:
Opens serial port (auto-detected at 115200, 8N1)
Launches XSDB through Vivado Lab Edition
settings64.shConnects to board via JTAG (
connect,target -set)Resets device (
dev reset– ensures clean state)Downloads bootloader to DDR via JTAG (
dev p BOOT.bin)Waits for U-Boot prompt on serial console (
versal2>or=>)Downloads OSPI image to DDR at address 0x20000000 (
dow -data)Initializes SPI flash controller (
sf probe 0 0 0)Erases OSPI flash with progress indicator (
sf erase– displays ‘.’ every 5 seconds, ~2-5 minutes)Writes OSPI flash from DDR with size-aware operation (only writes actual file size, not full 256MB – significantly faster for smaller images)
Verifies completion (checks for “Erased: OK” and “Written: OK” in U-Boot output)
Cleans up XSDB and serial connections
Note
The script manages two independent communication channels:
XSDB (JTAG): Downloads files into board DDR memory
Serial console: Accesses U-Boot to execute flash commands
Both channels are orchestrated by the same expect process, eliminating the need for manually switching between terminal windows.
Error Handling#
The script includes comprehensive error detection:
A timestamped log file is created in the current directory: vek385-flash-ospi_<timestamp>.log
Step 3: Switch to OSPI Boot Mode#
After OSPI programming completes successfully:
Power OFF the board
Set SW1 DIP switch to OSPI boot mode (0001 = ON, ON, ON, OFF)
Power ON the board
The board now boots independently from OSPI flash – JTAG is no longer required.
Section 2: SD Card Setup#
Purpose: Automated SD Card Preparation
Prerequisites#
SD card (minimum 32GB) inserted into host machine card reader
SD card physically removed from the VEK385 board
Scripts directory with automation tools
Note
The SD card script must be run as root (sudo) because it writes directly to block devices.
Step 1: Validate Configuration (Dry Run)#
Before writing to the SD card, validate the configuration:
cd <path to versal_2ve/tools/ospi_sd_flash/>
sudo ./vek385-flash-sdcard.sh \
--boot-images /path/to/boot_images \
--dry-run
The dry run validates:
Running as root (
sudo)Boot images directory structure
Root filesystem image auto-detection (
*.wic.xz)Block map file auto-detection (
*.wic.bmap)bmaptoolinstallation
Example output of the SD card flash dry run:
========================================================================
VEK385 SD Card Flash Tool
Automates UG1787 (SD Card Setup)
========================================================================
Boot images: <path to boot_images>
Rootfs image: rootfs.wic.xz
Bmap file: rootfs.wic.bmap (found)
SD device: /dev/sdb
Device size: 59GB
Device model: Micro SD
Log file: <path>/vek385-flash-sdcard_<timestamp>.log
Mode: DRY RUN (no hardware operations)
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sdb 8:16 1 59.6G 0 disk
|-sdb1 8:17 1 1G 0 part
|-sdb2 8:18 1 1G 0 part
`-sdb3 8:19 1 57.4G 0 part
========================================================================
Dry run complete -- all paths and settings validated
========================================================================
All prerequisites satisfied. Re-run without --dry-run to flash.
Step 2: Flash SD Card#
Flash the root filesystem and copy all overlays:
sudo ./vek385-flash-sdcard.sh \
--boot-images /path/to/boot_images
The script will:
Auto-detect SD card (USB readers, built-in slots, mmcblk devices)
Display device information (size, model, partitions)
Request user confirmation before destructive operation
Perform safety checks (size < 128GB, not mounted as
/)Unmount existing partitions and kill holding processes
Flash root filesystem using
bmaptool(sparse write, ~2-3 minutes)Mount rootfs partition
Copy overlay files from boot_images (PL/AIE configuration)
Install setup scripts (
setup_overlay.sh,runtime_env.sh)Install systemd service and create enable symlink
Extract environment variables to
/etc/profile.d/vek385-runtime.shSync, unmount, eject
Note
Override auto-detection with --sd-device /dev/sdX if multiple candidates are found.
Example output after the SD card flash completes successfully:
========================================================================
Finalizing SD card
========================================================================
[INFO] Syncing...
[INFO] Unmounting /mnt/vek385-sd...
[INFO] Ejecting /dev/sdb...
[INFO] SD card ejected.
========================================================================
SD card is ready!
========================================================================
Log file: <path>/vek385-flash-sdcard_<timestamp>.log
Next steps:
1. Insert the SD card into the VEK385 board
2. Ensure SW1 DIP is set to OSPI mode (0001 = ON, ON, ON, OFF)
3. Power on the board
Optional: Copy Compiled Models#
To copy pre-compiled AI/ML models to the SD card:
sudo ./vek385-flash-sdcard.sh \
--boot-images /path/to/boot_images \
--models-dir /path/to/compiled_models
Models are copied to /home/models/ on the rootfs partition.
Note
Before the first boot, the rootfs partition on the SD card has only about 3.1 GB of free space available. Attempting to copy models larger than 3.1 GB at this stage fails with a “no space left on device” error.
On the first boot, the rootfs auto-resize service expands the partition to consume the full SD card capacity. It is therefore recommended to copy compiled models to the SD card after the first boot, once the rootfs has been expanded.
What the Script Does#
The script performs the following operations:
Resulting SD Card Partition Layout#
After flashing, the SD card contains:
/dev/sdc1 1 GB FAT32 /efi # EFI boot partition (kernel, bootloader)
/dev/sdc2 1 GB ext4 /root/storage # Storage partition
/dev/sdc3 6 GB ext4 / # Root filesystem (expands on first boot)
Note
The actual partition device names (for example, /dev/sdc1, /dev/sdb1, /dev/mmcblk0p1)
and partition sizes you see might differ depending on your host system, the SD card device
assignment, and the SD card capacity. The layout shown above is representative; verify
the device name on your system before performing any operations on the SD card.
Rootfs Contents:
/overlay/
setup_overlay.sh # Installed by SD flash script
runtime_env.sh # Installed by SD flash script
x_plus_ml.pdi # Copied from boot_images/overlay/
x_plus_ml.dtbo # Copied from boot_images/overlay/
image_processing.cfg # Copied from boot_images/overlay/
x_plus_ml.xclbin # Copied from boot_images/overlay/
/etc/ufs_config/
configure_ufs.sh # UFS configuration script (optional)
ufsconfig_64gb # UFS 64GB configuration descriptor
/etc/systemd/system/
vek385-setup.service # Installed by SD flash script
/etc/systemd/system/multi-user.target.wants/
vek385-setup.service -> ... # Enable symlink (auto-runs on boot)
/etc/profile.d/
vek385-runtime.sh # Environment variables (auto-sourced on login)
/home/models/ # Optional: compiled AI models
<model_cache_directories>
Special Options#
Skip Re-Flash (Update Only)
If the SD card is already flashed and you only need to update overlays or models:
sudo ./vek385-flash-sdcard.sh \
--boot-images /path/to/boot_images \
--skip-flash
This skips the bmaptool operation and jumps directly to mounting and copying files (much faster).
Non-Interactive Mode
For automated/scripted workflows, skip all confirmation prompts:
sudo ./vek385-flash-sdcard.sh \
--boot-images /path/to/boot_images \
--yes
Error Handling#
Scenario |
Behavior |
|---|---|
Not running as root |
Exits immediately with sudo hint |
|
Exits with |
Device > 128GB |
Refuses to flash (safety check) |
Device mounted as |
Refuses to flash (system disk protection) |
User declines confirmation |
Exits gracefully |
|
Exits with error code and log reference |
No ext4 partition found |
Warning, falls back to last partition |
Mount fails |
Exits with error message |
Device busy during eject |
Warning with manual removal instructions |
Ctrl-C during execution |
Cleanup trap unmounts and removes mount point |
A timestamped log file is created in the current directory: vek385-flash-sdcard_<timestamp>.log
Section 3: Board Boot#
Purpose: Automatic System Configuration
Step 1: Boot the Board#
Insert the prepared SD card into the VEK385 board
Verify SW1 DIP switch is set to OSPI mode (0001 = ON, ON, ON, OFF)
Power ON the board
The board boots from OSPI (bootloader) and SD card (root filesystem).
Note
The automated setup requires no manual intervention after boot. The systemd service vek385-setup.service runs automatically during boot sequence and consolidates overlay programming, runtime environment setup, and optional UFS flash enablement.
Important
Optional UFS Flash Support: VEK385 boards include UFS (Universal Flash Storage) that ships in a disabled state. The vek385-setup.service includes an optional UFS enablement step that, on first boot, configures the UFS device with 64GB capacity and requires a reboot to activate. On subsequent boots, the service detects that UFS is already enabled and skips reconfiguration. If you do not need UFS, ignore the reboot notice and continue using the SD Card boot flow.
For background on UFS and the workflows it enables (booting from UFS, programming UFS via the System Boot Image Recovery Tool), see OSPI + UFS Boot Flow.
Step 2: Verify Configuration#
After logging in, verify the automatic configuration succeeded:
Check Service Status#
systemctl status vek385-setup.service
Expected output:
● vek385-setup.service - VEK385 board setup (overlay, runtime, UFS)
Loaded: loaded (/etc/systemd/system/vek385-setup.service; enabled; preset: enabled)
Active: active (exited) since Fri 2026-05-01 00:03:45 UTC; 1min ago
Process: 683 ExecStart=/overlay/setup_overlay.sh (code=exited, status=0/SUCCESS)
Process: 749 ExecStart=/overlay/runtime_env.sh (code=exited, status=0/SUCCESS)
Process: 759 ExecStart=/etc/ufs_config/configure_ufs.sh (code=exited, status=0/SUCCESS)
Main PID: 759 (code=exited, status=0/SUCCESS)
Verify Kernel Module#
The amdxdna kernel module is loaded automatically by the system. Verify it is loaded:
lsmod | grep amdxdna
Expected output:
amdxdna 123456 0
Note
The module loading is handled automatically by the Linux system (via udev rules or kernel auto-loading), not by the runtime_env.sh script.
Verify Environment Variables#
echo $LD_LIBRARY_PATH
Expected output:
/usr/lib/python3.12/site-packages/onnxruntime/capi/:/usr/lib/python3.12/site-packages/flexmlrt/lib/:/usr/lib/python3.12/site-packages/voe/lib/
true
1
Manual Re-run (If Needed)#
If the service fails or the overlay needs re-programming:
# Re-run via systemd
sudo systemctl restart vek385-setup.service
# Or run scripts directly
cd /overlay
sudo ./setup_overlay.sh
source ./runtime_env.sh
# Re-run UFS configuration (if needed)
sudo /etc/ufs_config/configure_ufs.sh
Note
When running runtime_env.sh manually, source is required to set environment variables in your current shell. When systemd runs it on boot, environment variables are installed to /etc/profile.d/vek385-runtime.sh and apply to all user login shells automatically.
Troubleshooting#
OSPI Flash Issues#
Symptom |
Resolution |
|---|---|
“Serial port locked” error |
Kill minicom/screen: |
“No targets found” (XSDB) |
Check USB cable, verify SW1=JTAG (0000) |
U-Boot prompt timeout |
Check DIP switch, verify board powered on |
“sf probe” fails |
Hardware issue – flash not detected by U-Boot |
“sf erase” timeout |
256MB erase takes 2-5 minutes – wait longer |
OSPI flash script hangs |
Press Ctrl-C, check log file for details |
SD Card Flash Issues#
Symptom |
Resolution |
|---|---|
“Not running as root” error |
Prefix command with |
Multiple SD cards detected |
Script shows numbered list – choose correct one |
“Device is too large” (>128GB) |
Verify correct device – SD cards are <128GB |
“Device busy” during flash |
Script runs |
bmaptool fails |
Check log file, verify |
SD card won’t eject |
Manual removal safe after |
Boot Configuration Issues#
Additional Options#
Logging#
Both scripts create timestamped log files in the current directory:
vek385-flash-ospi_20260418_143022.log
vek385-flash-sdcard_20260418_144530.log
Override log file path:
./vek385-flash-ospi.exp --boot-images /path --log-file /tmp/ospi.log
sudo ./vek385-flash-sdcard.sh --boot-images /path --log-file /tmp/sd.log
Advanced OSPI Options#
# Override auto-detected serial port
./vek385-flash-ospi.exp \
--vivado-dir <path to Vivado Lab 2025.2> \
--boot-images /path/to/boot_images \
--serial-port /dev/ttyUSB3
# Use custom OSPI image filename
./vek385-flash-ospi.exp \
--vivado-dir <path to Vivado Lab 2025.2> \
--boot-images /path/to/boot_images \
--ospi-image custom-ospi-image.bin
Advanced SD Card Options#
# Explicit device selection
sudo ./vek385-flash-sdcard.sh \
--boot-images /path/to/boot_images \
--sd-device /dev/sdc
# Custom rootfs image
sudo ./vek385-flash-sdcard.sh \
--boot-images /path/to/boot_images \
--rootfs-image custom-rootfs.wic.xz
Summary#
The scripts cover the complete board bring-up flow. For users who need to troubleshoot or understand the underlying process, the equivalent step-by-step manual procedure is documented in the appendix: OSPI and SD Card Boot Flow - Manual Steps Reference.
UFS flash activation is optional and not needed for standard AI/ML inference workflows. It is only required if you plan to use the Image Recovery Tool or need additional persistent storage. For details, see OSPI + UFS Boot Flow.