MBRのおさらい
先日お亡くなりになったMacBookのHDD
データがなくなったのは仕方ないが,なんとか活用できないものか?
Intel Macは既にEFIを利用していて,パーティションテーブルにはGPTを採用している
そして,WikipediaによるとGPTはディスクの後方にもGPTヘッダーとパーティションテーブルを備えているらしい
互換性を保つためGPTではLBA0にMBRが存在するらしく,ディスク全体がひとつのパーティションであるように見えるらしいが,問題のHDDのLBA0には欠損があるようで読み取れなかった
ということで,このHDDを利用して,勉強がてらパーティション情報を復活させてみようと思う
その前に確認の意味も込めてMBRのおさらいをしてみる
実験台にされたのはUbuntu 9.04 (64bit) メインのLinuxマシン
こいつはソフトウェアRAIDを組んでるマシンだが今回は片方のディスクを対象にする
このディスクの情報は下記の通り
% sudo sfdisk -l /dev/sda ディスク /dev/sda: シリンダ数 60801、ヘッド数 255、63 セクタ/トラック ユニット = 8225280 バイトのシリンダ、1024 バイトのブロック、0 から数えます Device Boot Start End #cyls #blocks Id System /dev/sda1 * 0+ 7 8- 64228+ fd Linux raid 自動検出 /dev/sda2 8 1831 1824 14651280 fd Linux raid 自動検出 /dev/sda3 1832 56783 54952 441401940 5 拡張領域 /dev/sda4 0 - 0 0 0 空 /dev/sda5 1832+ 56540 54709- 439450011 fd Linux raid 自動検出 /dev/sda6 56541+ 56783 243- 1951866 82 Linux スワップ / Solaris
まず,MBRを取り出してやる
MBRはHDDのCHSだとC:0 H:0 S:1,LBAだと0から512バイトの領域なので
% sudo dd if=/dev/sda of=mbr bs=512 count=1
取り出したMBRをダンプしてやる
zオプションを使ってることから明らかなように作業はLinuxでやってます
$ od -tx1z -Ax mbr ・・・ 0001b0 00 00 00 00 00 00 00 00 18 cd 01 00 00 00 80 01 >................< 0001c0 01 00 fd fe 3f 07 3f 00 00 00 c9 f5 01 00 00 00 >....?.?.........< 0001d0 01 08 fd fe ff ff 08 f6 01 00 20 1f bf 01 00 fe >.......... .....< 0001e0 ff ff 05 fe ff ff 28 15 c1 01 a8 84 9e 34 00 00 >......(......4..< 0001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa >..............U.< 000200
MBRの大半はIPLで占められていて,先頭から446バイト後方にパーティションテーブルが,さらに64バイト後方に2バイトのシグネチャ (0xAA55) がある
ダンプ結果を見ると確かにシグネチャ 0xAA55が確認できる
(リトルエンディアンな点に注意)
0×0001b8-0×0001bbの4バイトには,ディスクIDも確認できる
ダンプデータから,パーティションテーブルの情報を抜き出して見る
パーティションテーブルには4つのエントリがあり,各エントリの構成は先頭から順に,次のようになっている
- ブートフラグ (8bits)
- 開始位置 (CHS) (24bits)
- パーティションタイプ (8bits)
- 終了位置 (CHS) (24bits)
- 開始位置 (LBA) (32bits)
- セクタ数 (LBA) (32bits)
また,CHS形式の値は先頭から順に,次のようになっている
- Head (8bits)
- Cylinder上位 (2bits)
- Sector (6bits)
- Cylinder下位 (8bits)
従ってパーティションの情報は次の通り
| Partition | Boot Flag | Partition Type | Start (CHS) | End (CHS) | Start (LBA) | Sector Counts |
| 1 | 80h | FDh | C:0 H:1 S:1 | C:7 H:254 S:63 | 63 | 128457 |
| 2 | 0h | FDh | C:8 H:0 S:1 | C:1023 H:254 S:63 | 128520 | 29302560 |
| 3 | 0h | 05h | C:1023 H:254 S:63 | C:1023 H:254 S:63 | 29431080 | 882803880 |
| 4 | 0h | 0h | C:0 H:0 S:0 | C:0 H:0 S:0 | 0 | 0 |
基本パーティションと拡張パーティションをあわせて3つしかないので4番目のエントリは0で埋められている
ブートフラグを見ると第1パーティションにブート可能を示す80hが格納されており,他のパーティションには0hが格納されている
BIOSによってMBRが0×7C00にロードされると,IPLはブートフラグが80hになっているパーティションを探す
古いBIOSでは,パーティションテーブルの先頭から順に1バイトずつ,DL, DH, CL, CHレジスタに格納される
つまり,DLレジスタでこの80hをドライブナンバー,DHでヘッド数,CHでシリンダ数の下位8ビット,CLの第7-8ビットでシリンダ数の上位2ビットを指定してINT 13hをコールすることで,パーティションテーブルのブートレコードが読み込まれる
拡張INT 13hでは,CHSではなくLBAを利用する
ちなみに,GRUBなどはIPLを書き換えて独自のブートプロセスをとるため,この限りではない
CHS方式では1024個のシリンダしか扱えないので,最近の大容量のHDDではCHSによるジオメトリではなくリニアなLBAを使用するが,CHSのエントリとしては1023/254/63が格納されている
sfdiskの結果をみると,H:254 S:63は固定で,シリンダの値としてディスク容量から算出された1024より大きな値が表示されている
パーティションはシリンダの境界から始めるのがルールだが,第1パーティションだけは例外でMBRの次のヘッダである C:0 H:1 S:1から始まる
LBAの開始アドレスとそのパーティションのセクタ数を足してみると,次のパーティションの開始アドレスになっており,リニアにアドレスが振られていることが分かる
パーティションタイプは,FDhがLinuxのソフトウェアRAID,05hが拡張領域.他にもNTFSなら0×07とかになる
続いて,CHSとLBAの変換方法はHDDの基本的な構造から考えれば自明
CHS->LBA
LBA = C * 1トラックのセクタ数 * ヘッド数 + H * 1トラックのセクタ数 + S – 1
= (C * ヘッド数 + H) * 1トラックのセクタ数 + S – 1
LBA->CHS
C = LBA / 1トラックのセクタ数 / ヘッド数
H = (LBA / 1トラックのセクタ数) % ヘッド数
S = LBA % 1トラックのセクタ数 + 1
計算してみると分かるが,LBAから算出した値はsfdiskの表示する1024を超えたシリンダ番号と一致する




