SDカードイメージ作り for Agilex™ SoC ~Cyclone®︎ V SoCとの比較を添えて~

今回は、Intel®︎ Agilex™️ SoC向けのSDカードの作り方を書いていこうと思う。きっかけは
[Intel® Agilex™ FPGAs (code named Sundance Mesa) Deliver Industry Leading Power-Efficient Performance][LINK_SM]
が発表されたからである。このデバイスは将来的にCyclone®︎ V SoCを乗り換える動機につながると考えています。

とはいえ、まだ世の中にデバイスがあるわけではないので、同じIntel® Agilex™️シリーズですでに量産されている Intel® Agilex™ F-Series Transceiver SoC Development Kitを使ってIntel® Agilex™️ SoC向けのSDカード作りに取り組んでみようと思います。

ゴールはDE10-Nano/FPGA Cloud Connectivity Kit(Cyclone®︎ V SoC)にて使われていたSDカードイメージのマイグレーション(コンテナが動作すること)であり、Cyclone®︎ V SoCでの開発経験があるが、Intel® Stratix®︎ 10 SoC/Intel® Agilex™️ SoCでの開発経験がない方向けの記事になっています。


著者環境
+ Build SD Card Image
  + FPGA Image: CentOS 7.4 with Intel® Quartus® Prime Software 22.3
  + Other Image: CentOS 7.4 using Docker(Base Image:Debian 11.5/bullseye))
+ Write and Customize SD Image: Ubuntu 20.04
+ Device: Intel® Agilex™ F-Series Transceiver-SoC Development Kit(Engineering Sample/ES, Device OPN:AGFB014R24A2E3VR0)
(これ以降は Intel® Agilex™ SoC DKと略)
+ Intel® Quartus® Prime Software Version: v22.3 Pro Edition
+ GCC Arm Cross Compiler: arm-11.2-2022.02-x86_64

