Skip to content

HPS Fabric Configuration from Linux

Introduction

The HPS Baseline System Example Design (formerly known as "GSRD" or "Golden System Reference Design") configures the FPGA fabric from U-Boot. This Tutorial example design shows how to customize the Yocto recipes for the HPS Baseline System Example Design to configure the fabric from Linux, instead of U-Boot.

The following modifications are done:

  • Use 0 as board_id in the boot script, so that the vanilla Linux device tree is used at boot time, which does not need the fabric to be configured.
  • Copy the core.rbf file in /lib/firmware on the target rootfs
  • Create a device tree overlay fabric_overlay.dtb and also copy it in /lib/firmware on the target rootfs
  • Update the kernel configuration to include the required additional drivers and settings.

Prerequisites

The following are needed:

  • Agilex 3 FPGA and SoC C-Series Development Kit, ordering code DK-A3W135BM16AEA. Other Agilex 3 development boards will also work in the same manner, just that other set HPS Baseline System Example Design binaries will be used.
  • Host PC with Linux (Ubuntu 22.04 was used, but others should work too)
  • Quartus Pro 26.1.1 (or just Quartus Pro standalone Programmer 26.1.1).
  • Ashling RiscFree bundled with Quartus Pro 26.1.1 (can be installed and use with just the standalone Programmer)
  • Network access, for downloading the sources while building the binaries

Build Example Design

Setup Environment

Create a folder to contain all the example files:

sudo rm -rf agilex3.fabric-config-linux
mkdir agilex3.fabric-config-linux
cd agilex3.fabric-config-linux
export TOP_FOLDER=`pwd`

Enable Quartus tools to be called from command line:

source ~/altera_pro/26.1.1/qinit.sh

Build Quartus Design

The Quartus design is derived from the HPS Baseline System Example Design (formerly known as "GSRD" or "Golden System Reference Design"), with the JOP component added and connected to clock, reset and the LWH2F bridge

The following instructions are used:

cd $TOP_FOLDER
rm -rf agilex3_soc_devkit_ghrd && mkdir agilex3_soc_devkit_ghrd && cd agilex3_soc_devkit_ghrd
wget https://github.com/altera-fpga/agilex3c-ed-gsrd/releases/download/QPDS26.1.1_REL_GSRD_PR/dk-a3w135bm16aea-baseline.zip
unzip dk-a3w135bm16aea-baseline.zip
rm -f dk-a3w135bm16aea-baseline.zip
make baseline-install
cd ..

The following files are created:

  • $TOP_FOLDER/agilex3_soc_devkit_ghrd/install/binaries/baseline.sof
  • $TOP_FOLDER/agilex3_soc_devkit_ghrd/install/binaries/ghrd.core.rbf

Build Rootfs Using Kas

1. Copy the core.rbf file to where the recipes needs it

cd $TOP_FOLDER/agilex3_soc_devkit_ghrd/software/yocto_linux
cp $TOP_FOLDER/agilex3_soc_devkit_ghrd/install/binaries/ghrd.core.rbf \
   $TOP_FOLDER/agilex3_soc_devkit_ghrd/software/yocto_linux/meta-custom/recipes-fpga/fpga-bitstream/files/

2. Create the patch file for customizing Yocto to configure fabric from Linux:

base64 -d <<'EOF' | gunzip > fabric-config-linux.patch
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
EOF

For reference, the fabric-config-linux.patch looks like this:

diff --git a/kas.yml b/kas.yml
index f3409fa..0ad3121 100644
--- a/kas.yml
+++ b/kas.yml
@@ -41,9 +41,11 @@ local_conf_header:
     CUSTOM_LINUX_DEVICE_TREE = "0"

   # RBF file should be placed in meta-custom/recipes-fpga/fpga-bitstream/files/
+  # FPGA_ENABLE_CORE_PGM=0: RBF is NOT embedded in kernel.itb; instead it is
+  # installed to /lib/firmware in the rootfs for Linux-side fabric configuration.
   fpga-bitstream: |
-    FPGA_ENABLE_CORE_PGM ?= "1"
-    FPGA_RBF_FILE ?= "baseline_hps_debug.core.rbf"
+    FPGA_ENABLE_CORE_PGM ?= "0"
+    FPGA_RBF_FILE ?= "ghrd.core.rbf"

   kernel-modules: |
     KERNEL_MODULE_PROBECONF = "cfg80211"
