APU/APU2のfirmware(coreboot)をv.4.16.xに更新する

# はじめに

手元に複数のPC Engines社製のAPU, APU2を持っているのですが、最新のfirmware(v4.16.0.3)に更新するための方法をまとめておきます。

# 参考資料

* https://pcengines.github.io/
* https://pcengines.github.io/apu2-documentation/
  * [Firmware flashing](https://pcengines.github.io/apu2-documentation/firmware_flashing/)
  * [APU2 vs APU3](https://pcengines.github.io/apu2-documentation/apu2_vs_apu3/)


# APUシリーズの生産終了について

APUシリーズのFirmwareはv4.19.0.1が最終版になることがアナウンスされています。

* https://docs.dasharo.com/variants/pc_engines/post-eol-fw-announcement/

将来的にはサブスクリプションモデルに以降する意向が表明され、[Firmware配布サイト (https://pcengines.github.io/)](https://pcengines.github.io/)ではアンケートへの協力が呼び掛けられていました。

アンケート調査結果のサマリーは下記のURLで閲覧できます。

* https://vpub.dasharo.com/e/1/dasharo-user-group-1  (DUG#1の18:30-18:50のセッションです)

資料のトピックは、年毎のサブスクリプションモデルが有望、Firmwareの販売のような先行投資・後払い型のビジネスモデルは採用できない、2023年内にcoreboot, seabiosの次期バージョンに対応する予定といったところでしょうか。

# 対象機器

APUとAPU2を対象としていますが、区別のためAPUはAPU1と記載しています。

* OS: Ubuntu 22.04 or 18.04.6
* Firmware: coreboot v4.16.0.3 for APU1 or APU2

firmwareは APU1 と APU2 で別々なので、正しいものを選択するようにしてください。

# Firmwareの更新

APU1とAPU2それぞれの更新手順と、主な画面出力を掲載しています。

## APU1の更新手順

参考資料に挙げた資料に沿って、``dmidecode``、``flashrom``コマンドを実行していきます。

Webで検索すると ``boardmismatch=force`` を指定する方法が多いのですが、参考資料では、SMBIOSテーブルの内容によるもので、メインボードのバージョンがv4.6.7 in mainline and v4.0.15 in legacy以降では正しくなっていると記載されています。

また既にOS(Ubuntu 22.04)が導入されているので、USBメモリなどは使わずに直接更新していきます。

```bash:コマンドラインのログ
## 必要なコマンドのダウンロード (firmwareイメージはAPU1用の最新版)
$ sudo apt-get install dmidecode
$ sudo apt-get install flashrom
$ wget https://3mdeb.com/open-source-firmware/pcengines/apu1/apu1_v4.16.0.3.rom

## 導入されているfirmwareのバージョンチェック
$ sudo dmidecode -s bios-version
4.0
## 別のボードでは次のような出力になりました。
SageBios_PCEngines_APU-45

## 最初に正規の方法で試してみる
$ sudo flashrom -w apu1_v4.16.0.3.rom -p internal -c "MX25L1605A/MX25L1606E/MX25L1608E"
...
This coreboot image (PC Engines:apu1) does not appear to
be correct for the detected mainboard (PC Engines:APU).
Aborting. You can override this with -p internal:boardmismatch=force.

## エラーになった場合には boardmismatch=force を加えて実行
$ sudo flashrom -w apu1_v4.16.0.3.rom -p internal:boardmismatch=force -c "MX25L1605A/MX25L1606E/MX25L1608E"
```

### 成功した際の画面出力

```text:
flashrom v1.2 on Linux 5.15.0-27-generic (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
coreboot table found at 0xdffdf000.
Found chipset "AMD SB7x0/SB8x0/SB9x0".
Enabling flash write... OK.
Found Macronix flash chip "MX25L1605A/MX25L1606E/MX25L1608E" (2048 kB, SPI) mapped at physical address 0x00000
000ffe00000.
This coreboot image (PC Engines:apu1) does not appear to
be correct for the detected mainboard (PC Engines:APU).
Proceeding anyway because user forced us to.
Reading old flash chip contents... done.
Erasing and writing flash chip... Erase/write done.
Verifying flash... VERIFIED.
```

更新後は、full reset が必要だとあるので、shutdown して、電源の抜き差しで起動しています。

dmidecodeの出力は次のようになっています。

```bash:dmidecodeの出力
$ sudo dmidecode -s bios-version
v4.16.0.3
```

## APU2の更新手順

基本的な方法は APU1 と同じですが、firmwareのバージョン、flash chipの指定がないなど、微妙に異なっています。

```bash:APU2のコマンドライン
## 必要なコマンドのダウンロード (firmwareイメージはAPU2用の最新版)
$ sudo apt-get install dmidecode
$ sudo apt-get install flashrom
$ wget https://3mdeb.com/open-source-firmware/pcengines/apu2/apu2_v4.16.0.3.rom

## 導入されているfirmwareのバージョンチェック
$ sudo dmidecode -s bios-version
88a4f96

## 最初に正規の方法で試してみる
$ sudo flashrom -w apu2_v4.16.0.3.rom -p internal 

## エラーになった場合には boardmismatch=force を加えて実行
$ sudo flashrom -w apu2_v4.16.0.3.rom -p internal:boardmismatch=force
```

## APU6の更新手順

v4.12.0.5からv4.19.0.1への更新については、boardmismatch=forceを加える必要はありませんでした。

```bash:APU6のコマンドライン
## 必要なコマンドのダウンロード (firmwareイメージはAPU2用の最新版)
$ sudo apt-get install dmidecode
$ sudo apt-get install flashrom
$ wget https://3mdeb.com/open-source-firmware/pcengines/apu6/apu6_v4.19.0.1.rom

## 導入されているfirmwareのバージョンチェック
$ sudo dmidecode -s bios-version
v4.12.0.5

## 最初に正規の方法で試してみる
$ sudo flashrom -w apu6_v4.19.0.1.rom -p internal
```

# flashrom実行後の再起動の方法

ドキュメントには``A full power cycle is required after flashing. ``と記載されていて、単純なrebootコマンドは受け付けないようにみえます。

試しにAPU1で、flashromコマンド実行後にrebootコマンドをリモートで実行してみましたが、mSATAに接続されているデバイスを認識できなくなり、起動ディスクがみつからないと真新しいBIOSが再起動を繰り返していました。

SSH接続でもfirmwareのアップグレードまではできますが、その後の稼動確認を考えると、シリアルコンソールをちゃんと接続してsudo shutdown -h now ＋ 電源コネクタの抜き差しを実行するようにする必要がありそうです。

いずれにしても挙動がおかしくなった場合には、電源の抜き差しで復旧しています。作業には物理的にアクセスできる状態であることが必要です。

# APU1とAPU2の違い

主な違いは、CPUとUSBにあります。

|  |CPU  |USB  |
|---|---|---|
|APU1 |G-T40E (2core)  | USB2.0  |
|APU2 |GX-412TC (2core) |SUB3.0  |

APU2とAPU3はLTEサポートの違いぐらいかと思われがちですが、参考資料にあるようにいくつかの点で異なっています。
特にmPCIeの仕様はAPU4を含めて、それぞれで違うようなので、Wi-Fiカードの利用などを検討する場合には注意が必要です。

## APU6の特徴

基本的な特徴はAPU2と同様ですが、SFPスロットを備えていて、これは *enp1s0" として認識されます。

```bash:左端のNICにケーブルを接続した際のlinkの状況
$ 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp1s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 00:0d:b9:xx:xx:00 brd ff:ff:ff:ff:ff:ff
3: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether 00:0d:b9:xx:xx:01 brd ff:ff:ff:ff:ff:ff
4: enp3s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 00:0d:b9:xx:xx:02 brd ff:ff:ff:ff:ff:ff
5: enp4s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 00:0d:b9:xx:xx:03 brd ff:ff:ff:ff:ff:ff
```

またシリアルコンソールのインタフェースがmicroUSBに変更されています。

回路図を確認するとこれはCP2104に接続しているため、Windows11で利用するためにはUniversalドライバーをインストールする必要がありました。

Linuxで利用する際にはカーネルに組込まれているため、自動的に/dev/ttyUSB0などにマップされます。

# Firmwareアップグレードのメリット、デメリット

安定して稼動している場合には、firmwareの更新は必ずしも必要ありません。動作に不満がなければリスクのある作業はしない事をおすすめします。

ただし、向上したiPXE・Serialコンソール機能の利用や、APU2以降が持つCore Performance Boost機能の利用、watchdog機能の利用、TPM機能の利用、あるいは、なんとなく全体的に最新のソフトウェアを使いたい、など、といった理由があればfirmwareの更新はそこまで危険な作業ではありません。

ただ念のためパッケージは全て最新にして、再起動した後、余計なサーバープロセスは停止した上で作業するといった配慮はした方が良いと思います。

また、古いfirmwareから最新にするとBIOSの設定はすべてリセットされるので、iPXEブートなどの設定は改めて有効にする必要があります。APU2で比較的新しいfirmware(v4.14.0.1以降)を使っていれば、設定を保存したままアップグレードできるオプションが参考資料に記載されています。

```bash:参考資料に記載されている設定を保存したままアップグレードするコマンドラインの例
$ sudo flashrom -w apuX_v4.14.0.2.rom -p internal --fmap -i COREBOOT
```

```--fmap -i COREBOOT```の部分が追加されたオプションですが、これはまだ試していません。
APU2では特に気にしなくても起動ディスクの順序などは保存されているようにみえますが、気のせいかもしれません。

boardmismatch=forceなどのオプションは反応をみて、適宜追加してください。