> [!NOTE]  
> 1. Host OSに関しては、筆者が普段から使っている環境ということもあり、少しバージョンが古いものとなっています。
> 後に出てくるRocketBoards.orgの記事では、Ubuntu20.04を推奨しています。
> 利用したバージョンではそのまま動かなかったので、Dockerをかましてビルドしました。[後述](#tips-dockerコンテナを使ってsdカードのパーツをビルドする)
> 2. Deviceは今回ES版を利用しています。これに関しては、FPGAイメージ作成の部分にのみ差が出てきます。

## まずはじめに
大前提として、今回の記事で使うコマンドのほとんどは

+ [Agilex™ SoC GSRD][LINK:AGSCGSRD]
+ [Building Bootloader for Stratix 10 and Agilex][LINK_BBSA]

この2つのドキュメントの掛け合わせです。
前者のドキュメントではYoctoと呼ばれるオープンソースベースのビルドプロジェクトを使って一括でビルドすることができるドキュメントとなっています。
後者はそのパーツごとにビルドするドキュメントとなっています。

前者のYoctoを使ったビルドでは内部で使うツール等を自動でビルド、利用してくれるというメリットがある一方で、
プロジェクト中で何がどう実行されているのかが非常に理解しづらいと思います。
後者のパーツごとにビルドするほうは実行するコマンド量は多いですが、それぞれ何をビルドしているのかがわかりやすいので、
Cyclone®︎ V SoCでの開発経験がある方は後者のドキュメントのほうが馴染み深いかもしれません。
また、後半の記事で書くようなオプションをカスタマイズする場合はこちらのほうが楽だと思います。

こういった経緯から、今回は[Building Bootloader for Stratix 10 and Agilex][LINK_BBSA]をベースに記事を書きます。
（Yoctoでのカスタマイズも一応理解したつもりなので、また時間あれば書きたいな、、）

そしてドキュメントはほぼ手順が記載してあるのみで、 技術的背景については留意されていません。
本記事はそれらの内容を実際に実行しつつ、それらの背景となる知識をカバーする内容になります。

>[!Note]
> 書いていたら文章がすごい量になってきてしまい可読性の問題から、一部RocketBoards.org内のコマンドと重複する部分は今回書いてません。RocketBoards.orgのリンクを必ず近くに置くので合わせて読んでください。


## SDイメージの構成について

まずは振り返りとして、
[DE10-Nano/FPGA Cloud Connectivity Kit using Microsoft* Azure][LINK_FCCKSDCI]のチュートリアルで使われていた[SDカードイメージ][LINK_FCCKSDCI](!SDカードイメージへの直接URLなのでご注意)をみてみます。

(Cyclone®︎ V SoC)
```bash
root@de10nano:~# ls -l /dev/mmcblk0*
brw-rw---- 1 root disk 179, 0 Oct 20 22:19 /dev/mmcblk0
brw-rw---- 1 root disk 179, 1 Oct 20 22:19 /dev/mmcblk0p1 #U-Boot, zImage, DTB
brw-rw---- 1 root disk 179, 2 Oct 20 22:19 /dev/mmcblk0p2 #Linux Filesystem
brw-rw---- 1 root disk 179, 3 Oct 20 22:19 /dev/mmcblk0p3 #Preloader
```
このように3つのパーティションが切られていました。パーティション1にはU-Boot、zImage, DTB(Device Tree Blob)とLinuxが起動するまでに必要なもの、パーティション2にはLinux Filesystem(Ubuntu18.04)、パーティション3は直接マウントできませんが、Preloaderが入っていました。

続いて、Intel® Agilex™ SoCのイメージをみてみます。

(Intel® Agilex™ SoC)
```bash
root@agilex:~# ls -l /dev/mmcblk0*
brw-rw---- 1 root disk 179, 0 Apr 21 21:54 /dev/mmcblk0
brw-rw---- 1 root disk 179, 1 Apr 21 21:54 /dev/mmcblk0p1 #U-Boot, Image, DTB 
brw-rw---- 1 root disk 179, 2 Apr 21 21:54 /dev/mmcblk0p2 #Linux Filesystem
```

パーティションが２つに減っています。理由としては、Boot Upの手順が変わっているからです。

## Boot Up手順の違い
Intel® Agilex™ SoC(正確にはIntel® Stratix® 10 SoCから)ではCyclone®︎ VとのBootの手順がやや微細化しているように感じるかもしれません。これは[SDM (Secure Device Manager)][LINK_SDM]による影響です。

[Cyclone®︎ V SoC: Typical HPS Boot Flow][LINK:CVSCBF]  
[Intel® Agilex™ SoC: Typical HPS Boot Flow][LINK:AGSCBF]

ざっくりとした理解としては、Cyclone®︎ VのPreloaderステージとIntel® Agilex™ SoCのATF(Arm Trusted Firmware)　ステージ終了時がほぼ同じイメージです。SDMのステージはCyclone®︎ VのBoot ROMよりも高機能なステージとなるので、SDM=Boot ROM+Preloaderのステージの一部　というように思うとよいでしょう。

### SDMの存在
Intel® Stratix️®︎ 10より、FPGAのイメージの書き込みはSDMというものが行うようになっています。SDMの存在により、FPGAは常にConfigurationする前にSecureなイメージかを確認することができるなどのメリットが存在します。

SDMはBoot ROMに加えてプロセッサを有しており、Boot時にはまず初めにSDMをBootさせる必要があります。
このBootイメージは、Intel®︎ Agilex™ SoC DKではHPSにつながっているSDカードからの読み出しはすることができない（そもそもSDカードってオプションですからね)ので、搭載されているQSPI Flashから読み出します。

> [!Note]
> SDMの登場により、HPS First/FPGA Firstという2種類のConfigurationの方法があります。
> 少しややこしいですが、こちらの[Intel︎® Agilex™ SoC FPGA Boot User Guide:Boot Flow Overview][LINK_IAGSCBOOT_USERGUIDE]では、ステージの切り分け方が異なっています。 RocketBoards.orgの作り方では、基本的にはHPS FirstでのBootになっています。
> ドキュメント内のFSBL(First Stage Bootloader)には、先ほどのU-Boot SPLとATFが含まれます。

### ARM Trusted Firmware-A(TF-A/ATF)
Intel®︎ Stratix®︎ 10 SoCよりHPS内のArmを使う際はTrusted Firmwareを使う必要があります。
こちらはArm Aシリーズを使う場合のお作法的なものだという理解で構いません。
特にカスタムするシチュエーションも多くはないと思います。参考用にURLをいくつか載せておきます。

[Trusted Firmware-A Documentation][LINK_TFA]
[Intel︎ SoC FPGA Documentation for Trusted Firmware-A][LINK_ISOCTFA]

このFirmwareは後にuboot.itbというファイル内に格納されます。


### U-Boot SPL(Secondary Program Loader)
U-Bootの２番目のローダーではなく、全体のbootの順番としての２番目と理解するとわかりやすいです。
SPLのステージではIOやSDRAMの最低限の設定を行います。U-Boot SPLに関しては色んな方がまとめているので、そちらを参考にしてみてください。  
[Develop U-Boot:Generic SPL framework:U-Boot Phases][LINK_UBOOT]