diff --git a/meta-custom/conf/layer.conf b/meta-custom/conf/layer.conf
index 8971475..00139c8 100644
--- a/meta-custom/conf/layer.conf
+++ b/meta-custom/conf/layer.conf
@@ -46,6 +46,9 @@ IMAGE_INSTALL:append = "${@bb.utils.contains('GPIO_INT_TEST', 'true', ' pio-inte
 IMAGE_INSTALL:append = "${@bb.utils.contains('HELLO_WORLD_APP', 'true', ' hello', '', d) if d.getVar('SSBL_BOOT_SOURCE') != 'qspi' else ''}"
 IMAGE_INSTALL:append = "${@'' if d.getVar('SSBL_BOOT_SOURCE') == 'qspi' else ' rootfs-files'}"

+# Install ghrd.core.rbf and fabric_overlay.dtb to /lib/firmware in the rootfs.
+IMAGE_INSTALL:append = " fpga-bitstream fpga-linux-overlay"
+
 # Add variables for wic creation of sdcard image
 IMAGE_BOOT_FILES = " \
        uboot.env \
diff --git a/meta-custom/recipes-bsp/u-boot/bootscr/uboot.txt b/meta-custom/recipes-bsp/u-boot/bootscr/uboot.txt
new file mode 100644
index 0000000..9c268c5
--- /dev/null
+++ b/meta-custom/recipes-bsp/u-boot/bootscr/uboot.txt
@@ -0,0 +1,45 @@
+echo "Trying to boot Linux from device ${target}";
+
+if test ${target} = "mmc0"; then
+   if test -e ${devtype} ${devnum}:${distro_bootpart} /${bootfile}; then
+       echo "Found kernel in mmc0";
+       mmc rescan;
+       fatload ${devtype} ${devnum}:${distro_bootpart} ${loadaddr} ${bootfile};
+        if test -n "${custom_bootargs}"; then
+            setenv bootargs ${custom_bootargs}
+        else
+            setenv bootargs "earlycon panic=-1 root=${mmcroot} rw rootwait";
+        fi
+       bootm ${loadaddr}#board-0;
+       exit;
+   fi
+fi
+
+if test ${target} = "qspi"; then
+   mtdparts;
+   ubi part root;
+   ubi readvol ${loadaddr} kernel;
+   ubi detach;
+    if test -n "${custom_bootargs}"; then
+        setenv bootargs ${custom_bootargs}
+    else
+        setenv bootargs "earlycon panic=-1 ubi.mtd=1 root=ubi0:rootfs rootfstype=ubifs rw rootwait";
+    fi
+   bootm ${loadaddr}#board-0;
+fi
+
+if test ${target} = "nand"; then
+   setenv mtdids "nor0=nor0,nand0=ffb90000.nand.0";
+   setenv mtdparts "mtdparts=nor0:66m(u-boot),190m(qspi_root);ffb90000.nand.0:2m(u-boot),-(root)";
+   env select UBI;
+   saveenv;
+   mtdparts;
+   ubi part root;
+   ubi readvol ${loadaddr} kernel;
+    if test -n "${custom_bootargs}"; then
+        setenv bootargs ${custom_bootargs}
+    else
+        setenv bootargs "earlycon panic=-1 root=${nandroot} rw rootwait rootfstype=ubifs ubi.mtd=1";
+    fi
+   bootm ${loadaddr}#board-0;
+fi
diff --git a/meta-custom/recipes-bsp/u-boot/u-boot-socfpga-scr.bbappend b/meta-custom/recipes-bsp/u-boot/u-boot-socfpga-scr.bbappend
new file mode 100644
index 0000000..299fc18
--- /dev/null
+++ b/meta-custom/recipes-bsp/u-boot/u-boot-socfpga-scr.bbappend
@@ -0,0 +1,6 @@
+# Override the upstream boot script to use a fixed board-0 FIT config,
+# bypassing board_id detection.  FPGA fabric is configured from Linux,
+# not from U-Boot, so board-0 (vanilla DTB, no FPGA section in ITB) is
+# always the correct choice.
+
+FILESEXTRAPATHS:prepend := "${THISDIR}/bootscr:"
diff --git a/meta-custom/recipes-fpga/fpga-bitstream/fpga-bitstream.bbappend b/meta-custom/recipes-fpga/fpga-bitstream/fpga-bitstream.bbappend
index 9da6b0a..9dabc77 100644
--- a/meta-custom/recipes-fpga/fpga-bitstream/fpga-bitstream.bbappend
+++ b/meta-custom/recipes-fpga/fpga-bitstream/fpga-bitstream.bbappend
@@ -7,4 +7,18 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
 python () {
     if not d.getVar('FPGA_ENABLE_CORE_PGM'):
         raise bb.parse.SkipRecipe("FPGA Enable Core Programming option is not set!")
+
+    # We always want the RBF in /lib/firmware
+    d.delVarFlag('do_install', 'noexec')
 }
