旧式マシンでもResizableBAR有効にしたい(した)話

## ⚠️注意⚠️

:::note alert
この記事の内容は **UEFI/BIOS/ファームウェアの改造** という **システム(マザーボード)を起動不能に破壊する恐れのある行為** について言及しています。
:::

:::note alert
実行になられる際は **自己責任** の下、 **用法・容量・要領を守って正しく実行し、かかる結果については全て自身が全てを負ってください** 。
:::

:::note alert
筆者は **逸般の誤家庭** でレガシーな資産を使い回して戦い続けるため保守機材がそこそこ転がっており、 **基板の一枚や二枚の損失では堪えない(震え声)バックアップ環境がある** ので実行しました。
:::

:::note alert
筆者の言う通りにしたけど **何か文鎮になったんだけど💢** とか言われても **何も出来ません。**
:::

……ふう、これだけ書いておけば大丈夫だろ(フラグ立ててくスタイル)。

## 前情報

それでは本題に入ります。
今から2年ぐらい前にひっそりと話題になった案件がありました。

https://github.com/xCuri0/ReBarUEFI

ここ5年ぐらいのシステムで有効にすることが出来る、主に **拡張カード型GPUのパフォーマンスを向上させるUEFI/BIOS/ファームウェアの機能である「ResizableBAR」** は、 **機能的にはSandyBridge(-E/EP)以降のCPUには既に実装されている** 、というものです。

:::note warn
より厳密に言うと **ResizableBARはPCI Express 3.0以降で対応の機能** ですので、PCIe 2.0までの対応であるSandyBridge(LGA1155)やマザーボード的にPCIe 2.0までの対応なハードウェアでは対応していない(はず)です。
**~~何故か動作報告あるらしいけど。~~**
:::

**ということは詰まり、NVMe非対応だがUEFIには対応しているマザーボードにNVMeドライバを組み込んでNVMe SSDからシステムをブート可能にするのと同じ要領で、モジュールを組み込むなりUEFI/BIOS/ファームウェアのフラグを立ててやるなりすれば、ResizableBARをレガシーなハードウェアでもオンに出来るんじゃね？** と考えた方がいらっしゃったようです。
~~果たしてそんなレガシーハードウェアでResizableBARを有効にする価値があるかどうかはさて置き、~~ そんな愛すべき先駆者の方が **様々な苦労の末に築き上げた** のが、上掲のGitHubページで公開されているノウハウ及びパッチファイルになります。
今回はそんな経緯のある話を実際に実施してみた、というお話です。

## 今回用意したもの

+ **CPU: Intel Xeon E5-2697 v2(2.7GHz/12コア24スレッド)**
+ **マザーボード: Jingsha X79M-S(Red/Q67)**
+ **メモリ: DDR3 Registered DIMM 32GB×4(128GB)**
+ **NVMe SSD: SUNEAST SE900NVG70(2TB)**
+ **GPU: ASRock Intel Arc A380 6GB**
+ **USBメモリ: 8GB以上のものを2本**
+ **UEFITool(Alpha版ではない)が管理者権限で動作する別のPC**
+ **Windows10 or Windows11のインストールディスク**

## 準備

では早速、**正解の作業順序に沿って** 、作業内容を追想していきます。

### UEFI Shellの起動ディスクを作る

今回~~いけにえに捧げられた~~実験に供されたのは、「**新仮想化基盤にデータが粗方移ったし、Debian12を入れ直してQEMU/KVMで仮想マシンにGPUをパススルーして運用してえなあ**」と思っておりました、通常「**旧仮想化基盤**」と呼ばれているマシンです。
**Jingsha X79M-SというmicroATXでLGA2011(v1)が乗っているマイニングマシン用中華マザー(情報過多)** が乗っているこのマシンは、その**マイニングが中国大陸で違法になり保守部品が市場に大量放出されて日本に流れてきた**というマザーボードの出自からも大体想像が付くのではないかと思いますが、**メーカー提供のUEFI/BIOSファイルがありません。**
**ネット上にはそれが本当に正規のメーカーが提供しているUEFI/BIOSファイルなのか怪しい出所のファイルしかありません。**