<!--
U-Boot References:
https://qiita.com/ikwzm/items/efacec8d8e0744e17d45
https://blog.techlab-xe.net/memo-uboot-bootloader/
http://blog.kmckk.com/archives/4414137.html
-->

## SDカード構成まとめ
改めて、Intel®︎ Agilex™ SoC DKの起動に必要なファイルをまとめてみます。
具体的なファイル名が書いてあるものは、SDカードをマウントしたときに見えるファイル名です。

SDカード外(QSPI Flashに格納)
+ Phase 1 FPGA Image(.jic)
  + Phase 1 FPGA Image
  + U-Boot SPL Hex/Binary(!New)

SDカード:パーティション1
+ Linux Kernel Image(Image)
+ Phase 2 FPGA Image(ghrd.core.rbf)
+ Device Tree Blob(socfpga_agilex_socdk.dtb)
+ u-boot.itb
  + U-Boot Image
  + Trusted Firmware-A(New!, RocketBoards.org内の記事ではATFと記述)
  + Device Tree File

SDカード:パーティション2
+ Rootfs Image

それではそれぞれのファイルを作っていきましょう。このドキュメントを実行するコマンドは  
[Building Bootloader for Stratix 10 and Agilex:Agilex - Boot from SD Card][LINK_BBSA_Boot]  
のドキュメントと基本的に同じなのでセクション名をそのまま引用します。

>[!NOTE]
> Yoctoビルドの場合は, Linux Kernel Image+Phase 2 FPGA Image+Device Tree Blobを全て合わせてkernel.itbというファイルを形成します。

## B. Build Hardware Design (! ES/Production 違いあり !)
このセクションでは、Phase 1, Phase 2のの両方を含んだコンフィギュレーションファイル(.sof)をGHRD(Golden Hardware Reference Design)から作成します。ESのボードでは一部機能が制限されていることとデバイスのOPNが異なることに注意します。  
参考:[Intel︎® Agilex™ F-Series Transceiver-SoC Development Kit User Guide][LINK_AGILEXDKUG]

```bash
cd $TOP_FOLDER
rm -rf  ghrd-socfpga-QPDS-22.3pro-21.1std QPDS-22.3pro-21.1std.zip agilex_soc_devkit_ghrd
wget https://github.com/altera-opensource/ghrd-socfpga/archive/refs/tags/QPDS-22.3pro-21.1std.zip
unzip QPDS-22.3pro-21.1std.zip
mv ghrd-socfpga-QPDS-22.3pro-21.1std/agilex_soc_devkit_ghrd .
rm -rf  ghrd-socfpga-QPDS-22.3pro-21.1std QPDS-22.3pro-21.1std.zip
cd agilex_soc_devkit_ghrd
# disable sgmii and partial reconfiguration - to decrease build time
export HPS_ENABLE_SGMII=0
export ENABLE_PARTIAL_RECONFIGURATION=0

export QUARTUS_DEVICE=AGFB014R24A3E3VR0 #ES Board Only
export ENABLE_HPS_EMIF_ECC=0 #ES Board Only

~/intelFPGA_pro/22.3/nios2eds/nios2_command_shell.sh make scrub_clean_all
~/intelFPGA_pro/22.3/nios2eds/nios2_command_shell.sh make generate_from_tcl
# change the board id to be 4 - the one used when booting from SD card

#Production Board
#sed -i 's/set_global_assignment -name STRATIX_JTAG_USER_CODE .*/\
#set_global_assignment -name STRATIX_JTAG_USER_CODE 4/g' ghrd_agfb014r24b2e2v.qsf

# ES Board
sed -i 's/set_global_assignment -name STRATIX_JTAG_USER_CODE .*/\
set_global_assignment -name STRATIX_JTAG_USER_CODE 4/g' ghrd_agfb014r24a3e3vr0.qsf

~/intelFPGA_pro/22.3/nios2eds/nios2_command_shell.sh make all
cd ..
```
これにより、
`ghrd_agfb014r24b2e2v.sof`(Production版)ないしは`ghrd_agfb014r24a3e3vr0.sof`(ES版)
が作成されます。
Phase 1とPhase 2の切り分けについては、Bootloader(U-boot SPL)のバイナリを作成した後に行います。

## C. Build Arm Trusted Firmware / D. Build U-Boot
この部分に関しては特に変更がないのでドキュメントを参考にしてください。  
[Building Bootloader for Stratix 10 and Agilex:Agilex - Boot from SD Card][LINK_BBSA_Boot]  

