MBR、GPT、UEFI、GRUB2、パーティションの理解を深める

#はじめに
Windowsをとある理由で再インストールしました
とある理由とは、WSL2を業務で使いたかったので、InsiderPreview（ベータ版）のWindowsを使ってたのですが
もう安定板でWSL2が使えるようになったため、安定板に戻したかった

そして、何年も前からLinuxをVMやWSL、Dockerで使えるようになったためLinuxとのマルチブートを行わなくなったため
UEFIが出てきた頃からマルチブート環境を作らなくなったため
知識をアップデートします！

# やっちまった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/17d414cb-ad48-7ace-f7cc-65e65db980ca.png)

旧OSでは、CドライブにNVMe SSD 1TBを使い、補助として4TBのHDDを使っていました
今回、速いNVMe 2TBを購入したのでそちらにWindowsをインストールしたのですが
旧SSDも刺していたため、旧SSDのUEIFと回復パーティションを使われてしまいました・・・
Windows再インストール あるある話・・
なので、新SSDだけでブート出来るように、UEFIのお勉強です


# POST 
Power On Self Test
PC起動時にBIOSあるいはUEFIが最初に行うセルフテスト
BIOSのエラー、システムメモリ、I/O等のテストを行う

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/74cf52c5-4cae-25cf-6999-384873a28217.png)
(Intelより)

# BIOS(レガシー）
Basic Input/Output System
古くからある、PC起動時にマザーボードが実行するプログラム
電源投入時にハードウェアを初期化し、ディスクからブートを行う
MBR方式のブートにしか対応していない
セキュアブート等が使えない
またMBRの制限で、2TB以上のディスク、4つ以上のパーティションに対応していない

# UEFI
Unified Extensible Firmware Interface
EFIという規格を元に制定された標準規格（インテル）
BIOSを置き換える新しい規格
UEFI BIOSやBIOSと呼ばれる事もあるが、ここでは旧来のレガシーをBIOSと呼び、UEFIと区別する
主に64ビットOSを対象にしており、OSの対応も必須である
GPT方式という新しいブート方式を採用し
128パーティション、8ゼビバイト(キロ、メガ、ギガ、テラ、ペタ、エクサの次)という大容量ディスクまで対応可能
一応従来のMBRからのブートも対応している（もちろんその場合はMBRの制限がある）
BIOSよりも速いブートが可能で、セキュアブートも対応している
また、複数のアーキテクチャ、ドライバ等に対応しており
簡単なファイルシステムの読み書き、ネットワーク、シェルなどが使える
OS起動後も、ブート時に読み込まれたドライバ等を使うことができる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/d083a115-b6ae-9218-9160-182893ba227e.png)
(Intelより)

## CSM
Compatibility Supported Module
UEFIを実装するマザーボードではレガシーBIOSは入っていない（Dual BIOSはどうなんだろう？）
そのため、レガシーでブートするには、CSMを使いエミュレートする必要がある
もちろん起動も遅くなるので、レガシーを使わないのであれば常時無効にすべきだ

## CHS、LBA
### CHS（Cylinder Head Sector）
ディスクの物理的なアドレスを指す
元々のディスク（フロッピーディスク、ハードディスク）では、シリンダ、ヘッダ、セクタで表されていた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/54a05b98-52cc-df70-31f5-76d36995874b.png)

ディスクは通常複数のプラッターが存在する
そこに中心から円を描くようにトラックが複数作られ
そのトラック内に、一定のサイズでセクタが作られる
この、プラッター、トラック、セクタの番号でディスクの物理アドレスを示すのがCHS方式である

ただしこのCHS方式にはいろいろな問題があった。
元々はセクタはすべて512バイトの大きさであるが、プラッターの中心部は短く、外周は長い
そのため、外側のトラックは無駄が多くなる
その解決法として

- 内側と外側のトラックで分割セクター数を変える
- 内側と外側のトラックで、セクターのデータサイズを変える