**大事なことなので2回書きました。~~じゃあそのマザーボードは信用に足るのかって言われるともう何も言えねえや~~**

というわけで最初に必要な作業は「**別のPCでUSBメモリをFAT(FAT32)でフォーマットして、UEFI ShellやUEFI/BIOSダンプツールを仕込む**」です。

:::note info
レシピはこうです。**※大体下掲ページの手順を意訳したものになります。**

https://chipsec.github.io/installation/USBwithUEFIShell.html

+ **USBメモリをFAT(FAT32)でフォーマット(クイックでOKです)**
+ **USBメモリに下掲のフォルダ構造を作ります**
```shell
/
┣ EFI/
┃　┃
┃　┗ BOOT/
┃
┗ chipsec/
```
+ **上記ページからDLしたShell.efiを「Bootx64.efi」にリネームします**
+ **「BOOT」フォルダに「Bootx64.efi」をコピーします**
+ **上記ページ左の「Download CHIPSEC」から最新のCHIPSEC一式のZIPファイルをダウンロードします**
+ **CHIPSEC一式を解凍したら、その中の「__install__/UEFI/chipsec_py368_uefi_x64.zip」を解凍すると出てくる2つのフォルダ(「StdLib」と「Tools」)を「EFI」フォルダ直下(「BOOT」フォルダと同じ階層)に置きます**
+ **CHIPSEC一式を解凍したものの中にある「chipsec」フォルダをUSBメモリの「chipsec」フォルダの中にコピーします**
+ **ルートフォルダ直下の方の「chipsec」フォルダに「chipsec_main.py」と「chipsec_util.py」を配置します**
:::

これで1本目のUSBメモリの準備はOKです。

### 対象のマシンからUEFI/BIOS/ファームウェアをダンプする

:::note info
+ **次に、UEFI/BIOSを抽出(ダンプ)したいマシンにUSBメモリを挿し(※あらかじめUEFI/BIOSの読み書きを制御するジャンパピンがある場合は読み書き可能に切り替えておきます)、USBメモリから起動します**
+ **以下の通りコマンドを入力していきます(最新版のCHIPSEC基準)**
```shell
Shell> mode 80 25
Shell> fs0:
FS0:\> cd chipsec
FS0:\chipsec\> Python.efi chipsecutil.py spi dmp <保存したいファイル名>
```
+ **しばらく経ってコマンドがエラー表示なく終了してShellの入力画面になったら、一旦、このPCの電源はオフにします**
:::

これで1本目の **USBメモリの「chipsec」フォルダ内に「<保存したいファイル名>」でUEFI/BIOS/ファームウェアがダンプされています。**

## UEFI/BIOS/ファームウェア改造

### UEFI/BIOS/ファームウェアを解析し、ReBarDxeドライバーモジュールを挿入する

次に、このダンプしたファイルをUEFIToolで解析にかけます。

:::note info
+ **https://github.com/LongSoft/UEFITool/releases/tag/0.28.0 から「UEFITool_0.28.0」を解析用PCにダウンロードします**
+ **ダウンロードしたファイルを解凍したら、管理者権限でUEFIToolを起動します**
+ **1本目のUSBメモリを解析用PCに接続し、UEFIToolにダンプしたファイルをドラッグ&ドロップするなどして開きます**
+ **https://github.com/xCuri0/ReBarUEFI/releases/tag/0.3 から「ReBarDxe.ffs」をダウンロードします**
+ **メニューのAction -> Searchで検索ウインドウを出し、「GUID」タブで検索ボックスには「3C1DE39F-D207-408A-AACC-731CFB7F1DD7」、ラジオボタンは「Header only」に合わせ、検索します**
+ **出てきた結果がMessagesエリアに表示されますのでダブルクリックすると、メイン画面の該当モジュールの部分を展開してくれます**
+ **該当モジュールが配置されている親モジュールの「PXE Driver」の表示の一番最後までスクロールし、最後のモジュール上で右クリックします**
+ **「Insert after...」を選択するとファイル選択ダイアログが表示されますので、先にダウンロードしておいた「ReBarDxe.ffs」を選択して開きます**
+ **「PXE Driver」の最後の行に「ReBarDxe」の表示がついたモジュールが挿入されているのを確認したら、別名でUSBメモリに保存します**
:::