Build Arm Trusted Firmware で`bl31.bin` を作成し、Build U-Bootで U-Boot SPLである
`u-boot-spl-dtb.hex`に加えて、U-bootのイメージである`u-boot.itb`を作成します。

## E. Prepare QSPI Image (! ES/Production 違いあり !) 
Productionボードの場合はRocketBoards.orgのドキュメントの通りです。
[Building Bootloader for Stratix 10 and Agilex:Agilex - Boot from SD Card][LINK_BBSA_Boot]  

ESボードの場合はQSPI FlashやFPGAのOPNを変更する必要があります。

```bash
~/intelFPGA_pro/22.3/nios2eds/nios2_command_shell.sh \
  quartus_pfg -c agilex_soc_devkit_ghrd/output_files/ghrd_agfb014r24a3e3vr0.sof \
  ghrd.jic \
  -o hps_path=u-boot-socfpga/spl/u-boot-spl-dtb.hex \
  -o device=MT25QU02G \
  -o flash_loader=AGFB014R24A3E3VR0 \
  -o mode=ASX4 \
  -o hps=1
```
これを実行すると、
QSPI Flashに格納すべきイメージ`ghrd.hps.jic`(Phase 1 FPGA Image with U-boot SPL)および
`ghrd.core.rbf`(Phase 2 FPGA Image)の2つが生成されます。

## Linux Kernelビルド
RocketBoards.orgのドキュメントでは次にSD Cardのイメージ作りになっていますが、まだ材料が足りないので順番を少し読み替えます。  
[Building Bootloader for Stratix 10 and Agilex:Appendix - Building Linux Binaries][LINK_BBSA_BLINUX]  
このセクションにジャンプして`Building Linux Kernel`のサブセクションまでを書いてある通りに実行します。

## Rootfs
続いてドキュメントでは、Yocto内のPokyという組み込み向けのDistributionを使っています。これは軽量で最初に試すにはよいと思います。一方で、Ubuntuなどの一般的なDistributionを使った方が利用できるパッケージも多く便利です。今回はUbuntu20.04に入れ替えてみたいと思います。

まずは、[Ubuntu Base 20.04.5 LTS (Focal Fossa)][LINK_UBUNTU_DL]にアクセスします。するとbaseのrootfsだけをダウンロードすることができます。この中にある`-arm64`がついたtar.gzをダウンロードします。執筆(2022/12)時点では20.04.5が最新でしたので、これをダウンロードします。
```bash
cd $LINUX_BIN/a53
wget https://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/ubuntu-base-20.04.5-base-arm64.tar.gz
```
ここでダウンロードしてきたものがYoctoでビルドした`core-image-minimal-agilex.tar.gz`と等価なのです。

>[!Note]
> ここでダウンロードしてきたものは最低限になっているため、このままSDカードを作成・焼き込んでも起動しません。
> SD焼き込み後SDカードのイメージを編集する必要があります。(後述)

## G. Prepare SD Card Image
ここまでで全ての材料が揃いました。

