mkdosfsで遊ぶ
FAT形式のファイルシステムを作成する「mkdosfs」を使って、面白いことを見つけたので
記事にまとめます。
用意するもの
- mkdosfsコマンドが使えるLinux PC
- USBフラッシュメモリ/SDカードなど、フォーマットして構わないもの
- あるいは、QEMU(後述)
ちょっとした驚きまでの手順
USBフラッシュメモリを使用し、/dev/sdbで認識しているとします。
やることは、/dev/sdbをmkdosfsでフォーマットするだけです。
$ sudo mkdosfs -I /dev/sdb
- 何気なく指定している「-I」オプションや、「/dev/sdb1」のようにパーティション指定をしない点が重要です
ファイルは何も配置されていません。
$ sudo mount /dev/sdb /mnt/ $ ls -a /mnt/ . .. $ sudo umount /mnt/
ですが、このUSBフラッシュメモリを挿したままマシンを再起動すると・・・。
以下のメッセージが画面に表示されます!
This is not a bootable disk. Please insert a bootable floppy and
press any key to try again
何が起きていたのか?
「中身が空」を確認していたのに。。。
ならどこから、あのメッセージは出てきたのか?
(また、どこにあのメッセージは保存されているのか?)
を考えると、少し不思議です。
答えは、ファイルシステムの中身を見るとわかります。
$ hexdump -C /dev/sdb | head 00000000 eb 3c 90 6d 6b 64 6f 73 66 73 00 00 02 08 08 00 |.<.mkdosfs......| 00000010 02 00 02 00 00 f8 f8 00 3d 00 08 00 00 00 00 00 |........=.......| 00000020 00 a0 07 00 00 00 29 c0 f0 f7 b6 20 20 20 20 20 |......).... | 00000030 20 20 20 20 20 20 46 41 54 31 36 20 20 20 0e 1f | FAT16 ..| 00000040 be 5b 7c ac 22 c0 74 0b 56 b4 0e bb 07 00 cd 10 |.[|.".t.V.......| 00000050 5e eb f0 32 e4 cd 16 cd 19 eb fe 54 68 69 73 20 |^..2.......This | 00000060 69 73 20 6e 6f 74 20 61 20 62 6f 6f 74 61 62 6c |is not a bootabl| 00000070 65 20 64 69 73 6b 2e 20 20 50 6c 65 61 73 65 20 |e disk. Please | 00000080 69 6e 73 65 72 74 20 61 20 62 6f 6f 74 61 62 6c |insert a bootabl| 00000090 65 20 66 6c 6f 70 70 79 20 61 6e 64 0d 0a 70 72 |e floppy and..pr| 000000a0 65 73 73 20 61 6e 79 20 6b 65 79 20 74 6f 20 74 |ess any key to t| 000000b0 72 79 20 61 67 61 69 6e 20 2e 2e 2e 20 0d 0a 00 |ry again ... ...|
hexdumpは、引数で指定したファイルを16進や、その他の形式でダンプするコマンドです。
この場合は、USBフラッシュメモリに書かれているバイナリ列を16進(中央列)とASCII(右列)でダンプしています。
(左の列はアドレスです)
ASCIIの列を見ると、「This is not a ...」のメッセージがあり、
やはり、あのメッセージはUSBメモリに書かれていたのだとわかります。
「ファイル」としては見えないけど、mkdosfsはコッソリと、
あのメッセージをUSBフラッシュメモリに書いていたのです。
なぜ、mkdosfsはこんなことをしているのか?
PCの電源投入時、BIOSは起動デバイスとして設定されたデバイスの先頭512バイトをメモリにロードします。
この512バイトが、基本的にブートローダーのプログラムで、このブートローダーがOS起動のための処理を行います。
「先頭512バイト」は、アドレスで0x000〜0x1FFで、あのメッセージが書かれていた場所です。
mkdosfsは、フォーマットしたデバイスが誤って起動デバイスとして選択されてしまった時のために、
「『これはブート用のデバイスではないよ』というメッセージを画面表示するプログラム」
を先頭512バイトに書いていたわけです。
ちなみに、mkdosfs実行時に「-I」オプションを指定したり、パーティション指定をしなかったりしたのは、
パーティションがあると、デバイスの先頭にパーティションテーブルが配置されてしまうためです。
QEMUで試す場合
「デバイスファイル」でなくても、「通常のファイル」に対してもファイルシステムを作成することが可能です。
まず、空のファイルを用意します。(この場合は1Mバイト)
$ dd if=/dev/zero of=mkdosfs_test.img bs=1M count=1 1+0 レコード入力 1+0 レコード出力 1048576 バイト (1.0 MB) コピーされました、 0.0036791 秒、 285 MB/秒
ファイル自体が空の状態です。
$ hexdump -Cv mkdosfs_test.img | head 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
mkdosfsでファイルシステムを作成します。
$ sudo mkdosfs mkdosfs_test.img mkdosfs 3.0.13 (30 Jun 2012)
- sudoを使わず、/sbin/mkdosfsでもOKです
マウントし、何もファイルが無いことを確認します。
$ sudo mount -o loop mkdosfs_test.img /mnt/ $ ls -a /mnt/ . .. $ sudo umount /mnt/
$ qemu -fda mkdosfs_test.img
以下のメッセージが表示されると思います。
This is not a bootable disk. Please insert a bootable floppy and
press any key to try again
hexdumpで確認すると、あのメッセージが書かれていることがわかります。
$ hexdump -C mkdosfs_test.img | head -n 12 00000000 eb 3c 90 6d 6b 64 6f 73 66 73 00 00 02 04 01 00 |.<.mkdosfs......| 00000010 02 00 02 00 08 f8 02 00 20 00 40 00 00 00 00 00 |........ .@.....| 00000020 00 00 00 00 00 00 29 2f fe ee a7 20 20 20 20 20 |......)/... | 00000030 20 20 20 20 20 20 46 41 54 31 32 20 20 20 0e 1f | FAT12 ..| 00000040 be 5b 7c ac 22 c0 74 0b 56 b4 0e bb 07 00 cd 10 |.[|.".t.V.......| 00000050 5e eb f0 32 e4 cd 16 cd 19 eb fe 54 68 69 73 20 |^..2.......This | 00000060 69 73 20 6e 6f 74 20 61 20 62 6f 6f 74 61 62 6c |is not a bootabl| 00000070 65 20 64 69 73 6b 2e 20 20 50 6c 65 61 73 65 20 |e disk. Please | 00000080 69 6e 73 65 72 74 20 61 20 62 6f 6f 74 61 62 6c |insert a bootabl| 00000090 65 20 66 6c 6f 70 70 79 20 61 6e 64 0d 0a 70 72 |e floppy and..pr| 000000a0 65 73 73 20 61 6e 79 20 6b 65 79 20 74 6f 20 74 |ess any key to t| 000000b0 72 79 20 61 67 61 69 6e 20 2e 2e 2e 20 0d 0a 00 |ry again ... ...|
おわりに
面白いネタだと思って、勢いで書いた割には「当たり前」なことばかりの記事になってしまいました。
なお、今回のネタは、「QEMUで試す場合」で紹介した「通常ファイルをフォーマットする」方法で、色々なファイルシステムでフォーマットし、バイナリをダンプして眺める事を繰り返している中で見つけました。
マウントし、ファイルをいくつか配置した後、ダンプすれば、
ファイル名やファイル内容が管理されている様子を見ることができ、面白いです。
- ASCII文字のファイル名で、ASCII文字のテキストファイルを配置するとわかりやすいです
# mkdosfsが先頭512バイトに警告メッセージのプログラムを配置するネタから、
# 古いプレステ等のゲーム用CD-ROMにあった警告音声を思い出しました。
# - ゲーム用CD−ROMの警告メッセージ: 面白ゲーム変遷史 名作からクソゲーまで