GPTの仕組みと操作(導入編)

はじめに

本記事はディスクのパーティション管理方式の一種であるGPTについての解説兼備忘録です。

OSの起動の仕組みを始め、段階的に解説していく予定です。また実際にパーティションをプログラムで操作する方法についても軽く解説する予定です。

よく調べたうえで記事を書いているつもりですが、内容に誤りを含む場合があります。

実際に本記事を参考にプログラムを書く際は自己責任でお願いします。

(誤りを見つけたらコメント欄で報告をお願いします。確認ができ次第、修正します。)

 

セクタとは

セクタ(Sector)とはディスクの細かい区切りのことです。大抵の記憶デバイス(以下、”ディスク”と表記)は512Bを一区切りとしてディスクを管理します。現在ではディスクの最初のセクタから最後のセクタまでに0から通し番号を振り分け、その番号で特定のセクタにアクセスするのが一般的です。*1この通し番号のことをLBA(Logical Block Addressing)と呼びます。

 

パーティションとは

パーティションとは、ディスクのデーター領域の区切りです。1つのディスクには複数のパーティションを作ることができます。似た意味の言葉にボリュームとドライブという言葉があります。ボリュームとはディスク上のデーターを格納する領域という意味です。つまりパーティションというのはディスクの区切りで、その中に存在するデーター領域をボリュームと呼びます。
本棚で例えると、本棚全体がディスクで、本棚を仕切りによって分けたときにできる区画がパーティションです。そしてその区画の中のことをボリュームと呼びます。下図でいえば青枠がパーティションで、その中の水色の領域がボリュームです。

f:id:KALMIA:20190329130335p:plainそしてドライブというのはボリュームを利用するための装置もしくはその概念です。例えばDVDにはデーターが格納されていますが、そのままでは読み込めません。なのでDVDドライブを用意してそれを経由してデーターにアクセスすると思います。またディスク上に作ったボリュームにしてもCとかDとかのドライブラベルを割り当てないとアクセスできないと思います。あの概念のこともドライブと呼びます。

 

 

 

ディスクの容量を表す単位

ディスクの容量を表す単位には10進数で計算する方式と2進数で計算する方式があります。

10進数で計算する方式は以下のように定義されます。

8bit = 1B(バイト)  1000B = 1KB(キロバイト)  1000KB = 1MB(メガバイト)  1000MB = 1GB(ギガバイト)  1000GB = 1TB(テラバイト)  1000TB = 1PB(ペタバイト)  1000PB = 1EB (エクサバイト) 1000EB = 1ZB(ゼタバイト)

割と一般的な方式ですね。1000倍ずつで単位が変化します。

 

2進数で計算する方式は以下のように定義されます。