+
+# Always include the RBF in SRC_URI regardless of FPGA_CORE_PGM_ENABLE.
+SRC_URI:append = " file://${FPGA_RBF_FILE}"
+
+# Install core.rbf to /lib/firmware
+do_install () {
+    install -D -m 0644 ${S}/${FPGA_RBF_FILE} \
+        ${D}${nonarch_base_libdir}/firmware/${FPGA_RBF_FILE}
+}
+
+FILES:${PN} = "${nonarch_base_libdir}/firmware/*"
diff --git a/meta-custom/recipes-fpga/fpga-linux-overlay/files/fabric_overlay.dts b/meta-custom/recipes-fpga/fpga-linux-overlay/files/fabric_overlay.dts
new file mode 100644
index 0000000..9d5b461
--- /dev/null
+++ b/meta-custom/recipes-fpga/fpga-linux-overlay/files/fabric_overlay.dts
@@ -0,0 +1,76 @@
+/dts-v1/;
+/plugin/;
+
+/ {
+   /*
+    * Fragment 0 – target the FPGA region at root level.
+    * Triggers FPGA Manager to load the bitstream and registers the
+    * PIO controllers as children of the programmed fabric region.
+    */
+   fragment@0 {
+       target-path = "/fpga-region";
+       #address-cells = <0x2>;
+       #size-cells = <0x2>;
+       __overlay__ {
+           #address-cells = <0x2>;
+           #size-cells = <0x2>;
+           /*
+            * Map local fabric address space to the LWH2F bridge.
+            * child-hi  child-lo  parent-hi  parent-lo  size-hi  size-lo
+            */
+           ranges = <0x0 0x0 0x0 0x20000000 0x0 0x200000>;
+
+           firmware-name = "ghrd.core.rbf";
+           config-complete-timeout-us = <30000000>;
+
+           /* FPGA LED PIO – 3 output bits driving board LEDs */
+           led_pio: gpio@10080 {
+               compatible = "altr,pio-1.0";
+               reg = <0x0 0x10080 0x0 0x10>;
+               #gpio-cells = <2>;
+               gpio-controller;
+               resetvalue = <0>;
+           };
+
+           /* FPGA Button PIO – input with edge-triggered interrupt */
+           button_pio: gpio@10060 {
+               compatible = "altr,pio-1.0";
+               reg = <0x0 0x10060 0x0 0x10>;
+               interrupt-parent = <&intc>;
+               interrupts = <0 17 1>;
+               altr,interrupt-type = <2>;
+               #gpio-cells = <2>;
+               gpio-controller;
+           };
+       };
+   };
+
+   /*
+    * Fragment 1 – add gpio-leds at root level, referencing the
+    * led_pio controller defined in fragment@0.
+    * GPIO_ACTIVE_HIGH = 0 (numeric, no header dependency).
+    */
+   fragment@1 {
+       target-path = "/";
+       __overlay__ {
+           soc_leds: fpga-leds {
+               compatible = "gpio-leds";
+
+               led_fpga0: fpga0 {
+                   label = "fpga_led0";
+                   gpios = <&led_pio 0 0>;
+               };
+
+               led_fpga1: fpga1 {
+                   label = "fpga_led1";
+                   gpios = <&led_pio 1 0>;
+               };
+
+               led_fpga2: fpga2 {
+                   label = "fpga_led2";
+                   gpios = <&led_pio 2 0>;
+               };
+           };
+       };
+   };
+};
diff --git a/meta-custom/recipes-fpga/fpga-linux-overlay/fpga-linux-overlay.bb b/meta-custom/recipes-fpga/fpga-linux-overlay/fpga-linux-overlay.bb
new file mode 100644
index 0000000..7a79f66
--- /dev/null
+++ b/meta-custom/recipes-fpga/fpga-linux-overlay/fpga-linux-overlay.bb
@@ -0,0 +1,32 @@
+SUMMARY = "FPGA fabric configuration device tree overlay"
+DESCRIPTION = "Compiles fabric_overlay.dts to fabric_overlay.dtb and installs it to \
+/lib/firmware so that userspace or an early-boot service can apply it via \
+the kernel configfs overlay interface to trigger Linux-side FPGA programming."
+SECTION = "bsp"
+
+LICENSE = "GPL-2.0-only"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0-only;md5=801f80980d171dd6425610833a22dbe6"
+
+DEPENDS = "dtc-native"
+
+FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
+SRC_URI = "file://fabric_overlay.dts"
+
+S = "${UNPACKDIR}"
+
+PACKAGE_ARCH = "${MACHINE_ARCH}"
+
+do_configure[noexec] = "1"
+
+do_compile() {
+    # -@ generates __symbols__ and __fixups__ nodes so the kernel can resolve
+    # phandle references to the base DTB (e.g. &intc for button interrupts).
+    dtc -@ -I dts -O dtb -o ${B}/fabric_overlay.dtb ${UNPACKDIR}/fabric_overlay.dts
+}
+
+do_install() {
+    install -D -m 0644 ${B}/fabric_overlay.dtb \
+        ${D}${nonarch_base_libdir}/firmware/fabric_overlay.dtb
+}
+
+FILES:${PN} = "${nonarch_base_libdir}/firmware/fabric_overlay.dtb"
diff --git a/meta-custom/recipes-kernel/linux/linux-socfpga-lts/configs/config_agilex5.cfg b/meta-custom/recipes-kernel/linux/linux-socfpga-lts/configs/config_agilex5.cfg
index c5d0ec8..8a4764d 100644
--- a/meta-custom/recipes-kernel/linux/linux-socfpga-lts/configs/config_agilex5.cfg
+++ b/meta-custom/recipes-kernel/linux/linux-socfpga-lts/configs/config_agilex5.cfg
@@ -1,3 +1,12 @@
+CONFIG_OF_RESOLVE=y
+CONFIG_OF_OVERLAY=y
+CONFIG_OF_CONFIGFS=y
+CONFIG_FPGA_MGR_STRATIX10_SOC=y
+CONFIG_FPGA_BRIDGE=y
+CONFIG_FPGA_REGION=y
+CONFIG_OF_FPGA_REGION=y
+CONFIG_OVERLAY_FS=y
+CONFIG_ALTERA_SYSID=y
 CONFIG_MARVELL_PHY=y
 CONFIG_OF_MDIO=y
 CONFIG_VLAN_8021Q=y
