0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FAT16の構造研究1ブートセクタ

0
Posted at

初めに

FAT16形式で初期化したOSの入っていないディスクから起動しようとすると表示される文言について調べます。

FAT16ディスクを生成

仮想ディスク生成

dd if=/dev/zero of=fat16.img bs=1M count=10
sudo mkfs.vfat -F 16 fat16.img
sudo mount -o loop,uid=$(id -u),gid=$(id -g) fat16.img /mnt

ファイル書き込み(今回の実験には関係無い)

echo "Hello FAT16" | sudo tee /mnt/test.txt
cat /mnt/test.txt

sudo mkdir /mnt/dir1
sudo mkdir /mnt/dir2
sudo umount /mnt

ls -la /mnt/

FAT16ディスクのブートセクタを解析

バイナリで初めの512bバイトを覗くと英語で起動できるディスクではないという旨の文言が見える。
これがこのFAT16のディスクからOSを起動しようとした時に画面上に表示される文言である。
画面に表示される以上、この文言を表示する為の命令もどこかにあるはずなので今回はその命令を探してみる。
※起動したばかりのx86のCPUはまだ16bitモードで動いているので、以下全て16bitだと仮定して逆アセンブルしていく。

test@test-fujitsu:~/kaihatsu$ xxd fat16.img | head -40
00000000: eb3c 906d 6b66 732e 6661 7400 0204 0400  .<.mkfs.fat.....
00000010: 0200 0200 50f8 1400 2000 0200 0000 0000  ....P... .......
00000020: 0000 0000 8001 2927 e86c 3d4e 4f20 4e41  ......)'.l=NO NA
00000030: 4d45 2020 2020 4641 5431 3620 2020 0e1f  ME    FAT16   ..
00000040: be5b 7cac 22c0 740b 56b4 0ebb 0700 cd10  .[|.".t.V.......
00000050: 5eeb f032 e4cd 16cd 19eb fe54 6869 7320  ^..2.......This 
00000060: 6973 206e 6f74 2061 2062 6f6f 7461 626c  is not a bootabl
00000070: 6520 6469 736b 2e20 2050 6c65 6173 6520  e disk.  Please 
00000080: 696e 7365 7274 2061 2062 6f6f 7461 626c  insert a bootabl
00000090: 6520 666c 6f70 7079 2061 6e64 0d0a 7072  e floppy and..pr
000000a0: 6573 7320 616e 7920 6b65 7920 746f 2074  ess any key to t
000000b0: 7279 2061 6761 696e 202e 2e2e 200d 0a00  ry again ... ...
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000100: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000110: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000120: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000130: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000140: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000150: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000160: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000170: 0000 0000 0000 0000 0000 0000 0000 0000  ................
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 0000 0000 0000 0000 0000 0000  ................
000001c0: 0000 0000 0000 0000 0000 0000 0000 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.

...(省略)...

逆アセンブルすると一番上にjmp 0x7c3eという命令が見える。

test@test-fujitsu:~/kaihatsu$ objdump -D -b binary -m i8086 --adjust-vma=0x7c00 boot.bin | head -100

boot.bin:     文件格式 binary


Disassembly of section .data:

00007c00 <.data>:
    7c00:	eb 3c                	jmp    0x7c3e
    7c02:	90                   	nop

...(省略)...

eb 3c=jmp 0x3c(相対距離)
よってjmp先は0x7c02 + 0x3c = 0x7c3e
※次回以降に確認するBPB(BIOS Parameter Block)とい領域を飛ばす為にjmp命令がある。

jmp先の0x7c3eからの領域を逆アセンブルしてみる。

test@test-fujitsu:~/kaihatsu$ dd if=boot.bin of=code.bin bs=1 skip=62
记录了450+0 的读入
记录了450+0 的写出
450字节已复制,0.0146694 s,30.7 kB/s
test@test-fujitsu:~/kaihatsu$ ndisasm -b 16 -o 0x7c3e code.bin
00007C3E  0E                push cs
00007C3F  1F                pop ds
00007C40  BE5B7C            mov si,0x7c5b
00007C43  AC                lodsb
00007C44  22C0              and al,al
00007C46  740B              jz 0x7c53
00007C48  56                push si
00007C49  B40E              mov ah,0xe
00007C4B  BB0700            mov bx,0x7
00007C4E  CD10              int 0x10
00007C50  5E                pop si
00007C51  EBF0              jmp short 0x7c43
00007C53  32E4              xor ah,ah
00007C55  CD16              int 0x16
00007C57  CD19              int 0x19
00007C59  EBFE              jmp short 0x7c59

...(省略)...

アセンブリの意味を解析する。

00007C3E  0E                push cs           ; DS(データセグメント)とCS(コードセグメント)
00007C3F  1F                pop ds            ; を一致させる。
00007C40  BE5B7C            mov si,0x7c5b     ; 表示する文言のオフセット
00007C43  AC                lodsb             ; AL = [DS:SI], SI = SI + 1
00007C44  22C0              and al,al         ; if(AL=0x00)goto 0x7c53 終端(0x00)なら跳ぶ 
00007C46  740B              jz 0x7c53
00007C48  56                push si           ; int 0x10中にSI破壊の可能性がある為退避
00007C49  B40E              mov ah,0xe        ; ALの文字を1文字表示
00007C4B  BB0700            mov bx,0x7        ; ページ0, 属性07h
00007C4E  CD10              int 0x10
00007C50  5E                pop si
00007C51  EBF0              jmp short 0x7c43
00007C53  32E4              xor ah,ah         ; AH=0 INT 16はキーボードから1文字読み込む
00007C55  CD16              int 0x16          ; and..press any key to try againのまま
00007C57  CD19              int 0x19          ; 再起動
00007C59  EBFE              jmp short 0x7c59  ; jmp $ 無限ループ(安全の為にCPUを止める.int 0x19失敗時保険)
00000050: 5eeb f032 e4cd 16cd 19eb fe54 6869 7320  ^..2.......This 

'T' = 0x54、'h' = 0x68、'i' = 0x69、's' = 0x73から文言の開始文字(T)オフセットは0x7c5bと分かる。

実機上で実際に起動してみる

逆アセンブルの為に切り出したboot.binをそのままCF(コンパクトフラッシュ)に書き込む。

sudo dd if=boot.bin of=/dev/sdb bs=512 count=1 conv=notrunc

V30実機

66f39e14105498

Think Pad X280

0b9fcfcb52652 e00811e0e01598
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?