8bit = 1B  1024B = 1KiB(キビバイト)1024KiB = 1MiB(メビバイト

1024MiB = 1GiB(ギビバイト) 1024GiB = 1TiB(テビバイト)1024TiB = 1PiB(ペビバイト)1024PiB = 1EiB(エクスビバイト)1024EiB = 1ZiB(ジビバイト)

これも見たことあると思います。1024倍、すなわち2の10乗で単位が変化します。

本記事では2進数で計算する方式を採用します。

 

ちなみに余談ですが、Windowsは単位はGB、TBであるのにもかかわらず、1024倍で単位が変化する方式を採用しています。確かに昔は1024MB = 1GBという定義と1000MB = 1GBという定義が混在していましたが、今はGB、GiBという単位に分けることによって区別しています。

「まあ名残だからいいんじゃね?」

個人的にダメです。なぜなら多くのLinux系のOSやMacOSはちゃんと定義に則って表記しているため、Windowsも守ってもらわないとユーザーのミスを誘発する原因になります。

まあ、Windowsは一般ユーザーが多いですから、定義を突然変えると混乱が起きるのも事実ですが・・・・

 

BIOSについて + OS起動の仕組み

BIOS(バイオス)とはBasic Input/Output Systemの略であり、PCを起動したら真っ先に起動するプログラムです。BIOSマザーボードのROM(Read Only Memory)に組み込まれており、PC起動直後にCPUやメモリ、HDDなどのハードウェアのエラーチェック及び初期化を行います。そしてマザーボードに接続された記憶デバイス(HDDなど)からブートローダーと呼ばれるプログラムを読み込み、それを実行します。ブートローダーはディスクのパーティション情報(パーティションテーブル)を読み込み、OSがインストールされているパーティションを把握し、そのパーティションのブートセクタと呼ばれる領域をロードします。ブートセクタにはOSを起動するためのプログラム*2が記述されています。それを実行することによってやっとOSが起動します。

 

1つのPCにOSが複数インストールされている場合はOSの選択画面が表示されると思います。あの選択画面を表示させているのもブートローダーです。

 

MBRについて + MBRパーティション管理法

さてBIOSの説明においてブートローダーを接続された記憶デバイスから読み込むという説明をしましたが、そもそもブートローダーは記憶デバイスのどこに書き込まれているのでしょうか?

GPT登場以前は、ディスクの先頭セクタ(LBA = 0)ありました。このディスクの先頭セクタのことをMBR(Master Boot Record)と呼びます。しかし最近のPCではMBRは使われなくなってきました。そして代わりに現れたのがGPTです。ですがGPTの説明の前にMBRについて説明させてください。

MBRにはブートローダーとパーティションテーブルというものが記述されています。

パーティションテーブルにはパーティションエントリと呼ばれるものが複数記述されており、パーティションエントリには、パーティションの開始位置、終了位置、パーティションの種類などが書かれています。ブートローダーはこのパーティションエントリを見てどのパーティションがOSの起動に使われるのかを判断します。

MBRの場合、パーティションテーブルに書き込めるパーティションエントリの最大数は4です。つまりMBRでフォーマットされたディスクにはパーティションを4つまでしか作れません。

ですが、あくまでも4つまでしか作れないのは普通のパーティション(プライマリーパーティション)のみです。

拡張パーティションと呼ばれるものを作り、さらにその中に論理パーティションというものを作ればさらにパーティションを作れます。

拡張パーティションとは1つのディスクにつき1つしか作れない特殊なパーティションです。拡張パーティションの先頭にはEBR(Extended Boot Record)というMBRと似た領域が存在し、MBRと同様にそこにパーティションテーブルが存在します。故に拡張パーティションというのはパーティショニングが可能なパーティションです。そして拡張パーティション内に作られるパーティションのことを論理パーティションと呼びます。

さらにややこしいことに論理パーティションもEBRを持ちます。すなわち論理パーティション内にもパーティションを作れます。このような仕組みからわかる通り、拡張パーティション内にはディスクの容量が許す限り、無限に論理パーティションを作れます。

ちなみに論理パーティションにもOSがインストールできます。(ブートローダーの種類によっては論理パーティション内のOSを認識できない場合があります。)

さてMBRパーティションを4つまでしか作れないという欠点がありましたが、拡張パーティション、論理パーティションという概念の登場により、無理矢理に克服することに成功しました。が、MBRには最大の欠点が存在します。 MBRで管理可能なディスクの最大容量は2TiBまでなのです。

 

UEFIの登場

先ほど説明したBIOSMBRは古くから存在するシステムです。現在でもディスクを購入したときにMBRでフォーマットする人が存在します。(マザボが古い場合、GPTは使えません)

ですが、BIOSMBRは古いが故に時代遅れな部分が多いです。BIOSMBRが生まれた当時は8GiBのHDDが大容量とか言われていた時代です。しかし現代ではノートPCでさえ256GBのSSDもしくはHDDが一般的です。256GBのディスクの場合、パーティションを均等に4つ作ったとしても、1つのパーティションにつき64GBも使えます・・・

それなのにMBRパーティションは最大4つまで・・・ それを解決するために拡張パーティションが現れたわけですが、2TiBの壁はMBRではどうしても超えられません・・・

となるとMBRに代わる新たなシステムが必要です。そのシステムこそがGPTと言いたいところなんですが、まだ壁があります。BIOSさんです・・・・ BIOSは基本的にMBRを前提に作られています。なのでまずはBIOSに代わるシステムが必要なのです・・・

そこで現れたのがUEFI(Unified Extensible Firmware Interface)です。*3UEFIとはOSとファームウェアの間のインターフェースの仕様です。分かりやすく言えばOSとハードの仲介役です。ちなみにUEFIが採用されているBIOSのことをUEFI BIOSと呼びますが、BIOSは略してUEFIと呼ぶことが多いです。またUEFIのことをBIOSと呼び、従来のBIOSのことを旧BIOSと呼ぶ人もいます。

UEFIについてはこの程度の説明で済ませます。詳しくはWikipediaでどうぞ。

ja.wikipedia.org

GPTの登場

GPTとはUEFIで定義されているディスクのパーティション管理に関する規格であり、MBRに代わるものとして登場しました。現在販売されているPCのマザーボードには基本的にUEFIが採用されているため、ディスクもGPTでフォーマットされています。

GPTはGUID Partition Tableの略称です。さてPartition Tableは文字通りパーティションテーブルなので意味は分かると思いますが、GUIDとは何者でしょうか?

 

GUIDとはGlobally Unique Identifieの略で日本語訳はグローバル一意識別子です。

128bitの二進数の数値であり(表記されるときは16進数です。)ファイルやディスク、データーなどを識別する時に利用されます。

乱数によりGUIDは作成可能で、それによって作られたGUIDは世界で唯一存在する識別子になります。

「え?乱数で生成するんだろ? 自分が作ったGUIDとまったく同じGUIDが世界のどこかで生まれるかもしれないじゃん・・・」

実際に計算すると確率はほぼ0%です。

実際の計算方法は鳩の巣原理*4の応用です。詳しい話は別のサイトに譲ります。

ただし乱数のシード値を固定してGUIDを生成し続けたら、高い確率で衝突します。気を付けてください。

 

さて話を戻します。このGUIDですがGPTにおいてはパーティションの識別に使用されます。1つのパーティションにはパーティションタイプGUIDとパーティションユニークGUIDが振り分けられます。パーティションタイプGUIDというのはパーティションの種類を表すGUIDです。

どのGUIDが何を表すのかはWikipediaにまとめられていますので参照してください。(下記のWikipediaの「パーティションの型を表すGUID」という項目を参照)

ja.wikipedia.orgユニークGUIDというのは文字通りユニークなGUID、すなわち乱数で生成されるそのパーティション固有のGUIDです。

 

GPTは2番目のセクタ(LBA = 1)からスタートします。*5LBA = 1にはGPTヘッダーと呼ばれるものが記述されており、LBA = 2 ~ LBA = 33にはパーティションテーブルが記述されます。MBRは1つのセクタにブートローダーとパーティションテーブルをまとめていたのに対し、GPTは32個のセクタを利用しています。これによりパーティションの最大数は128個までとなりました。また大容量のディスクにも対応し、最大約8ZiBまで利用できます。TiBに換算すると909494702‬TiBです。当分はこんな大容量のディスクは現れないと思うので十分だと思います。(技術的に可能だとしても普通は必要ない)

 

 

GPTにおけるOS起動プロセス

 GPTにはMBRでいうブートローダーが記述されていません。代わりにEFIシステムパーティションというパーティション内にあるファイルが(拡張子は".efi")担当します。つまりこのファイルに記述されたプログラムがブートローダというわけです。MBRはディスクの先頭セクタに記述されたブートローダーがOSがインストールされたパーティションを探し出し起動していたのに対し、GPTは最初にEFIシステムパーティションを参照し、あとはそこにあるプログラムに全てを委ねます。*6

このようにブートローダパーティション内のファイルとして存在するので、MBRと違ってサイズの制限がない上に、普通のファイルと同様にOSからアクセスできます。

しかもこのブートローダーはUEFIが提供するAPIC言語で簡単に記述することが可能です。*7

 

 次回に続く

とりあえずGPTについて説明する前の導入は以上です。次回はGPTディスクを実際にダンプして細かく見ていきます。

*1:一昔前はCHSという方式でディスクの特定のセクタにアクセスしていましたが、ディスクの大容量化に伴い使われなくなりました。

*2:このプログラムのこともブートローダーと呼んだりすることもあります。

*3:実際はそのちょっと前にEFIという規格が登場し、最終的にそれがUEFIに発展しました。

*4:「鳩が11羽、箱が10箱あり、その箱に鳩を詰め込むとき、詰め込み方によらず必ずどれか1箱には鳩を2羽詰め込まなければならない。」という話です。

*5:LBA = 0はMBRとの互換性維持のために残してあります。

*6:ちなみにEFIシステムパーティションを参照するプログラムそのものはマザーボードのROMに組み込まれているUEFIが担当しています。

*7:MBRの場合はアセンブリなどを用いる必要があります。