1. はじめに
Agilex™ FPGA には複数の CPU コアが搭載されており、用途に応じて一部のコアを Linux 以外の OS、あるいは OS を使用しない Bare-metal 環境で運用したいケースもあります。
この記事では、Agilex™ 5 FPGA E-Series Premium Development Kit を使用し、Linux と Bare-metal アプリケーションが並行して動作する SD カードイメージの作成方法をご紹介します。
【図 1】 Linux + Bare-metal 搭載イメージ
なお、この記事では以下の HPS GHRD Linux Boot Examples の手順をベースに、一部カスタマイズした内容で記載しておりますので併せてご参照ください。
参考: HPS GHRD Linux Boot Examples - Altera FPGA Developer Site
ポイント:
この記事では Agilex™ 5 FPGA を中心に記載しておりますが、Agilex™ 7 FPGA においても基本的には同様の手順で構築可能です。Agilex™ 7 FPGA 特有の設定についても併せて記載していますので、該当デバイスをご利用の方もご参考にしていただければと思います。
2. 事前準備
この記事の内容を実行するにあたり、以下のホスト PC 環境をご準備ください。
- Linux OS ※ この記事では Ubuntu 22.04 LTS を使用した説明となっています。
- 64 GB 以上の RAM
- Quartus® Prime Pro Edition Version 25.1
2-1. Quartus® 環境変数の設定
この記事の手順では Quartus® Prime のツールを使用しますので、以下のコマンドを実行し Quartus のパスを環境変数に設定してください。
注記: Quartus® Prime のインストール・ディレクトリーに合わせて以下のコマンドを変更する必要があります。
export QUARTUS_ROOTDIR=~/altera_pro/25.1/quartus/
export PATH=$QUARTUS_ROOTDIR/bin:$QUARTUS_ROOTDIR/linux64:$QUARTUS_ROOTDIR/../qsys/bin:$PATH
2-2. Bare-metal アプリケーションの作成
以下のサイトを参考に、Bare-metal アプリケーションの "hello_world.bin" を事前に作成してください。
参考: E-Series Premium Development Kit GHRD - Baremetal Hello World Example -
※ "hello_world.bin" のみを作成する場合は、参考サイトの手順 4(Build ATF)、および、手順 10(Build FIP file, containing ATF bl31 and the hello application)以降は不要となります。 注記:
この記事での動作環境では Bare-metal アプリケーションのエントリーポイントを 0x90200000 番地としています。
そのため baremetal-drivers/build/aarch64/core0.ld ファイルを以下のように変更する必要があります。
【図 2】 core0.ld ファイルの変更
2-3. ハードウェア・デザインファイルの準備
以下のサイトを参考に、ハードウェア・デザインの "legacy_baseline.sof" を事前にご用意ください。
参考: HPS GHRD Linux Boot Examples - Altera FPGA Developer Site
※ ATF、U-Boot、LinuxKernel、Rootfs については 「3. SD カードイメージの作成」 で実施しますので、準備の時点では .sof ファイルのみの作成で問題ありません(Build Arm Trusted Firmware 以降の手順は不要となります)。
2-4. Yocto 環境の事前準備
この記事では Root File System を Yocto プロジェクトの環境を用いて作成します。そのため、事前に Yocto ビルドが実行できる環境を準備します。
2-4-1. パッケージのインストール
下記コマンドを実行して Yocto ビルドに必要なパッケージをインストールします。
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install openssh-server mc libgmp3-dev libmpc-dev gawk wget git diffstat unzip texinfo gcc \
build-essential chrpath socat cpio python3 python3-pip python3-pexpect xz-utils debianutils iputils-ping \
python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev pylint xterm python3-subunit mesa-common-dev zstd \
liblz4-tool git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison xinetd \
tftpd tftp nfs-kernel-server libncurses5 libc6-i386 libstdc++6:i386 libgcc++1:i386 lib32z1 \
device-tree-compiler curl mtd-utils u-boot-tools net-tools swig -y
2-4-2. sh コマンドのリンク元変更
Yocto プロジェクトのスクリプトは sh コマンドが "bash" で実行される前提で作成されています。しかし Ubuntu の場合、"dash" がデフォルト設定となっているため、以下のコマンドを実行して sh コマンドのリンク元を "dash" から "bash" に変更します。
sudo ln -sf /bin/bash /bin/sh
3. SD カードイメージの作成
3-1. 環境セットアップ
各実行ファイルを作成するための環境構築を行います。
3-1-1. 作業ディレクトリーの作成
下記コマンドを実行して環境作成用の作業ディレクトリー(agilex5_boot.enablement)を作成します。
mkdir agilex5_boot.enablement
cd agilex5_boot.enablement
export TOP_FOLDER=`pwd`
3-1-2. ツールチェーンのセットアップ
下記コマンドを実行して、ARM Developer サイトから GNU ツールチェーンをダウンロードし、ツールチェーンのパス等を環境変数に設定します。
cd $TOP_FOLDER
wget https://developer.arm.com/-/media/Files/downloads/gnu/11.2-2022.02/binrel/\
gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz
tar xf gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz
rm -f gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar.xz
export PATH=`pwd`/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu/bin:$PATH
export ARCH=arm64
export CROSS_COMPILE=aarch64-none-linux-gnu-
3-2. 事前準備ファイルの格納
「2. 事前準備」 の手順で事前に準備した "hello_world.bin"、"legacy_baseline.sof" を $TOP_FOLDER 配下に格納します。
3-3. Arm Trusted Firmware のビルド
下記コマンドを実行して Arm Trusted Firmware (ATF) のダウンロード & ビルドを実行します。
cd $TOP_FOLDER
git clone -b QPDS25.1_REL_GSRD_PR https://github.com/altera-fpga/arm-trusted-firmware
cd arm-trusted-firmware
make -j 48 PLAT=agilex5 bl31
上記コマンドの実行が正常終了すると下記ファイルが生成されます。
-
- $TOP_FOLDER/arm-trusted-firmware/build/agilex5/release/bl31.bin
3-4. U-Boot のビルド
3-4-1. U-Boot ソースコードのダウンロード
下記コマンドを実行して U-Boot ソースコードを Altera github からダウンロードし、ダウンロードしたディレクトリに移動します。
cd $TOP_FOLDER
git clone -b QPDS25.1_REL_GSRD_PR https://github.com/altera-fpga/u-boot-socfpga
cd u-boot-socfpga
3-4-2. Configuration 変更
ダウンロードした U-Boot ソースコード内の Configuration を変更します。
① CONFIG_BOOTCOMMAND の変更
CONFIG_BOOTCOMMAND に下記設定を追加し、Bare-metal アプリケーションを CPU3(Cortex-A76#1)で動作させるように変更します。
-
-
fatload mmc 0:1 0x90200000 hello_world.bin
-> SD カードの FAT パーティションから hello_world.bin を読み出し、DDR の 0x90200000 番地にロード -
dcache flush
-> 0x90200000 番地にロードした hello_world.bin プログラムを、他の CPU でも参照できるようにキャッシュフラッシュ -
smc 0xC4000003 0x300 0x90200000 0
-> SMC を実行して 0x90200000 のエントリーポイントから CPU3 を起動。SMC コマンドのフォーマットは下記となります:- 第 1 引数: 0xC4000003 ... CPU ON のコマンド ID
- 第 2 引数: 0x300 ............. CPU No. ※ MPIDR_EL1 レジスタのフォーマットで Aff1-0 フィールド(Bit#11-0)の値を設定する必要がある
- 第 3 引数: 0x90200000 ... エントリーポイント
- 第 4 引数: 0 ..................... 未使用
-
fatload mmc 0:1 0x90200000 hello_world.bin
ポイント:
Agilex™ 7 FPGA の場合、Aff0 フィールド(Bit#3-0)が CPU No. に該当するため、第 2 引数の値は "0x0003" を設定することになります。
-
-
setenv bootargs maxcpus=3
-> bootargs の環境変数に maxcpus=3 を追加し、Linux の SMP で CPU3 を未使用にする
-
setenv bootargs maxcpus=3
② CONFIG_CMD_SMC の追加
以下の SMC コマンドの Configuration を追加します。
-
- CONFIG_CMD_SMC=y
上記の変更を加えた Configuration 変更のコマンドは以下となります。
※ 上記変更以外の設定については、HPS GHRD Linux Boot Examples - Altera FPGA Developer Site の設定を踏襲しています。
# enable dwarf4 debug info, for compatibility with arm ds
sed -i 's/PLATFORM_CPPFLAGS += -D__ARM__/PLATFORM_CPPFLAGS += -D__ARM__ -gdwarf-4/g' arch/arm/config.mk
# only boot from SD, do not try QSPI and NAND
sed -i 's/u-boot,spl-boot-order.*/u-boot\,spl-boot-order = \&mmc;/g' arch/arm/dts/socfpga_agilex5_socdk-u-boot.dtsi
# disable NAND in the device tree
sed -i '/&nand {/!b;n;c\\tstatus = "disabled";' arch/arm/dts/socfpga_agilex5_socdk-u-boot.dtsi
# link to atf
ln -s ../arm-trusted-firmware/build/agilex5/release/bl31.bin
# create configuration custom file.
cat << EOF > config-fragment
# use Image instead of kernel.itb
CONFIG_BOOTFILE="Image"
# disable NAND/UBI related settings from defconfig.
CONFIG_NAND_BOOT=n
CONFIG_SPL_NAND_SUPPORT=n
CONFIG_CMD_NAND_TRIMFFS=n
CONFIG_CMD_NAND_LOCK_UNLOCK=n
CONFIG_NAND_DENALI_DT=n
CONFIG_SYS_NAND_U_BOOT_LOCATIONS=n
CONFIG_SPL_NAND_FRAMEWORK=n
CONFIG_CMD_NAND=n
CONFIG_MTD_RAW_NAND=n
CONFIG_CMD_UBI=n
CONFIG_CMD_UBIFS=n
CONFIG_MTD_UBI=n
CONFIG_ENV_IS_IN_UBI=n
CONFIG_UBI_SILENCE_MSG=n
CONFIG_UBIFS_SILENCE_MSG=n
# disable distroboot and use specific boot command.
CONFIG_DISTRO_DEFAULTS=n
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT_HUSH_PS2="> "
CONFIG_USE_BOOTCOMMAND=y
CONFIG_BOOTCOMMAND="load mmc 0:1 ${loadaddr} ghrd.core.rbf; fpga load 0 ${loadaddr} ${filesize};bridge enable; mmc rescan; fatload mmc 0:1 0x90200000 hello_world.bin; dcache flush; smc 0xC4000003 0x300 0x90200000 0; fatload mmc 0:1 82000000 Image;fatload mmc 0:1 86000000 socfpga_agilex5_socdk.dtb;setenv bootargs console=ttyS0,115200 root=${mmcroot} rw rootwait maxcpus=3;booti 0x82000000 - 0x86000000"
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_DOS_PARTITION=y
CONFIG_SPL_DOS_PARTITION=y
CONFIG_CMD_PART=y
CONFIG_SPL_CRC32=y
CONFIG_LZO=y
CONFIG_CMD_DHCP=y
# enable more QSPI flash manufacturers
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_GIGADEVICE=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SPI_FLASH_ISSI=y
# enable SMC
CONFIG_CMD_SMC=y
EOF
3-4-3. U-Boot のビルド実行
変更した Configuration 設定にしたがって、下記コマンドを実行して U-Boot を実行します。
make clean && make mrproper
make socfpga_agilex5_defconfig
./scripts/kconfig/merge_config.sh -O . -m .config config-fragment
make -j 64
上記コマンドの実行が正常終了すると下記ファイルが生成されます。
-
- $TOP_FOLDER/u-boot-socfpga/u-boot.itb
- $TOP_FOLDER/u-boot-socfpga/spl/u-boot-spl-dtb.hex
3-5. Linux Kernel のビルド
下記コマンドを実行して Linux Kernel のダウンロード & ビルドを実行します。
cd $TOP_FOLDER
git clone -b QPDS25.1_REL_GSRD_PR https://github.com/altera-fpga/linux-socfpga
cd linux-socfpga
cat << EOF > config-fragment-agilex5
# Enable Ethernet connectivity so we can get an IP address
CONFIG_MARVELL_PHY=y
EOF
make defconfig
./scripts/kconfig/merge_config.sh -O ./ ./.config ./config-fragment-agilex5
make oldconfig
make -j 64 Image && make intel/socfpga_agilex5_socdk.dtb
上記コマンドの実行が正常終了すると下記ファイルが生成されます。
-
- $TOP_FOLDER/linux-socfpga/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk.dtb
- $TOP_FOLDER/linux-socfpga/arch/arm64/boot/Image
3-6. Root File System の作成
下記コマンドを実行して Yocto プロジェクトからレイヤー、レシピをダウンロードし、local.conf 編集後、bitbake を実行します。
cd $TOP_FOLDER
mkdir yocto && cd yocto
git clone -b styhead https://git.yoctoproject.org/poky
git clone -b styhead https://git.yoctoproject.org/meta-intel-fpga
git clone -b styhead https://github.com/openembedded/meta-openembedded
source poky/oe-init-build-env ./build
echo 'MACHINE = "agilex5_dk_a5e065bb32aes1"' >> conf/local.conf
echo 'BBLAYERS += " ${TOPDIR}/../meta-intel-fpga "' >> conf/bblayers.conf
echo 'BBLAYERS += " ${TOPDIR}/../meta-openembedded/meta-oe "' >> conf/bblayers.conf
echo 'CORE_IMAGE_EXTRA_INSTALL += "openssh gdbserver"' >> conf/local.conf
bitbake core-image-minimal
上記コマンドの実行が正常終了すると下記ファイルが生成されます。
-
- $TOP_FOLDER/yocto/build/tmp/deploy/images/agilex5_dk_a5e065bb32aes1/core-image-minimal-agilex5_dk_a5e065bb32aes1.rootfs.tar.gz
3-7. FPGA Configuration File の作成
HPS Boot First モードの場合、U-Boot(SSBL)起動以降のタイミングで FPGA Core のコンフィグレーションを実施する必要があります。
そのため、FPGA Core のコンフィグレーション・データ(core.rbf ファイル)も SD カードに格納しておく必要があります。
下記コマンドを実行して、「2. 事前準備」 の手順で事前に準備した "legacy_baseline.sof" と 「3-4. U-Boot のビルド」 で作成した "u-boot-spl-dtb.hex" から "ghrd.core.rbf" を作成します。
cd $TOP_FOLDER
quartus_pfg -c $TOP_FOLDER/legacy_baseline.sof ghrd.jic \
-o device=MT25QU128 \
-o flash_loader=A5ED065BB32AE6SR0 \
-o hps_path=$TOP_FOLDER/u-boot-socfpga/spl/u-boot-spl-dtb.hex \
-o mode=ASX4 \
-o hps=1
上記コマンドの実行が正常終了すると下記ファイルが生成されます。
-
- $TOP_FOLDER/ghrd.core.rbf
- $TOP_FOLDER/ghrd.hps.jic
ポイント:
"ghrd.core.rbf" と同時に生成される "ghrd.hps.jic" は SD カードには含めないファイルとなりますが、動作確認をする上で SDM 側の QSPI Flash に Write するファイルとなります。
3-8. SD カードイメージの生成
下記コマンドを実行して SD カード イメージを生成します。
下記コマンドでは、SD カードイメージ生成用のツール(make_sdimage_p3.py)をダウンロードし、SD カードに書き込むファイルを収集後、ツールを実行しています。
cd $TOP_FOLDER
mkdir sd_card && cd sd_card
wget https://releases.rocketboards.org/release/2020.11/gsrd/tools/make_sdimage_p3.py
sed -i 's/\"\-F 32\",//g' make_sdimage_p3.py
chmod +x make_sdimage_p3.py
mkdir fatfs && cd fatfs
cp $TOP_FOLDER/ghrd.core.rbf .
cp $TOP_FOLDER/hello_world.bin .
cp $TOP_FOLDER/u-boot-socfpga/u-boot.itb .
cp $TOP_FOLDER/linux-socfpga/arch/arm64/boot/Image .
cp $TOP_FOLDER/linux-socfpga/arch/arm64/boot/dts/intel/socfpga_agilex5_socdk.dtb .
cd ..
mkdir rootfs && cd rootfs
tar xf $TOP_FOLDER/yocto/build/tmp/deploy/images/agilex5_dk_a5e065bb32aes1/core-image-minimal-agilex5_dk_a5e065bb32aes1.rootfs.tar.gz
cd ..
sudo python3 make_sdimage_p3.py -f \
-P fatfs/*,num=1,format=fat32,size=64M \
-P rootfs/*,num=2,format=ext3,size=64M \
-s 140M \
-n sdcard.img
上記コマンドの実行が正常終了すると下記ファイルが生成されます。
- $TOP_FOLDER/sd_card/sdcard.img
4. 実行結果と確認
Agilex™ 5 FPGA E-Series Premium Development Kit に対し、「3. SD カードイメージの作成」 で作成したイメージ書き込んだ SD カードを挿入し、「3-7. FPGA Configuration File の作成」 で出力された "ghrd.hps.jic" を Quartus® Prime の Programmer ツールを使用して SDM 側の QSPI Flash に書き込みます。
その後、電源を OFF -> ON すると下記の U-Boot ログがターミナル上に出力されます。
U-Boot 2025.01-gcd3a9044d661-dirty (Aug 06 2025 - 09:11:31 +0900)socfpga_agilex5
CPU: Intel FPGA SoCFPGA Platform (ARMv8 64bit Cortex-A55/A76)
Model: SoCFPGA Agilex5 SoCDK
DRAM: 2 GiB (effective 8 GiB)
Core: 51 devices, 25 uclasses, devicetree: separate
WDT: Not starting watchdog@10d00200
WDT: Not starting watchdog@10d00300
WDT: Not starting watchdog@10d00400
WDT: Not starting watchdog@10d00500
WDT: Not starting watchdog@10d00600
MMC: mmc0@10808000: 0
Loading Environment from FAT... Unable to read "uboot.env" from mmc0:1...
In: serial0@10c02000
Out: serial0@10c02000
Err: serial0@10c02000
Starting HPS SMMU test for SDM.
sdm_tbu_stream_ctrl_reg_1_sdm : 0x3
smmuSetBaseAddr()
smmu1_S_IDR1.secure : 0x0
smmuInitStreamTable()
main(): Installing Event Queue
main(): Installing Command Queue
Issue commands to invalidate TLBs
main(): Enabling SMMU (Non-secure only)
smmuEnableCommandProcessing
smmuEnableEventQueue
smmuEnableTranslation()
main(): Intializing a context descriptor
~
Hit any key to stop autoboot: 5 4 3 2 1 0
1904640 bytes read in 93 ms (19.5 MiB/s)
..FPGA reconfiguration OK!
2107848 bytes read in 101 ms (19.9 MiB/s)
Res: 0x0 0x300 0x90200000 0x0
Hello, World!
46778880 bytes read in 2018 ms (22.1 MiB/s)
25456 bytes read in 14 ms (1.7 MiB/s)
## Flattened Device Tree blob at 86000000
Booting using the fdt blob at 0x86000000
Working FDT set to 86000000
Loading Device Tree to 00000000feb05000, end 00000000feb0e36f ... OK
Working FDT set to feb05000
Starting kernel ...
上記のログより、CPU3 を起動する SMC コマンドが実行され、Bare-metal アプリケーションが起動されていることが、下記のログ部分から分かります。
---------------------------------------
Res: 0x0 0x300 0x90200000 0x0
Hello, World!
---------------------------------------
また、Linux 起動完了後に デバッガー(Arm® DS)を起動して、各 CPU の プログラムカウンターを確認してみると、下図の通り、Cortex-A76 #1 のみ Bare-metal のプログラム領域(0x90200000~)で動作しているのが確認できます。
【図 3】 Arm® DS デバッガ―上のプログラムカウンター
5. おわりに
この記事では、Agilex™ FPGA 上で Linux と Bare-metal アプリケーションを同時に動作させる環境を構築する方法をご紹介しました。
特筆すべきは、U-Boot の設定を少し変更するだけで、複数の CPU コアに異なる OS を割り当てる柔軟なマルチ OS 構成が実現できるという点です。
このアプローチにより、リアルタイム処理が求められるタスクには Bare-metal を、汎用的な処理には Linux を割り当てるなど、システム全体の最適化が可能になります。
Agilex™ FPGA の持つ高い柔軟性を活かし、用途に応じた効率的なシステム設計を是非ご検討ください。