:::note warn
**UEFIToolの画面は場合によってはこの後の手順で再利用することがありますのでそのまま起動しておいてください**
:::

### UEFIPatchを適用する(※不要な場合もあります)

次に、UEFIPatchを適用します。

:::note info
+ **https://github.com/LongSoft/UEFITool/releases/tag/0.28.0 から「UEFIPatch」をダウンロードします**
+ **https://github.com/xCuri0/ReBarUEFI/blob/master/UEFIPatch/patches.txt から「patches.txt」をダウンロードします**
+ **UEFIPatchを解凍し、UEFIPatchの実行ファイルと同じフォルダの中に、「前の手順で作成した改造UEFI/BIOS/ファームウェアのファイル」と「patches.txt」をコピーします**
+ **「確実にX79 Expressチップセットが使われているマザーボード」の場合は「pathces.txt」の最後のコメントアウトされている行のコメントアウトを解除します**
:::

:::note warn
**⚠️注意⚠️**
この行は**マルチCPUシステムとの互換性がない可能性があるためコメント化されています(=デュアルCPUマザーボードでは不具合を生じる可能性があります)**
また、**一部のAliExpressマザーボード等の既に4G Decodeがオンになっているマザーボードでは、このパッチ作業は行わないでください**
:::

:::note info
+ **管理者権限でUEFIPatchを実行します**
```shell
sudoer@UEFImodPC:~/UEFIPatch$ ./UEFIPatch ./<Patchを適用したいUEFI/BIOS/ファームウェアファイル>
```
:::

:::note warn
**⚠️注意(今回の私の環境では当て嵌まらなかったので割愛)⚠️**
+ **Intel 7 Seriesチップセットでは、チップセットオンボードのUSB3ポートを機能させるためには追加で「IvyUSB3.txt」を使ってパッチを当てる必要があります**
+ **Intel 8 Seriesチップセットでは、チップセットオンボードのUSB3ポートを機能させるためには追加で「HswUSB3.txt」を使ってパッチを当てる必要があります**
+ **Intel 9 Seriesチップセットでは、チップセットオンボードのUSB3ポートを機能させるためには追加で「BdwUSB3.txt」を使ってパッチを当てる必要があります**
:::

:::note info
+ **パッチが適用された場合は拡張子が「.patched」となったUEFI/BIOS/ファームウェアファイルが生成されます。この場合、「主としてASUS製マザーボードに影響する」ファームウェアの損傷が起きている場合があります(※Jingsha X79M-S(Red/Q67)ではPatchは適用されなかったのでこの記事では割愛します)**
+ **「No patches can be applied to input file」が表示され何も新しいファイルが生成されなかった場合はそのままのUEFI/BIOS/ファームウェアファイルを次の手順で使用することができます**
:::

### DSDTパッチの適用(この記事では割愛)

:::note warn
**⚠️注意⚠️**
**DSDT パッチは、次のマザーボードでのみ必要です**
+ **UEFIPatchを適用したSandy/Ivy Bridgeマザーボード**
+ **ASRockのHaswell/Broadwell/Skylake/Kabylake(HEDT(X99/LGA2011およびX299/LGA2066)を除く)用マザーボード製品**
※4G Docoding用の壊れたDSDTが搭載されていることが多いため
+ **UEFIPatchで「Extend MMIOH limit to fix Above 4G Decoding」が適用された「X79システム」**
※隠し設定でも「Above 4G Decoding」ができないシステムでは、この修正は**Linuxでのみ機能**します(少なくとも GPU の場合)
:::

## UEFI/BIOS/ファームウェアをマザーボードに書き込む

### 修正されたUEFI/BIOS/ファームウェアをマザーボードに書き込む

