ちょっと早い夏休みだ自由研究をしよう(4日目)
TL;DR
- MBR から 基本パーティション or 拡張パーティションが合計4つ管理できる。
- 拡張パーティションの第1エントリーは論理パーティション、第2エントリーはリンク(PBR)。
- リンク(PBR)の、第1エントリーは論理パーティション、第2エントリーはリンク(PBR)。
- リンク(PBR)のオフセット計算は、どうやら拡張パーティション起点のよう。前のリンク(PBR)ではなさそう。
※用語がよく分からない。
はじめに
「ディスクの先頭には、Master Boot Record、MBRがあって、基本パーティションや拡張パーティションが管理されている。拡張パーティションの中にいくつか論理パーティションを確保できる」というのはよく見知った話である。
しかし、ここでふと気が付いてしまった。
「じゃあ、論理パーティションって、どうやって管理しているのか、説明できる?
そこで、今回はこのあたりの知識を再度確認してみる。
その前に…
実は、このMaster Boot Record管理には、色々な亜流がある。
今回はMS-DOS base、という前提で説明する。
micro SDカードをこんな感じにpartition分割してみた。
ベースはRaspberry piのディスクイメージ。これに最終パーティションを分割し、拡張パーティションを作ってみた。
fdiskの結果
Command (m for help): p
Disk /dev/mmcblk0: 59.5 GiB, 63864569856 bytes, 124735488 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xDEADBEEF
Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 8192 532479 524288 256M c W95 FAT32 (LBA)
/dev/mmcblk0p2 532480 93487103 92954624 44.3G 83 Linux
/dev/mmcblk0p3 93487104 124735487 31248384 14.9G 5 Extended
/dev/mmcblk0p5 93491200 101302271 7811072 3.7G 83 Linux
/dev/mmcblk0p6 101304320 109113343 7809024 3.7G 83 Linux
/dev/mmcblk0p7 109115392 124735487 15620096 7.5G 82 Linux swap / Solaris
MBR:Master boot recordと、基本パーティション
ディスク先頭は… (先頭446byteは読み飛ばして、16*4 + 2 )
root@raspberrypi:/home/pi# hexdump /dev/mmcblk0 -C -s 446 -n 66
000001be 00 00 01 40 0c 03 e0 ff 00 20 00 00 00 00 08 00 |...@..... ......|
000001ce 00 03 e0 ff 83 3f e0 ff 00 20 08 00 00 60 8a 05 |.....?... ...`..|
000001de 00 3f e0 ff 05 3f e0 ff 00 80 92 05 00 d0 dc 01 |.?...?..........|
000001ee 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001fe 55 aa |U.|
00000200
mmcblk0p1の情報は以下となる。
000001be 00 00 01 40 0c 03 e0 ff 00 20 00 00 00 00 08 00 |...@..... ......|
ID | parameter |
---|---|
state_of_physical_drive | 0x00 |
chs_first_absolute_address | { 00,01,40 } |
partition_type | 0c |
chs_last_absolute_address | { 03 e0 ff } |
first_address | { 00 20 00 00 } = 0x0000_2000 |
number_of_sectors | { 00 00 08 00 } = 0x0008_0000 = 524,288 |
先ほどの、fdiskの結果と並べてみる。
/dev/mmcblk0p1 8192 532479 524288 256M c W95 FAT32 (LBA)
開始アドレス = 8192 = 0x2000
サイズ数 = 524288 sector = 0x8_0000
W95FAT32 -> partition type = 0x0c
ここで、「あれ?chs_first_absolute_address とか、chs_last_absolute_address とかは?」と気になった人もいるかもしれない。linux kernelの、msdos_partition()ではCHS属性は一切使ってない。よって、気にすることはない(ものすごい雑な対応ですが)。
拡張パーティションと論理パーティション
拡張パーティションの中身を見てみる。
/dev/mmcblk0p3 93487104 124735487 31248384 14.9G 5 Extended
ということなので、94387104セクタ目から1sector。
root@raspberrypi:/home/pi/work# dd if=/dev/mmcblk0 of=tmp.dat skip=93487104 bs=512 count=1
1+0 records in
1+0 records out
512 bytes copied, 0.00840728 s, 60.9 kB/s
root@raspberrypi:/home/pi/work# hexdump -C tmp.dat
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3f |...............?|
000001c0 e0 ff 83 3f e0 ff 00 10 00 00 00 30 77 00 00 3f |...?.......0w..?|
000001d0 e0 ff 05 3f e0 ff 00 40 77 00 00 30 77 00 00 00 |...?...@w..0w...|
000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
00000200
root@raspberrypi:/home/pi/work# hexdump -s 446 -C tmp.dat
000001be 00 3f e0 ff 83 3f e0 ff 00 10 00 00 00 30 77 00 |.?...?.......0w.|
000001ce 00 3f e0 ff 05 3f e0 ff 00 40 77 00 00 30 77 00 |.?...?...@w..0w.|
000001de 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000001fe 55 aa |U.|
00000200
予想通り、第1エントリーと第2エントリーがある。第3、第4は全ゼロなので無効。
第1エントリー(実体部)
start offset = 0x0000_1000
。これに拡張パーティションの93487104
を加算すると、93491200
となる。これが論理パーティションmmcblk0p5
を管理するセクタ情報となる。
/dev/mmcblk0p5 93491200 101302271 7811072 3.7G 83 Linux
93491200
セクタ目の中身を確認すると… 空。まあ、初期化していませんからね…。
root@raspberrypi:/home/pi/work# dd if=/dev/mmcblk0 of=tmp.dat skip=93491200 bs=512 count=1
1+0 records in
1+0 records out
512 bytes copied, 0.00754861 s, 67.8 kB/s
root@raspberrypi:/home/pi/work# hexdump -s 446 -C tmp.dat
000001be 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000200
root@raspberrypi:/home/pi/work# hexdump -C tmp.dat
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000200
第2エントリー(リンク部)
start_offset = "00 40 77 00=
0x00774000` = 7,815,168。
これに拡張パーティションの93487104
を加算すると、101302272 = 0x609_C000
になる。これは、さっきのp5のちょうど真後ろ。
ここで、次のリンク(PBR)が管理されている。
root@raspberrypi:/home/pi/work# dd if=/dev/mmcblk0 of=tmp.dat skip=101302272 bs=512 count=1
1+0 records in
1+0 records out
512 bytes copied, 0.00807268 s, 63.4 kB/s
root@raspberrypi:/home/pi/work# hexdump -s446 -C tmp.dat
000001be 00 3f e0 ff 83 3f e0 ff 00 08 00 00 00 28 77 00 |.?...?.......(w.|
000001ce 00 3f e0 ff 05 3f e0 ff 00 70 ee 00 00 60 ee 00 |.?...?...p...`..|
000001de 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000001fe 55 aa |U.|
00000200
まとめ
同様に計算をしていくと以下のような構造であることがわかる。
まとめると、こういうことが分かる。
- MBR から 基本パーティション or 拡張パーティションが合計4つ管理できる。
- 拡張パーティションの第1エントリーは論理パーティション、第2エントリーはリンク(PBR)。
- リンク(PBR)の、第1エントリーは論理パーティション、第2エントリーはリンク(PBR)。
- リンク(PBR)のオフセット計算は、どうやら拡張パーティション起点のよう。前のリンク(PBR)ではなさそう。
以上になります。