@@ -14,3 +23,4 @@ CONFIG_DMATEST=y
 CONFIG_MTD_NAND_CADENCE=y
 CONFIG_I3C=m
 CONFIG_DW_I3C_MASTER=m
+CONFIG_GPIO_ALTERA=y
diff --git a/meta-custom/recipes-kernel/linux/linux-socfpga-lts_%.bbappend b/meta-custom/recipes-kernel/linux/linux-socfpga-lts_%.bbappend
index 5571dec..ec29f17 100644
--- a/meta-custom/recipes-kernel/linux/linux-socfpga-lts_%.bbappend
+++ b/meta-custom/recipes-kernel/linux/linux-socfpga-lts_%.bbappend
@@ -104,4 +104,9 @@ do_patch:append() {
 }


+# Compile all DTBs with -@ so they include a __symbols__ node.
+# This is required for the configfs device tree overlay mechanism to resolve
+# phandle references (e.g. &intc) from the FPGA fabric overlay at runtime.
+KERNEL_DTC_FLAGS:append = " -@"
+
 addtask do_patch after do_unpack before do_configure
 ```

3\. Apply the patch file:


```bash
patch -p1 < fabric-config-linux.patch

4. Build Yocto

python3 -m venv venv --system-site-packages
source venv/bin/activate
pip install --upgrade pip
pip install kas
pip install --upgrade kas
pip install kconfiglib
kas build kas.yml gsrd-console-image

The following relevant files are created in $TOP_FOLDER/agilex3_soc_devkit_ghrd/software/yocto_linux/build/tmp/deploy/images/agilex3/:

  • gsrd-console-image-agilex5e.rootfs.wic
  • u-boot-spl-dtb.hex