という方法が考えられたが、いろいろな理由から実現が難しかった
さらに、レジスタの制限から、シリンダー数は1024、ヘッドは16、セクタ数は64の制限があり
（IDEとBIOSで上限が異なるため、少ない方のアドレスまでしか使えない）
それらをフルに使っても、1セクタ512バイトだと528MBの制限があった
また、ディスクにより、シリンダー数も違えば、トラック数も違うため、それらをフルに使うことは出来ない

### LBA（Logical Block Addressing）
上記のようにディスクのアドレスを物理アドレスで示す事は不便であるため
セクタに対して0から順にシリアル番号を付ける事にした
結果的に、USBメモリ、SSD等のディスクを伴わないディスク（謎表現）にも最適になった

最初のLBAはアドレス長が28ビットだったため、137GBの壁があった
後にLBAを48ビットに拡張し（Large LBAまたはBigDriveと呼ばれる）144ペタバイトまで認識可能になった
さらにセクタサイズを4KiBに拡張するBigSector等もある

容量の壁に関しては、BIOS、IDEコントローラー、OS、フォーマット形式など様々な原因があったので
それらは下記などを見てください
https://ja.wikipedia.org/wiki/%E5%AE%B9%E9%87%8F%E3%81%AE%E5%A3%81



## セキュアブート
デジタル署名されたパーティションからしかブート出来ない仕組み
例えば、USBやCDからブートさせない、パーティション作ってOSインストールしてもブートさせない
おそらく、USB等からPCを起動してデータを盗んだり、悪事を防ぐための機能だと思われる
レガシーBIOSには存在しない機能なので、これを使うにはCSMを無効にしておく必要がある

# MBR
MasterBootRecord
昔からあるディスクのブート領域。UEFIに対してBIOSと表現される。
ディスクの先頭セクタ(512バイト) に置かれる
リアルモード(16ビットモード)で実行され、当然512バイトではOSのブートに足りないため、多段にブートを行う（ブートストラップ）
UEFI非対応のハードウェア、OSの場合はMBRを使う必要がある

- IPL(ブートストラップローダ、ブート用のプログラム)
- パーティションテーブル
- ブートシグネチュア

が入っている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/9dd1814c-b884-0d4d-ea4c-541abc7e7311.png)
(イメージはWikipediaより)

パーティションテーブルは16バイトx4エントリーのテーブルになっているため
パーティション（プライマリパーティション）は1つのディスクに4つまでしか作れない
また16ビットで表せられるアドレスは、最近では2TBまでとなっている


上記より、MBRの制限として下記の制限がうまれる

- ブートパーティションは4つまで
- ディスク容量は2TBまで

プライマリパーティション（BOOT時に見える起動パーティション）は4個しかないが
拡張パーティション＆論理パーティションを作ることで、データ用のパーティションは複数作ることが可能

# GPT
GUID Partition Table
MBRに代わる新しいブート方式
EFI標準規格の一部で、MBR(0セクタ目)の次、1セクタ目から保存される
またバックアップとしてディスクの最後にも保存される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/67b02162-cf39-e291-914b-6a56ef20ee68.png)
（Wikipediaより）

MBRが起動プログラム＋パーティションテーブルなのに対し、テーブルのみである
最初のセクタ（LBA0）はMBRのための予約（Protective MBRと言われている）
LBA1にはGPTテーブルのサイズ等の情報が入っている(GPT Header)
LBA2以降はパーティション情報が入っており、128パーティションを起動することが可能（可変）
また、ディスクサイズも 8ゼビバイトまで対応可能である

GPT Headerには、GPTバージョン、ヘッダサイズ、LBAサイズ、ディスクサイズ（LBA）、ディスクのGUID、CRCなどが入っている

GPTのパーティション情報は
パーティションタイプGUID（UEFIシステム、Windowsシステム、Linuxシステム・・・等の情報）
パーティションのGUID（ディスク内 UNIQUE）
パーティションの開始位置＆終了位置
アトリビュート（マウントするかなど）
パーティション名

のデータが入ってる