:::note alert
**⚠️注意⚠️**
+ **ここから先の作業はマザーボード等を起動不能になさしめる可能性があります**
+ **完全な自己責任で、失敗しても泣かない気概が持てる方のみ実行してください**
:::

:::note warn
+ **お使いのシステムに対応したAMI Firmware Update Utilityを探してきてダウンロード、解凍します**
+ **ファームウェアをダンプするのに使ったUSBメモリの「Tools」フォルダに、「AfuEfix64.efi」と改造したファームウェアファイルを配置します**
+ **(ここだけリンクを張ってなかったり、「探してきて」と表現しているのは「お察しください」)**
**(AMIファームウェアはチップセットによって使えるツールのバージョンが異なりますのでご注意ください)**
:::

:::note info
+ **https://github.com/datasone/grub-mod-setup_var/releases/ から「modGRUBShell.efi」をダウンロードして、ファームウェアをダンプするのに使ったUSBメモリの「Tools」フォルダに配置します(後の手順で使います)**
+ **https://github.com/xCuri0/ReBarUEFI/releases から最新の「ReBarState.exe」をダウンロードしてきて、USBメモリの「Tools」フォルダに配置します(後の手順で使います)**
+ **USBメモリを取り外し、UEFI/BIOS/ファームウェアを書き換えるPCに挿します**
:::

:::note alert
**⚠️注意⚠️**
+ **ここから先の作業はマザーボード等を起動不能になさしめる可能性があります**
+ **完全な自己責任で、失敗しても泣かない気概が持てる方のみ実行してください**

**⚠️注意⚠️**

+ **UEFI/BIOS/ファームウェアを書き換えるPCを起動してUEFIメニューに入ります**
+ **「CSM」を「オフ(Disable)」にします**
+ **「Secure Boot(Fast Boot)」を「オフ(Disable)」にします**
+ **設定を保存して再起動し、USBメモリのShellを起動します**
+ **AfuEfix64.efiに適切なオプションと改造済みUEFI/BIOS/ファームウェアファイルを指定して実行し、ファームウェアを書き換えます**
+ **無事にフラッシュが完了したら「reboot」と打ち込んで再起動します**
+ **無事に起動してきたら、UEFI/BIOS/ファームウェアメニューに入り、設定が初期値に戻されている場合がありますので適宜設定します**
+ **設定を保存して再起動し、再びUSBメモリのShellを起動します**
:::

### 「Above 4G Decoding」が隠し設定かつDisableになっているので強制的にEnableにする

:::note info
+ **UEFIToolが起動しているPCの画面に戻り、Action -> Search -> Textタブを開き、「Unicord」にチェックを入れて、「4G Decod」「Above 4G」「MMIO」のいずれかで該当する項目がないか検索します**
+ **検索で見つかったセクションの本文を「Extract body...」で適当なフォルダに出力します**
+ **https://github.com/LongSoft/IFRExtractor-RS/releases/ からIRFExtractor-RSをダウンロードして解凍します**
+ **IRFExtractor-RSと同じフォルダに「検索で見つかったセクションの本文」のファイルをコピーします**
+ **IRFExtractor-RSを管理者権限で次のように実行します**
```shell
sudoer@UEFImodPC:~/IRFExtractor-RS$ ./IRFExtractor-RS ./<検索で見つかったセクションの本文>
```
+ **「IRFExtractor-RS」のフォルダ内にtxtファイルが生成されているはずですので、テキストエディタ等でそれを開き、中身に「4G Decod」または「Above 4G」のどちらかが含まれている箇所を探します**
```text
Form FormId: 0x401, Title: ""
	OneOf Prompt: "Above 4G Decoding", Help: "Enables or Disables 64bit capable Devices to be Decoded in Above 4G Address Space (Only if System Supports 64 bit PCI Decoding).", QuestionFlags: 0x10, QuestionId: 0x5, VarStoreId: 0x1, VarOffset: 0x1, Flags: 0x10, Size: 8, Min: 0x0, Max: 0x0, Step: 0x0
		OneOfOption Option: "Disabled" Value: 0, Default, MfgDefault
		OneOfOption Option: "Enabled" Value: 1
	End 
```
+ **「VarOffset(または「VarStoreInfo」「VarName」):」、「Size:」、「OneOfOption Option: "Enabled" Value:」に振られている値を控えます**
+ **USBメモリから「modGRUBShell.efi」を起動します**
+ **「setup_var_cv (VarOffsetの値) (Sizeの値) (Valueの値)」を実行します**
**以下は「Jingsha X79M-S(Red/Q67)」の場合です**
```shell
setup_var_cv 0x1 8 0x1
```
+ **おそらく「GUID is mismatch 云々」というエラーが表示されますが、ここで設定する値は安全なものですので問題ありません**
**~~※ここで設定した値は「最悪CMOSクリアすれば綺麗に元通りになる」ので、再起動後画面が映らなくなっても焦らず慌てず状況を確認しましょう~~**
+ **このマシンにインストールされているWindowsがある場合はそのWindowsを起動します**
**新規インストールする場合はもう1本のUSBにWindows10/11のインストールメディアを書き込んで、クリーンインストールします**
+ **適切な最新のグラフィックドライバを導入し、再起動します(Intel Arcシリーズの場合)**
+ **再起動後、グラフィックドライバが「ResizableBARが無効」な旨のダイアログを出してきますので、「管理者権限で」「PowerShellを起動して」「1本目のUSBメモリの「Tools」フォルダに移動して」「ReBarState.exe」を実行します**
+ **ダイアログでBARサイズを幾つにするか訊ねてきますので、適切な値(手元の環境では最大の「32」を設定しても適切な値にダウンサイズされました)を設定し、「Successfully」の表示が出たのを確認してから再起動します**
:::