Build QSPI Image

cd $TOP_FOLDER
rm -f baseline.hps.jic baseline.core.rbf
quartus_pfg \
-c agilex3_soc_devkit_ghrd/install/binaries/baseline.sof baseline.jic \
-o device=MT25QU128  \
-o flash_loader=A3CW135BM16AE6S \
-o hps_path=agilex3_soc_devkit_ghrd/software/yocto_linux/build/tmp/deploy/images/agilex3/u-boot-spl-dtb.hex \
-o mode=ASX4 \
-o hps=1

Run Example

The instructions from this section present how to run the remote debug example. Refer to the HPS Baseline System Example Design for more detailed instructions on how to set up the board, serial port, and write the binaries.

1. Write the SD card image: $TOP_FOLDER/agilex3_soc_devkit_ghrd/software/yocto_linux/build/tmp/deploy/images/agilex3/gsrd-console-image-agilex3.rootfs.wic

2. Write the QSPI image: $TOP_FOLDER/baseline.hps.jic.

3. Power up board

4. On the serial console, enter 'root' as username to log into Linux. No password will be requested.

5. List the LEDs registered with Linux:

root@agilex3:~# ls /sys/class/leds/
hps_led0  hps_led1  mmc0::

6. Configure the FGPA fabric by using the device tree overlay:

root@agilex3:~# mkdir /sys/kernel/config/device-tree/overlays/fpgas/fpga/path
root@agilex3:~# echo fabric_overlay.dtb > /sys/kernel/config/device-tree/overlay 
[ 3202.413832] fpga_manager fpga0: writing ghrd.core.rbf to Stratix10 SOC FPGA Manager
[ 3204.553879] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /fpga-region/ranges
[ 3204.563681] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /fpga-region/firmware-name
[ 3204.573962] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /fpga-region/config-complete-timeout-us
[ 3204.585534] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/led_pio
[ 3204.595322] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/button_pio
[ 3204.605346] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/soc_leds
[ 3204.615186] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/led_fpga0
[ 3204.625116] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/led_fpga1
[ 3204.635043] OF: overlay: WARNING: memory leak will occur if overlay removed, property: /__symbols__/led_fpga2

7. List again the LEDs registered with Linux:

root@agilex3:~# ls /sys/class/leds/
fpga_led0  fpga_led1  fpga_led2  hps_led0   hps_led1   mmc0::

8. Stop the background application which scrolls the FPGA LEDs:

root@agilex3:~# ./alteraFPGA/scroll_client -1

9. Display the status of FPGA LED0:

root@agilex3:~# cat /sys/class/leds/fpga_led0/brightness
0

10. Change the value of FPGA LED0:

root@agilex3:~# echo 1 > /sys/class/leds/fpga_led0/brightness

11. Read back the value to confirm it changed:

root@agilex3:~# cat /sys/class/leds/fpga_led0/brightness
1

Note: You can also see the LEDs being turned on and off, in addition to looking at the sysfs entries above.

Notices & Disclaimers

Altera® Corporation technologies may require enabled hardware, software or service activation. No product or component can be absolutely secure. Performance varies by use, configuration and other factors. Your costs and results may vary. You may not use or facilitate the use of this document in connection with any infringement or other legal analysis concerning Altera or Intel products described herein. You agree to grant Altera Corporation a non-exclusive, royalty-free license to any patent claim thereafter drafted which includes subject matter disclosed herein. No license (express or implied, by estoppel or otherwise) to any intellectual property rights is granted by this document, with the sole exception that you may publish an unmodified copy. You may create software implementations based on this document and in compliance with the foregoing that are intended to execute on the Altera or Intel product(s) referenced in this document. No rights are granted to create modifications or derivatives of this document. The products described may contain design defects or errors known as errata which may cause the product to deviate from published specifications. Current characterized errata are available on request. Altera disclaims all express and implied warranties, including without limitation, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement, as well as any warranty arising from course of performance, course of dealing, or usage in trade. You are responsible for safety of the overall system, including compliance with applicable safety-related requirements or standards. © Altera Corporation. Altera, the Altera logo, and other Altera marks are trademarks of Altera Corporation. Other names and brands may be claimed as the property of others.

OpenCL* and the OpenCL* logo are trademarks of Apple Inc. used by permission of the Khronos Group™.


Last update: September 11, 2026
Created: May 14, 2026
Ask in the Forum