11月
02
2009

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を超えたシリンダ番号と一致する

Written by p0n in: PC | タグ: ,

コメントはまだありません »

RSS feed for comments on this post. TrackBack URL

コメントをどうぞ

TheBuckmaker WordPress Themes Webhosting, MP3, AAC & Co