3日目
今回のテーマは、IPLを作成しようということです。
IPLとは、初期プログラムローダのことです。
FDの内容をメモリに展開
FDの先頭512バイト(1セクタ)の次の512バイトをメモリ上に展開する方法について解説してあります。
ソースでは、下記の箇所が街頭箇所になります。
#ディスクを読み込む movw $0x0820, %ax movw %ax, %es movb $0x00, %ch #シリンダ 0 movb $0x00, %dh #ヘッド 0 movb $0x02, %cl #セクタ 2 movb $0x02, %ah #ディスク読み込み movb $0x01, %al #1セクタ movw $0x00, %bx movb $0x00, %dl #Aドライブ int $0x13 #ディスクBIOSコール jc error
メモリマップ、INT命令は、下記記事にあるリンクを参照して下さい。
2日目 - 未来設計図
10シリンダー分読むプログラム
.equ CYLS, 10 .text .code16 # 以下は標準的なFAT12フォーマットフロッピーディスクのための記述 jmp entry .byte 0x90 .ascii "HELLOIPL" # ブートセクタの名前(8バイト) .word 512 # 1セクタの大きさ .byte 0x01 # クラスタの大きさ .word 1 # FATの開始位置(普通は、1セクタ目から) .byte 0x02 # FATの個数 .word 224 # ルートディレクトリ領域の大きさ(224エントリ) .word 2880 # このドライブの大きさ .byte 0xf0 # メディアのタイプ .word 9 # FAT領域の長さ .word 18 # 1トラックにあるセクタ数 .word 2 # ヘッドの数 .int 0 # パーティションの個数(未使用なので0) .int 2880 # このドライブの大きさをもう一度書く .byte 0x00, 0x00, 0x29 # ?? .int 0xffffffff # ボリュームシリアル番号 .ascii "HELLO-OS " # ディスクの名前(11バイト) readloop: movw $0x00, %si #失敗回数を数える retry: movb $0x02, %ah #ディスク読み込み movb $0x01, %al #1セクタ movw $0x00, %bx movb $0x00, %dl #Aドライブ int $0x13 #ディスクBIOSコール jnc next addw 1, %si #失敗回数をカウント cmp $0x05, %si #5失敗したらエラー jae error movb $0x00, %ah movb $0x00, %dl #Aドライブ int $0x12 #ドライブのリセット jmp retry #---------------------------- #次のセクタを読み出すための処理 #---------------------------- next: movw %es, %ax addw $0x0020, %ax #0x0200(512バイト分)進める movw %ax, %es addb $0x01, %cl #セクタ位置も更新 cmpb $18, %cl #18セクタ分読み込んだ場合 jbe readloop # cl <= 18だったら、readloopへ movb $1, %cl addb $1, %dh cmpb $2, %dh # dh < 2の場合は、readloopへ movb $0, %dh add $1, %ch cmp $CYLS, %ch jb readloop #読み込み終わったけどとりあえずやることないので寝る fin: hlt jmp fin readloop: movw $0x00, %si #失敗回数を数える retry: movb $0x02, %ah #ディスク読み込み movb $0x01, %al #1セクタ movw $0x00, %bx movb $0x00, %dl #Aドライブ int $0x13 #ディスクBIOSコール jnc next addw 1, %si #失敗回数をカウント cmp $0x05, %si #5失敗したらエラー jae error movb $0x00, %ah movb $0x00, %dl #Aドライブ int $0x12 #ドライブのリセット jmp retry #---------------------------- #次のセクタを読み出すための処理 #---------------------------- next: movw %es, %ax addw $0x0020, %ax #0x0200(512バイト分)進める movw %ax, %es addb $0x01, %cl #セクタ位置も更新 cmpb $18, %cl #18セクタ分読み込んだ場合 jbe readloop # cl <= 18だったら、readloopへ movb $1, %cl addb $1, %dh cmpb $2, %dh # dh < 2の場合は、readloopへ movb $0, %dh add $1, %ch cmp $CYLS, %ch jb readloop #読み込み終わったけどとりあえずやることないので寝る fin: hlt jmp fin error: movw $msg, %si putloop: movb (%si), %al addw $1, %si cmpb $0, %al je fin movb $0x0e , %ah #1文字表示 movw $15, %bx #カラーコード int $0x10 #ビデオBIOS呼び出し jmp putloop #表示用データ msg: .byte 0x0a, 0x0a .ascii "load error" .byte 0x0a .byte 0x00 .org 0x1fe, 0x00 .byte 0x55, 0xaa