OS(1) IBM-PCのブートシーケンス
IPLがロードされるメモリアドレス
周知のとおり、IBM-PCの場合BIOSの初期が完了後、BIOSの設定に従って検索された起動デバイスの先頭先頭セクタがメモリに読み込まれて実行開始するわけですが、物理アドレスで言うと0x7c00になります。
ただCPUはリアルモード(リアルアドレスモード)で動作しているため、セグメント:オフセットの組となり、実際には0000:7C00からのスタートとなるとのこと。
出所: http://hem.passagen.se/danma/nboot.htm
これを確認するため(だけ)のIPLを作成してみる。
seg.asm
ソースプログラムから
- nasm -o seg.bin seg.asm としてIPLデータ(512バイト)を作成
- ruby makeFDimage.rb seg.bin seg.img としてFDイメージファイルを作成
- Virtual PCを起動し、ステータスバーのFDアイコンへ seg.imgをDrag&Drop
としてして実行すればよし。
なお、このプログラムは
nasm -o seg.com -DCOMPROG seg.asm
としてやれば、コマンドプロンプトで実行できるCOMファイルとなります。違いは [org 0x100]となるところと、プログラム終了のMS-DOSファンクションコールを呼び出すところ。
seg.asmソース
; ; 開始アドレス seg:offset を画面に表示 ; %ifdef COMPROG [org 0x100] %endif start: call next next: mov ax, cs ; CSを表示 call put_AX mov al, ':' call putc pop ax ; 開始オフセット(start)を表示 sub ax, next - start call put_AX call put_CRLF %ifdef COMPROG mov ax, 0x4c00 int 0x21 %else jmp $ %endif ;======================================================================================== put_CRLF: push ax mov al, 13 call putc mov al, 10 call putc pop ax ret ; ; Video BIOSを利用したASCIZ文字列出力 ; puts: lodsb or al, al jz .@ret call putc jmp puts .@ret: ret ; ; 空白を出力 ; put_SPC: push ax mov al, ' ' call putc pop ax ret ; ; Video BIOSを利用した1文字出力 ; putc: push bx mov ah, 0x0e mov bx, 7 ; 白 int 0x10 pop bx ret ; ; AXレジスタを16進4桁で出力 ; put_AX: push ax push cx mov cx, 4 .@loop: rol ax, 4 push ax and al, 0x0f ; 4ビットを取り出し add al, '0' cmp al, '9' jbe .@disp add al, 'A' - '9' - 1 .@disp: call putc pop ax loop .@loop pop cx pop ax ret ; ; AXレジスタを16進4桁で出力 ; put_AL: push ax push cx mov cx, 2 .@loop: rol al, 4 push ax and al, 0x0f add al, '0' cmp al, '9' jbe .@disp add al, 'A' - '9' - 1 .@disp: call putc pop ax loop .@loop pop cx pop ax ret %ifndef COMPROG times 510 - ($ - $$) db 0 dw 0xaa55 %endif
makeFDimage.rb ソース
#! ruby -Ks if ARGV.size != 2 puts "usage: mkfdimage in-file out-file" exit end data = "" File.open(ARGV[0], "r+b") { |f| data = f.read } File.open(ARGV[1], "wb") { |f| f.write(data) f.truncate(80 * 2 * 18 * 512) }