(再掲)  
SDカード外(QSPI Flashに格納)
+ Phase 1 FPGA Image(ghrd.hps.jic) ([セクションE](#e-prepare-qspi-image--esproduction-違いあり-))
  + Phase 1 FPGA Image
  + U-Boot SPL Hex/Binary(u-boot-spl-dtb.hex)([セクションC](#c-build-arm-trusted-firmware--d-build-u-boot))

SDカード:パーティション1
+ Linux Kernel Image(Image)([Linux Kernelビルド](#linux-kernelビルド))
+ Phase 2 FPGA Image(ghrd.core.rbf)([セクションE](#e-prepare-qspi-image--esproduction-違いあり-))
+ Device Tree Blob(socfpga_agilex_socdk.dtb)([セクションD](#c-build-arm-trusted-firmware--d-build-u-boot))
+ u-boot.itb([セクションD](#c-build-arm-trusted-firmware--d-build-u-boot))
  + U-Boot Image
  + Trusted Firmware-A([セクションC](#c-build-arm-trusted-firmware--d-build-u-boot))
  + Device Tree File

SDカード:パーティション2
+ Rootfs Image(ubuntu-base-20.04.5-base-arm64.tar.gz)([Rootfs](#rootfs))

これらを全て組み合わせて1つのイメージを作成します。Rootfsに関してはドキュメントと異なっているので、
筆者は`rootfs`のディレクトリにシンボジックリンクを貼って、Yoctoと簡単に切り替えられるようにしています。
Ubuntuを使う場合はその後パッケージをダウンロードする関係上大きめにパーティションを確保することをお勧めします。

また、ドキュメント内には記述されていないですが、カーネルモジュールをコピーもしておきましょう。

```bash
cd $TOP_FOLDER
sudo rm -rf sd_card && mkdir sd_card && cd sd_card
wget https://releases.rocketboards.org/release/2020.11/gsrd/tools/make_sdimage_p3.py
chmod +x make_sdimage_p3.py
mkdir sdfs &&  cd sdfs
cp $TOP_FOLDER/u-boot-socfpga/u-boot.itb .
cp $LINUX_BIN/a53/Image .
cp $LINUX_BIN/a53/socfpga_agilex_socdk.dtb .
cp $TOP_FOLDER/ghrd.core.rbf .
cd ..

#ひと工夫
mkdir rootfs-yocto && cd rootfs-yocto #yoctoでのビルドをしていない場合不要
sudo tar xf $LINUX_BIN/a53/core-image-minimal-agilex.tar.gz
sudo rm -rf lib/modules/*
sudo cp -r $LINUX_BIN/a53/modules/* lib/modules/
cd ..

mkdir rootfs-ubuntu && cd rootfs-ubuntu 
sudo tar xf $LINUX_BIN/a53/ubuntu-base-20.04.5-base-arm64.tar.gz
sudo rm -rf lib/modules/*
sudo cp -r $LINUX_BIN/a53/modules/* lib/modules/
cd ..
ln -s rootfs-ubuntu rootfs
#ひと工夫ここまで

#パーティションのサイズを変える時は、2/3/4行目のsizeを変更(下記例では、パーティション1が56M,パーティション２が800Mで合計が856M)
sudo python3 make_sdimage_p3.py -f \
-P sdfs/*,num=1,format=fat32,size=56M \
-P rootfs/*,num=2,format=ext3,size=800M \
-s 856M \
-n sdcard.img
cd ..
```
> [!Note]
> このサイズを大きくするとその分だけイメージサイズが大きくなり、SDへの書き出し時間等が増加します。

## QSPI FlashへのJICファイルの書き込み
G. Bootのセクションにある通りコマンドを実行してください。  
本文中にあるMSEL to JTAGとは、 `SW1: ON-ON-ON-ON`の状態にすることです。 
逆にQSPIからの読み出しの時は、 `SW1: ON-OFF-OFF-ON`の状態に戻してください。

```bash
cd $TOP_FOLDER/flash_image/
~/intelFPGA_pro/22.3/nios2eds/nios2_command_shell.sh \
quartus_pgm -m jtag -o "pvi;./ghrd.hps.jic"
```

## SDカードへの書き込み
出来上がったSDカードのイメージをお好きなアプリケーションやツールを使って書き込みます。
筆者はddや、[balenaEtcher][LINK_balenaEtcher]を利用しています。

```
$ sudo dd if=sdcard.img of=/dev/<your device path> status=progress
```

前述のNoteでも触れていますが、このままIntel®︎ Agilex™ SoC DKに挿しても起動しません。
U-BootがLinuxのinit processを読み込みに行って見つけられなくて止まります。
そのため書き込みが終わった後に各種設定をカスタムする必要があります。

## SDカードのカスタマイズ
SDカードを挿し直すと新しいディスクが追加され、そのパーティションが2つに見えるはずです。
```bash
$ ls /dev/sd* #SDカード挿入前
sda sda1 sda2 sda3 
$ ls /dev/sd* #SDカード挿入後
sda sda1 sda2 sda3 sdb sdb1 sdb2
$ mkdir mnt #マウント用ディレクトリ作成
$ sudo mount /dev/sdb2 mnt
```
上記の例ではsdbがSDカードのディスクです。sdb2がファイルシステムに当たるのでこの部分を設定していきます。
設定の仕方としては、色んなやり方があります。
[Cyclone® V SoC に載せるLinuxの構築手順:7. ルートファイルシステム（rootfs）の構築][LINK_SCVSOCLINUX_ROOTFS]
にて触れられている`mmdebstrap`を使うのがセーフティですが、もう少し単純にゴリ押ししてみます。

まずはアーキテクチャが異なるので、QEMUをインストールします。
```bash
sudo apt install qemu-user-static binfmt-support
```
インストールしたら、まずは必要なものをコピー、chrootするときにあると便利なサブディレクトリをマウントします。
```bash
sudo cp -b /etc/resolv.conf mnt/etc/resolv.conf 
sudo cp /usr/bin/qemu-aarch64-static mnt/usr/bin
sudo mount -t proc /proc mnt/proc
sudo mount -t sysfs /sys mnt/sys
sudo mount -o bind /dev mnt/dev
sudo mount -o bind /dev/pts mnt/dev/pts
```
するとこれだけでもchrootが可能となります。
```bash
sudo chroot mnt
```

chrootできた後は、まずはaptでパッケージを入れます。
筆者が試した限りでは、aptをそのまま叩こうとすると、エラーが出たので、/tmpにchmodしなおしています。([参考][LINK_APTERROR])
入れるパッケージはパーティションサイズ変更用の`parted`, ネットワーク周り系のアプリ、init processとしての`systemd`とお好きなエディターくらいは入れておいたほうがよいです。
```bash
chmod 1777 /tmp
apt clean && apt update
apt install -y vim git parted iproute2 netplan.io iputils-ping network-manager isc-dhcp-client kmod sudo openssh-server systemd
```

また、ユーザー等の設定もしておきます。
```bash
passwd
adduser agilex
usermod -aG sudo agilex
```
必要があればネットワークの設定も書いておくと便利です。
```bash
vim /etc/ssh/sshd_config #uncomment ﻿PasswordAuthentication yes
cat << EOF > /etc/netplan/00-default.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: yes 
EOF
```

ここまで終わったらセッションを終了し各ディレクトリをumountしていきます。先にサブディレクトリをumountしないと、Target is busyと拒否してくるのでご注意ください。
```
exit #chrootの終了
sudo umount mnt/proc
sudo umount mnt/sys
sudo umount mnt/dev/pts
sudo umount mnt/dev
sudo umount mnt
```

終わったらLet's bootです！

## Bootと残念なお知らせ
Kernelが起動するところまでは、
[Building Bootloader for Stratix 10 and Agilex:Agilex™ - Boot from SD Card][LINK_BBSA_Boot]  
のドキュメントと同じログが出てくるはずです。
一方で、Root Filesystemを読み込むとUbuntuとなっています。最終的に、
```
Ubuntu 20.04.5 LTS localhost.localdomain ttyS0

localhost login: %
```
この画面まで出て来れば無事に完成です。先ほど作ったユーザー`agilex` でログインしてみましょう。
先ほどのネットワークの設定を入れていれば、SDカードと同じ基板上にあるLANケーブルをさせばIPアドレスも自動的に降ってきてインターネットへの接続もできるはずです。
まずはこれで、最新版のIntel®︎ Quartus®︎ Prime Software v22.3を使ってSDカードのイメージが作成と起動ができました。

一方で、これは[DE10-Nano/FPGA Cloud Connectivity Kit using Microsoft* Azure][LINK_FCCKSDCI]のイメージとは異なりコンテナは動作できません。
実際にやってみればわかりますが、エラーでアプリのサービスが起動しません。
```
sudo apt install -y lxc
#インストール中にエラーが発生
```
参考: [Linux Containers][LINK_LXC]

[後編][LINK_Part2]では、この問題を解決するべく、Linuxカーネルオプションのカスタマイズの仕方を紹介しコンテナを動かしてみます。お楽しみに。


## Tips: Dockerコンテナを使ってSDカードのパーツをビルドする
筆者の環境ではビルド用の高速なマシンがあるのだが、作ったのが少し前なためCentOS7.4がホストして入っています。
諸般の事情により、簡単にUbuntu20.04を入れ直すことができません。
CentOS7.4でそのままできないかと少し試行錯誤しましたが、パッケージの依存関係が解消できず諦めました。
一方でビルドするだけならDockerコンテナを使うと便利でしたのでご紹介します。
ベースとしては、RocketBoards.org内では以下のページがあります。
[Docker Yocto Build][LINK_DYB]

しかしながら、この中にあるDockerfileはあくまでYoctoを動かすための最小限のイメージとなっており、
このままではLinuxのカーネルビルドを直接実行するにはパッケージが足りません。
そこで少しカスタムすることで、直接ビルドできるように変更します。

やることは単純です。
[Building Bootloader for Stratix 10 and Agilex][LINK_BBSA]内に書かれている
Ubuntu20.04用のパッケージをDockerfileの適切な箇所に追加記入するだけです。
具体的には、17行目付近にあるuseraddの前後（つまりrootユーザーの間に)にapt-getを実行します。
apt-getの実行の仕方に関しては、大元のとなっているDockerfileを参考するのがよいでしょう。  
参考:[OE Build Container][LINK_OEBC]: [Dockerfile][LINK_OEBCD]  

ただし、`swig`と`kmod`の２つのパッケージはビルドを試していく中で別途必要でした。
参考までにカスタムする前後の差分をとって比較してみます。
```bash
$ diff Dockerfile Dockerfile.custom
17a18,26
> 
> ARG DEBIAN_FRONTEND=noninteractive
> RUN apt-get update && apt-get install -yq gawk wget git-core diffstat unzip texinfo \
>     gcc-multilib  build-essential chrpath socat cpio python python3 \
>     python3-pip python3-pexpect  xz-utils debianutils iputils-ping \
>     python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev  pylint3 xterm \
>     libncurses-dev gawk flex bison openssl libssl-dev swig kmod && \
>     rm -rf /var/lib/apt-lists/*
```

そうして完成したらDocker buildし、runします。
run時のポイントとしては、Intel® Quartus® Prime Softwareの入っているディレクトリとソースおよびgccのツール群を含んだディレクトリを全てマウントしておくと色々楽です。
コンテナログインに入れたあとは通常通りビルドするだけです。
```bash
$ docker build  -t buildSA --build-arg username=$(whoami) --build-arg build_dir=$PWD .
$ docker run -v ~/intelFPGA_pro/22.3:~/intelFPGA_pro/22.3 -v $PWD:$PWD -it --rm --user=$UID --name builder buildSA
```

## References

+ [Intel® Agilex™ FPGAs (code named Sundance Mesa) Deliver Industry Leading Power-Efficient Performance][LINK_SM]
+ [Building Bootloader for Stratix 10 and Agilex][LINK_BBSA]
+ [Agilex™ SoC GSRD][LINK:AGSCGSRD]
+ [OE Build Container][LINK_OEBC]
+ [Docker Yocto Build][LINK_DYB]
+ [DE10-Nano/FPGA Cloud Connectivity Kit using Microsoft* Azure][LINK_FCCKMSEdgeDoc]
+ [Cyclone®︎ V SoC GSRD][LINK:CVSCGSRD]  
+ [Intel︎® Agilex™ SoC FPGA Boot User Guide:Boot Flow Overview][LINK_IAGSCBOOT_USERGUIDE]
+ [Intel︎® Agilex™ Configuration User Guide: Secure Device Manager][LINK_SDM]
+ [Trusted Firmware-A Documentation][LINK_TFA]
+ [Intel︎ SoC FPGA Documentation for Trusted Firmware-A][LINK_ISOCTFA]
+ [Develop U-Boot:Generic SPL framework:U-Boot Phases][LINK_UBOOT]
+ [Ubuntu Base 20.04.5 LTS (Focal Fossa)][LINK_UBUNTU_DL]
+ [balenaEtcher - Flash OS images to SD cards &amp; USB drives][LINK_balenaEtcher]
+ [Cyclone︎® V SoC に載せるLinuxの構築手順][LINK_SCVSOCLINUX]
+ [sudo apt-get update couldn't create temporary file][LINK_APTERROR]
+ [Intel︎® Agilex™ F-Series Transceiver-SoC Development Kit User Guide][LINK_AGILEXDKUG]
+ [Linux Containers][LINK_LXC]
+ [コンテナ Ready SDカードイメージ作成 for Intel® Agilex™ SoC][LINK_Part2]

[LINK_BBSA]: https://www.rocketboards.org/foswiki/Documentation/BuildingBootloader
[LINK_OEBC]: https://github.com/YoeDistro/docker-yoe-build/
[LINK_OEBCD]:https://rocketboards.org/foswiki/pub/Documentation/DockerYoctoBuild/Dockerfile
[LINK_DYB]: https://www.rocketboards.org/foswiki/Documentation/DockerYoctoBuild
[LINK_FCCKMSEdgeDoc]: https://github.com/intel-iot-devkit/terasic-de10-nano-kit/tree/master/azure-de10nano-document
[LINK:CVSCGSRD]:https://www.rocketboards.org/foswiki/Documentation/Cyclone︎VSoCGSRD
[LINK:AGSCGSRD]:https://www.rocketboards.org/foswiki/Documentation/AgilexSoCGSRD
[LINK_IAGSCBOOT_USERGUIDE]:https://www.intel.com/content/www/us/en/docs/programmable/683389/21-4/boot-flow-overview.html
[LINK_SDM]:https://www.intel.com/content/www/us/en/docs/programmable/683673/22-2/secure-device-manager.html  
[LINK_TFA]:https://trustedfirmware-a.readthedocs.io/en/latest/
[LINK_ISOCTFA]:https://github.com/altera-opensource/arm-trusted-firmware
[LINK_UBOOT]:https://u-boot.readthedocs.io/en/latest/develop/spl.html#u-boot-phases
[LINK_UBUNTU_DL]:https://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/
[LINK_balenaEtcher]: https://www.balena.io/etcher/
[LINK_SCVSOCLINUX]:https://qiita.com/element/items/b52b14349a22ae0b34c7
[LINK_APTERROR]:https://superuser.com/questions/1496529/sudo-apt-get-update-couldnt-create-temporary-file
[LINK_AGILEXDKUG]:https://www.intel.com/content/www/us/en/docs/programmable/683752/current/overview.html
[LINK_LXC]:https://linuxcontainers.org/
[LINK_SM]:https://community.intel.com/t5/Blogs/Products-and-Solutions/FPGA/Intel-Agilex-FPGAs-code-named-Sundance-Mesa-Deliver-Industry/post/1413887
[LINK_Part2]:https://qiita.com/hikawai/items/84f5d25901348b7bd34a

<!--Hidden only used in the body-->
[LINK:CVSCBF]:https://www.rocketboards.org/foswiki/Documentation/CycloneVSoCGSRD#Typical_HPS_Boot_Flow
[LINK:AGSCBF]:https://www.rocketboards.org/foswiki/Documentation/AgilexSoCGSRD#Typical_HPS_Boot_Flow
[LINK_FCCKSDCI]: http://download.terasic.com/downloads/cd-rom/de10-nano/DE10-Nano-Cloud-Native.zip
[LINK_BBSA_Boot]:https://www.rocketboards.org/foswiki/Documentation/BuildingBootloader#Agilex_45_Boot_from_SD_Card
[LINK_BBSA_BLINUX]: https://www.rocketboards.org/foswiki/Documentation/BuildingBootloader#Appendix_45_Building_Linux_Binaries
[LINK_SCVSOCLINUX_ROOTFS]:https://qiita.com/element/items/b52b14349a22ae0b34c7#71-ubuntu%E3%83%AB%E3%83%BC%E3%83%88%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AE%E4%BD%9C%E6%88%90

<div class="ExternalClass7D186D114C98472EADF048741389811D"><p>​<br><br></p></div><div class="ExternalClassF6AD3A5B3FA24E9F85501B9B4261A00C"><p><span style="font-size&#58;13px;">Code names are used by Intel to identify products, technologies, or services that are in development and not publicly available. These a​​re not &quot;commercial&quot; names and not intended to function as trademarks.​​</span>​​​​<br></p></div><div class="ExternalClassB998B292B45749158C9DE17326B9D9D9"><p>Statements in this document that refer to future plans or expectations are forward-looking statements.&#160; These statements are based on current expectations and involve many risks and uncertainties that could cause actual results to differ materially from those expressed or implied in such statements.&#160; For more information on the factors that could cause actual results to differ materially, see our most recent earnings release and SEC filings at www.intc.com.​​​​<br></p></div><div class="ExternalClassB979BBAE723940F2855468C2BD8B02AD"><br>Copies of documents which have an order number and are referenced in this document may be obtained by calling&#160;1-800-548-4725&#160;or visiting&#160;<a href="http&#58;//www.intel.com/design/literature.htm">www.intel.com/design/literature.htm</a>.&#160;​<br>​<br></div><div class="ExternalClass83D67252C85741DF9243BE77507BB480">© Intel Corporation.  Intel, the Intel logo, and other Intel marks are trademarks of Intel Corporation or its subsidiaries.  Other names and brands may be claimed as the property of others​.​</div><div class="ExternalClassD599E195A26B4C5CA6451F6F8F27B74A"><p>​<br><br></p></div><div class="ExternalClass73EEFE24E22444BDAEB94EB840796D01"><div><p>​You may not use or facilitate the use of this document in connection with any infringement or other legal analysis concerning Intel products described herein. You agree to grant Intel a non-exclusive, royalty-free license to any patent claim thereafter drafted which includes subject matter disclosed herein.​</p></div></div><div class="ExternalClassC6A7CB503DD4430991D09F3A2FDBD5D3"><p>​<br><br></p></div><div class="ExternalClassCAB1C71CB78D4F219C47E293F3EAB2E6"><p>​<br>​<br></p></div><div class="ExternalClass8A412D6216B744DD807EEFDBA37BDC7B"><h1></h1><p>© Intel Corporation.&#160; Intel, the Intel logo, and other Intel marks are trademarks of Intel Corporation or its subsidiaries.&#160; Other names and brands may be claimed as the property of others​.​​<br></p></div>