### 設定が反映されていることを確認する

:::note info
+ **再起動後、グラフィックドライバが「ResizableBARが無効な旨のダイアログを表示せず」、「GPU-Z」などで「ResizableBAR」の項目が「Enabled(またはYes)」になっていることを確認します**
![47D860D6-51E9-4C15-9E72-A1E90E7B96F4_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1861875/9289f055-c3cf-8721-49be-95266e5c0e55.jpeg)
![2C540622-C86A-40D9-B7D6-FA5C3D6C417B_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1861875/7480f7ee-683c-a93f-2cc7-ce4b5006c0d0.jpeg)

+ **なお、本記事の設定の特性上、バッテリーが放電するなどしてCMOSクリアが発生するとResizableBARは無効になります**
:::

## 感想戦

**~~ぶっちゃけResizableBARを有効化したところで手持ちの時間と気力と体力が尽きたのでまだ細々したベンチマーク回せてませんというか、実はWindows消してDebian12入れてその上にQEMU/KVM載せ直してWindows11のインスタンス載せ直さなきゃなんだけど全然パーツも時間もお金も足りてません(世知辛い)~~**

### リファレンスは飽く迄もリファレンス
:::note info
+ **リファレンスでは「setup_var_cv」ではなく「setup_var」か「setup_var_3」を使うように指定されていたが、色々試した結果として「setup_var_cv」で漸くResizableBARが有効になりました**
+ **「リファレンスは飽く迄もリファレンス」で、「細かい所で差異は生じるので如何にそれをこちら側で吸収して実際の正しいやり方を導き出して実践するか」が技術力って感じがしました(小並感)**
:::

### 動作例の中に自分と同じJingsha X79M-Sがあったけれど……
:::note warn
+ **動作例の中に丁度Jingsha X79M-S(1.0)があったのでイケると思ってこの作業に踏み切ったんですが、後々スレッドをよく読んだら「X79M-S(1.0)には赤と緑がある」し「スレッド内で成功したのは恐らくX79M-S(Green)ぽい」し(だから単純に同じ手順でイケるとは限らないし実際行かなかった)し「X79M-Sって型番の割にはQ67が載ってたりする」し、「ロットによってスロットの色違うけど仕様上差異はないよ！」って書いてあったけど「えーホンマにィ？？？？」って感じでした**
:::

### 少なくとも3時間しか眠れなかった腹いせにぶっ通してやる作業ではない
:::note alert
+ **それは本当にそう**
:::