GPTは下記に詳しく解析がのってた
http://www.invoke-ir.com/2015/06/ontheforensictrail-part3.html

# ESP
EFI System Partition
GPTによりEFIシステムパーティションと指定されたパーティションで、ディスク上に１つしか存在できない
64ビットモード（32ビットモード）で起動する
FATでフォーマットされており、指定されたフォルダにOSの起動ファイルを置くことでブートを行う
例：\EFI\Microsoft\Boot\bootmgfw.efi
手持ちのディスクでは100MBとか200MBとかいろいろなサイズのものがある
マルチブート等を行う場合はパーティションを大きめに取るのがよい

# NVRAM
マザーボード上の保存領域がある
ブートオプションなどを記録しておく

## BCD
Boot Configuration Data
Windowsの場合、ESP内の下記に置かれる
\EFI\Microsoft\Boot\BCD
NVRAMの値をキャッシュしている

# GRUB2
GRand Unified Bootloader 2
ブートローダ
OSを1つしか入れない場合には不要だが、複数のOSをインストールし選んで起動する場合に便利
過去にはLILO（LInux LOader）、GRUB等があったが
最近はUEFIに対応している GRUB2あるいはeLILOが使われる
ESP領域にインストールを行い、起動時にブートメニューを表示する


# FAST BOOT（UEFI）、高速スタートアップ（Windows）
UEFI、Windowsでのブート時間の短縮
主にデバイスのテストやディスクの確認作業を省略する
デバイス構成に変更がなければキャッシュ内容でブートすればよい
ただし、デバイス構成に変更があった際、OSのバージョンアップの際は
これらを無効にしなければ起動に失敗したりするので
何か変更を行った際は必ず無効にして起動しよう

# Windows10のパーティション
下記の記事参照
https://www.atmarkit.co.jp/ait/articles/1810/11/news013.html

Windowsの起動ディスクでは最低でも下記のパーティションが必要
EFIシステム： 100MB以上。UEFIでのブートに必須
MSR: 16MB。Microsoftの予約
回復パーティション：サイズはOSバージョンで異なる。Windowsを初期化するのに必要
Windowsパーティション：ここにOSが入る

Windows10 Ver1709以前ではそのパーティションが下記の順番であった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/d67a2361-910d-5140-ac9d-565e7b5d6737.png)

回復パーティションが先頭に配置されている
しかし、問題が発生した
OSのバージョンが上がるにつれ、回復パーティションの中身が増えていき、インストール時のパーティションサイズを超えてしまう
回復パーティションの前後に空き領域がないため、空き領域を作って（たとえばWindowsパーティションの後ろを空けて）そこに新たなサイズの回復パーティションを作り、以前の回復パーティションは空きになってしまう
回復パーティションの飛び地問題が発生

そういった理由から、最近のWindowsでは下記の構成、Windowsパーティションのすぐ後ろに回復パーティションを配置し
回復パーティションが足らなくなった際に、Windowsパーティションの後ろを切って拡張できるようになっている

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/a6f7003f-e96a-55b7-ce9b-449276529aad.png)

もし新たにWindowsをインストールする事があれば、このパーティションを参考にすると、無駄がなくてよいでしょう。

# 結論
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/7c4df034-62eb-24fd-6178-bd65a851fed4.png)

こんな感じでパーティションを分けた・・・
本当はUEFIを余裕もって200MBを先頭に置いて回復パーティションを後ろにと思ったけど
OSパーティションを動かすにはイメージバックアップしてコピーしなおす必要があり
いいソフトが見つからなかったため、妥協した


# 謝辞
本当は、Windows10の最低限設定のイメージを取り（必要ソフトの設定等を行ったもの）
いつでもOSリセットできるようにしたり
UEFIの独自言語でサンプルプログラムを書いたり
GRUB2の中身を解読して、UEFIのブートローダーを説明したり
ブートローダーを作ったりと計画はあったんだが
モチベーションが続かず中途半端に終わってしまったことを
お詫びいたします