「手探りでCUI OS作成に挑む」連載
この記事は「手探りでCUI OS作成に挑む」連載の一部です。
全体の目次は「手探りでCUI OS作成に挑む」連載目次を御覧下さい。## 仮想HDD作成
目的
現在CUIのOSを開発している。
ファイル読み込みを実装するためにカーネルが保存されているHDDをFATで初期化しないといけない。しかし以下の記事の用に自前でMBR、VBR、FAT表、ルートディレクトリを用意するとWindowsからファイルを開くことが出来ない。
https://qiita.com/earthen94/items/f62e74b5b774e159d4c6
自作OSなので別にWindowsから読み込めなくても実装はできるがそれでは独自仕様と変わらない。
そのためMicrosoftの仕様に準拠した形式でファイルシステムを作りたいと考えている。
今回はWindowsXP上にてFAT形式で初期化し、その構造を理解することが目的。
その後でこのHDDにカーネル等を書き込んでいく。
仮想HDDの作成
# 128MBの仮想HDD生成
dd if=/dev/zero of=virtual_disk.img bs=1M count=128
XP上でマウントさせる
qemu-system-i386 \
-m 1024 \
-hda xp.img \
-hdb virtual_disk.img \
-boot c \
-cpu host \
-smp 2 \
-net nic -net user \
-vga std \
-rtc base=localtime \
-enable-kvm \
-usbdevice tablet
パーティションの作成
FATで初期化
Eドライブの中に検証用ファイルを1つ保存する
うまく2kbと表示されている(1クラスタが2kbなのでそれ以下でも2kbはある)。
ここでXPの電源は落とします。
この仮想HDDは誤って何かを書き込んでしまわないようにどこかへ複製しておく。
MBR
mbr
test@test-ThinkPad-X280:~$ xxd -s 0 -l 512 virtual_disk.img
00000000: 33c0 8ed0 bc00 7cfb 5007 501f fcbe 1b7c 3.....|.P.P....|
00000010: bf1b 0650 57b9 e501 f3a4 cbbd be07 b104 ...PW...........
00000020: 386e 007c 0975 1383 c510 e2f4 cd18 8bf5 8n.|.u..........
00000030: 83c6 1049 7419 382c 74f6 a0b5 07b4 078b ...It.8,t.......
00000040: f0ac 3c00 74fc bb07 00b4 0ecd 10eb f288 ..<.t...........
00000050: 4e10 e846 0073 2afe 4610 807e 040b 740b N..F.s*.F..~..t.
00000060: 807e 040c 7405 a0b6 0775 d280 4602 0683 .~..t....u..F...
00000070: 4608 0683 560a 00e8 2100 7305 a0b6 07eb F...V...!.s.....
00000080: bc81 3efe 7d55 aa74 0b80 7e10 0074 c8a0 ..>.}U.t..~..t..
00000090: b707 eba9 8bfc 1e57 8bf5 cbbf 0500 8a56 .......W.......V
000000a0: 00b4 08cd 1372 238a c124 3f98 8ade 8afc .....r#..$?.....
000000b0: 43f7 e38b d186 d6b1 06d2 ee42 f7e2 3956 C..........B..9V
000000c0: 0a77 2372 0539 4608 731c b801 02bb 007c .w#r.9F.s......|
000000d0: 8b4e 028b 5600 cd13 7351 4f74 4e32 e48a .N..V...sQOtN2..
000000e0: 5600 cd13 ebe4 8a56 0060 bbaa 55b4 41cd V......V.`..U.A.
000000f0: 1372 3681 fb55 aa75 30f6 c101 742b 6160 .r6..U.u0...t+a`
00000100: 6a00 6a00 ff76 0aff 7608 6a00 6800 7c6a j.j..v..v.j.h.|j
00000110: 016a 10b4 428b f4cd 1361 6173 0e4f 740b .j..B....aas.Ot.
00000120: 32e4 8a56 00cd 13eb d661 f9c3 496e 7661 2..V.....a..Inva
00000130: 6c69 6420 7061 7274 6974 696f 6e20 7461 lid partition ta
00000140: 626c 6500 4572 726f 7220 6c6f 6164 696e ble.Error loadin
00000150: 6720 6f70 6572 6174 696e 6720 7379 7374 g operating syst
00000160: 656d 004d 6973 7369 6e67 206f 7065 7261 em.Missing opera
00000170: 7469 6e67 2073 7973 7465 6d00 0000 0000 ting system.....
00000180: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000190: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001b0: 0000 0000 002c 4463 f0e9 6a4f 0000 0001 .....,Dc..jO....
000001c0: 0100 060f 7f00 3f00 0000 b1f3 0300 0000 ......?.........
000001d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
000001f0: 0000 0000 0000 0000 0000 0000 0000 55aa ..............U.
MBR
項目 | 値 | 説明 |
---|---|---|
ステータス | 0x00 |
非アクティブ(0x80 ではないためブート不可) |
開始ヘッド | 0x01 |
開始ヘッド番号 |
開始セクター | 0x01 |
下位6ビットがセクター番号(実際の値は 1 ) |
開始シリンダ | 0x00 |
上位2ビットを開始セクターから結合 → シリンダ 0
|
パーティションタイプ | 0x06 |
FAT16(16ビットFAT、セクタ数 > 65536) |
終了ヘッド | 0x0F |
終了ヘッド番号 |
終了セクター | 0x3F |
下位6ビットがセクター番号(実際の値は 63 ) |
終了シリンダ |
0x7F + 上位2ビット |
シリンダ 0x1FF (※CHSはレガシー、実際はLBAが使用される) |
LBA開始セクタ | 0x0000003F |
63(MBRや予約セクタを考慮したオフセット) |
セクタ数 | 0x0003FDB1 |
261,553セクタ(約127.7MB) |
終了セクタ | 63 + 261,553 - 1 = 261,615 | パーティションの最後のセクター番号 |
ブート可能性 | 不可 | 非アクティブなため、このディスク単体ではOS起動不可 |
VBR
パーティションの開始セクタ63セクタから512バイト(1セクタ)分にVBRが保存されている。
mbr
test@test-ThinkPad-X280:~$ xxd -s $((512*63)) -l 512 virtual_disk.img
00007e00: eb3c 904d 5344 4f53 352e 3000 0204 0600 .<.MSDOS5.0.....
00007e10: 0200 0200 00f8 fd00 3f00 1000 3f00 0000 ........?...?...
00007e20: b1f3 0300 8000 29bb dab2 784e 4f20 4e41 ......)...xNO NA
00007e30: 4d45 2020 2020 4641 5431 3620 2020 33c9 ME FAT16 3.
00007e40: 8ed1 bcf0 7b8e d9b8 0020 8ec0 fcbd 007c ....{.... .....|
00007e50: 384e 247d 248b c199 e83c 0172 1c83 eb3a 8N$}$....<.r...:
00007e60: 66a1 1c7c 2666 3b07 268a 57fc 7506 80ca f..|&f;.&.W.u...
00007e70: 0288 5602 80c3 1073 eb33 c98a 4610 98f7 ..V....s.3..F...
00007e80: 6616 0346 1c13 561e 0346 0e13 d18b 7611 f..F..V..F....v.
00007e90: 6089 46fc 8956 feb8 2000 f7e6 8b5e 0b03 `.F..V.. ....^..
00007ea0: c348 f7f3 0146 fc11 4efe 61bf 0000 e8e6 .H...F..N.a.....
00007eb0: 0072 3926 382d 7417 60b1 0bbe a17d f3a6 .r9&8-t.`....}..
00007ec0: 6174 324e 7409 83c7 203b fb72 e6eb dca0 at2Nt... ;.r....
00007ed0: fb7d b47d 8bf0 ac98 4074 0c48 7413 b40e .}.}....@t.Ht...
00007ee0: bb07 00cd 10eb efa0 fd7d ebe6 a0fc 7deb .........}....}.
00007ef0: e1cd 16cd 1926 8b55 1a52 b001 bb00 00e8 .....&.U.R......
00007f00: 3b00 72e8 5b8a 5624 be0b 7c8b fcc7 46f0 ;.r.[.V$..|...F.
00007f10: 3d7d c746 f429 7d8c d989 4ef2 894e f6c6 =}.F.)}...N..N..
00007f20: 0696 7dcb ea03 0000 200f b6c8 668b 46f8 ..}..... ...f.F.
00007f30: 6603 461c 668b d066 c1ea 10eb 5e0f b6c8 f.F.f..f....^...
00007f40: 4a4a 8a46 0d32 e4f7 e203 46fc 1356 feeb JJ.F.2....F..V..
00007f50: 4a52 5006 536a 016a 1091 8b46 1896 9233 JRP.Sj.j...F...3
00007f60: d2f7 f691 f7f6 4287 caf7 761a 8af2 8ae8 ......B...v.....
00007f70: c0cc 020a ccb8 0102 807e 020e 7504 b442 .........~..u..B
00007f80: 8bf4 8a56 24cd 1361 6172 0b40 7501 4203 ...V$..aar.@u.B.
00007f90: 5e0b 4975 06f8 c341 bb00 0060 666a 00eb ^.Iu...A...`fj..
00007fa0: b04e 544c 4452 2020 2020 2020 0d0a 5265 .NTLDR ..Re
00007fb0: 6d6f 7665 2064 6973 6b73 206f 7220 6f74 move disks or ot
00007fc0: 6865 7220 6d65 6469 612e ff0d 0a44 6973 her media....Dis
00007fd0: 6b20 6572 726f 72ff 0d0a 5072 6573 7320 k error...Press
00007fe0: 616e 7920 6b65 7920 746f 2072 6573 7461 any key to resta
00007ff0: 7274 0d0a 0000 0000 0000 00ac cbd8 55aa rt............U.
BPBの解析
オフセット | サイズ | 値 | 説明 | 実際の値/意味 |
---|---|---|---|---|
0x00 | 3 | EB 3C 90 | ジャンプ命令 |
jmp 0x3c + nop
|
0x03 | 8 | "MSDOS5.0" | OEM名 | MS-DOS 5.0互換 |
0x0B | 2 | 00 02 | バイト/セクタ | 512バイト |
0x0D | 1 | 04 | セクタ/クラスタ | 4セクタ (2KB/クラスタ) |
0x0E | 2 | 06 00 | 予約セクタ数 | 6セクタ |
0x10 | 1 | 02 | FATの数 | 2コピー |
0x11 | 2 | 00 02 | ルートエントリ数 | 512エントリ |
0x13 | 2 | 00 00 | 総セクタ数 (16bit) | 未使用 (0) |
0x15 | 1 | F8 | メディアタイプ | 固定ディスク |
0x16 | 2 | FD 00 | セクタ/FAT | 253セクタ/FAT |
0x18 | 2 | 3F 00 | セクタ/トラック | 63セクタ/トラック |
0x1A | 2 | 10 00 | ヘッド数 | 16ヘッド |
0x1C | 4 | 3F 00 00 00 | 非表示セクタ数 | 63セクタ |
0x20 | 4 | B1 F3 03 00 | 総セクタ数 (32bit) | 259,505セクタ (~126.7MB) |
0x24 | 2 | 80 00 | ドライブ番号・予約 | 0x80 (HDD) |
0x26 | 1 | 29 | 拡張ブートシグネチャ | 拡張BIOSパラメータ使用 |
0x27 | 4 | BB DA B2 78 | ボリュームシリアル番号 | 78B2DABB (16進数) |
0x2B | 11 | "NO NAME " | ボリュームラベル | 未命名ボリューム |
0x36 | 8 | "FAT16 " | ファイルシステム名 | FAT16フォーマット |
ルートディレクトリ
開始セクタ = 予約セクタ数 + (FAT数 × セクタ/FAT) = 6 + (2 × 253) = 512
LBA位置 = パーティション開始セクタ + 開始セクタ = 63 + 512 = 575セクタ
test@test-ThinkPad-X280:~$ xxd -s $((512*575)) -l 512 virtual_disk.img
00047e00: d0c2 bcd3 beed 2020 2020 2008 0000 0000 ...... .....
00047e10: 0000 0000 0000 029a e25a 0000 0000 0000 .........Z......
00047e20: 5445 5354 594f 5520 5458 5420 0046 889a TESTYOU TXT .F..
00047e30: e25a e25a 0000 829a e25a 0200 1300 0000 .Z.Z.....Z......
00047e40: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00047e50: 0000 0000 0000 0000 0000 0000 0000 0000 ................
一つ目に登録してあるデータは何に使うものか良く分からない。
Windowsが何かの用途で生成したものか?
オフセット | バイト列 | 内容 | 説明 |
---|---|---|---|
20h | 54 45 53 54 59 4f 55 20 | TESTYOU | ファイル名(8文字) |
28h | 54 58 54 | TXT | 拡張子(3文字) |
2Bh | 20 | 属性(通常ファイル) | |
2Ch〜35h | 00 46 88 9a e2 5a e2 5a | 予約・時間情報 | |
36h〜37h | 00 00 | 開始クラスタ番号(上位2バイト) FAT16なので未使用 or 0 |
|
38h〜39h | 82 9a | 開始クラスタ番号(下位16bit) 0x9A82 |
|
3Ah〜3Dh | e2 5a 02 00 | ファイルサイズ(リトルエンディアン) 0x00025AE2 = 154,466バイト |
FAT表1
FAT1の開始LBA = パーティション開始 + 予約セクタ数
= 63 + 6
= 69 セクタ目
test@test-ThinkPad-X280:~$ xxd -s $((512*69)) -l 512 virtual_disk.img
00008a00: f8ff ffff ffff 0000 0000 0000 0000 0000 ................
00008a10: 0000 0000 0000 0000 0000 0000 0000 0000 ................
f8ff ffff
は固定。
TESUTYOU.TXTの分はその次のffff
1クラスタに満たないからルートディレクトリに記録されているファイルの開始位置クラスタだけで足り、FAT表には終端のffff
のみが記録されている。
ファイルの置かれている場所
test@test-ThinkPad-X280:~$ xxd -s $((512 * 607)) -l 512 virtual_disk.img
0004be00: 7465 7374 310d 0a74 6573 7432 0d0a 7465 test1..test2..te
0004be10: 7374 3300 0000 0000 0000 0000 0000 0000 st3.............
今後の予定
これまでは自力でMBR、VBR、FAT表及びルートディレクトリを作ろうとしていたが、WindowsXPにマウントさせた時にファイル名が表示されるのみでファイルが正常に開けなかった。
今回WindowsXP初期化したFATの構造が理解できたので、WindowsXPで初期化したHDDの中に自分の開発中のOSカーネルなどを入れていく。