Bochs BIOS の動作などのまとめ  

このページはBochsのBIOS(rombios.c)についてまとめたページです。
参考にしたバージョンは以下の通りです。

$Id: rombios.c,v 1.160 2006/01/25 17:51:49 vruppert Exp $

もくじ  

ただし、リンクは使用できません。URLに「#」がつくだけです。


EBDA (Extended BIOS Data Area)  

BIOSが使用するデータバッファです。
最大でどのくらい使われるのか分かりませんが、大きくても40KB~63KBくらいでしょう。
640KBの低位メモリの高位(0x000A6000~0x000AFFFFなど)が使われます。

CMOS RAM の意味 (Bochs用)  

RAMアドレス用途/意味備考
0x10フロッピーディスクドライブのタイプ(high4bits:#0,low4bits:#1)
0x12ハードディスクタイプ(high4bits:#0,low4bits:#1)
0x19ハードディスク#0の拡張タイプ2Fh(47)固定?
0x1Aハードディスク#1の拡張タイプ
0x1B~23ハードディスクパラメータ#0
0x24~2Cハードディスクパラメータ#1
0x2Db5(0x20):CDブート非対応コンパイル時のブートシーケンス(=0:C,A/=1:A,C)
0x383rd(high4bits) boot device値の意味はこちら
0x38FDブート時のboot signature disableの値(bit0)=0:enable,=1:disable
0x39~3AATA driver: the translation policy is defined
0x3D1st(high4bits)/2nd(low4bits) boot device値の意味はこちら

1st/2nd/3rd boot device  

意味
0デバイス未定義(終了?)
1フロッピーディスクドライブ #0
2ハードディスクドライブ #0
3CD-ROMドライブ


Power On Boot時の一連の動作  

  1. F000:E05BhへFAR JMP
  2. DMACの初期化
  3. CMOSのシャットダウンステータスによって分岐
  4. (==0なら:) 割り込みに禁止し
  5. スタックの設定,BIOSコミュニケーションエリア(seg:0040h)の初期化
  6. biosメッセージの表示
  7. 割り込みベクタテーブルのゼロ初期化
  8. BIOSコミュニケーションエリアの初期値設定とベクタの設定
    • word [40:13h] = 639;
  9. int 17,18,19,1C,12,11,15hベクタの設定
  10. EBDA の初期化処理
    • byte [9fc0:0h] = 1; // size(1KB)
    • word [40:0eh] = 9fc0h;
  11. PITの初期値設定(18.2Hz)とint 08hベクタの設定(1chは初期化済)
  12. Keyboard(int 09,16hベクタの設定)
  13. Keyboard関連のコミュニケーションエリアへの書き込み
    • byte [40:17~19,71,97h], 0h;
    • byte [40:96h], 10h;
    • word [40:1a,1c,80h], 1eh;
    • word [40:82h], 3eh;
  14. キーボードの初期化処理
  15. ;; mov CMOS Equipment Byte to BDA Equipment Word
    • ax = [40:10h]; al = 14h; outpb(70h, al); al = inp(71h); [40:10h] = ax;
  16. パラレルポートのスキャン&設定(0378,0278h)
  17. シリアルポートのスキャン&設定(03F8,02F8,03E8,02E8h)
  18. CMOS/RTCのint 1A,4A,70hベクタを設定
  19. timer_tick_postの呼び出し
  20. PS/2マウス,FPU,VIDEOBIOSのint 74,75,10hベクタを設定
  21. PICの初期化
    • マスクレジスタはマスタ:B8h,スレーブ:8Fhのようだ。
  22. PCIBIOSによるIOMEM/IRQSの初期化?
  23. 外部ROMのスキャン&CRC検査&実行
    • VGABIOS.BINも実行されint 10hベクタが変更されビデオモード番号が03hに設定される?
  24. ROMBIOS.Cのバナー表示
  25. フロッピーディスクの設定(CMOSから読み込んでコミュニケーションエリアに設定するだけ)
    • byte [40:3e,3f,40,41,42,43,44,45,46,47,48,8bh], 0;
    • CMOS(10h)の上位,下位4bitをチェックしてドライブが存在すれば[40:8f]の相当のビットを7に変更して書き込み
    • byte [40:90,91,92,93,94,95], 0;
    • al = 2h; outp (0ah, al);
    • int 1e,40(int13_diskette?),0ehベクタの設定
    • ret
  26. ハードディスクドライブの設定(CMOSから読み込んでパラメータをコピー?)
    • outp(3f6h, 0ah);
    • byte [40:74,77,8c,8d,8eh], 0;
    • byte [40:75h], 1; byte [40:76h], c0h;
    • int 13,76,41,46hベクタの設定
    • ;; move disk geometry data from CMOS to EBDA disk parameter table(s)
    • CMOS(12h)の状態に従って分岐
    • 拡張タイプの時はCMOS(19,1ah)に従う(=47(user definable?)でないとHALT?)
      • CMOS(1b~23,24~2ch)にユーザーパラメータ?
    • ATA/ATAPIドライバの初期化と存在チェック
  27. CDエミュレーションの初期化?
  28. boot試行(int 19hの発行)

int 19hの動作  

  1. int19_relocated: がint 19h;で呼ばれる
  2. ds = 0;
  3. 1st-3rd boot device をチェック(push 1~3;call _int19_fucntion;add sp,2;test ax,ax; jnz boot_setup;)
    • 戻り値:bl = boot drive; ax = error (="0") or boot segment (exp:07C0h)
    • すべてのdeviceでbootが失敗するとint18_handlerがnear jmpで呼ばれる(int 18hをフックしても…無効?orz)
  4. どれかのboot deviceが認識されるとboot_setup:に実行が移行する(dl=device,ax=segment)
  5. dl = bl(boot device); eax = eax(segment)<<4; [ret_ip], ax; eax = eax>>4; ax &= f000h; [ret_cs], ax; ax = 0; es = 0; bp = 0; ax = aa55h; iret(to IPL code);

_int19_functionの動作  


コメントお名前NameLink

static int int19_function(char bseqhr);

// リターン値: ax = BOOTセグメント, bl = ドライブ番号
  Bit32u 
int19_function(bseqnr)
Bit8u bseqnr;
{
  Bit16u ebda_seg=read_word(0x0040,0x000E);
  Bit16u bootseq;
  Bit8u  bootdrv;
  Bit8u  bootcd;
  Bit8u  bootchk;
  Bit16u bootseg;
  Bit16u status;
  Bit8u  lastdrive=0;

  // BX_ELTORITO_BOOTをdefineしないでコンパイルした場合(古い方法)
  //   CMOS(0x2D)のbit5をDLのbit7にロードする.
  //   これはINT 13hの呼び出し時にセットされる(?)
  //    (0=フロッピーディスク A:, 0x80=HDD C:)
  //     0: ブートする順番はC:が最初でその後にA:
  //     1: ブートする順番はA:が最初でその後にC:
  // BX_ELTORITO_BOOTをdefineしてコンパイルした場合
  //   CMOS(0x3Dと0x38)の内容で以下のように指定する
  //     CMOS(0x3D)の下位4bit : 1st boot device
  //     CMOS(0x3D)の上位4bit : 2nd boot device
  //     CMOS(0x38)の上位4bit : 3rd boot device
  //   boot device の割り当て:
  //     0x00 : 未定義
  //     0x01 : フロッピーディスク(A:)
  //     0x02 : ハードディスク(C:)
  //     0x03 : CD-ROM(D:)
  //     その他 : ブート中断

  // ブートデバイスの順番を取得
  bootseq=inb_cmos(0x3d);
  bootseq|=((inb_cmos(0x38) & 0xf0) << 4);
  // bseqhrはboot device の順番(1st/2nd/3rd)
  if (bseqnr==2) bootseq >>= 4;
  if (bseqnr==3) bootseq >>= 8;
  if (bootseq<0x10) lastdrive = 1;
  bootdrv=0x00; bootcd=0;
  switch(bootseq & 0x0f) {
    case 0x01: bootdrv=0x00; bootcd=0; break;
    case 0x02: bootdrv=0x80; bootcd=0; break;
    case 0x03: bootdrv=0x00; bootcd=1; break;
    default:   return 0x00000000;
    }

  // CDからブートすることができる場合
  if (bootcd != 0) {
    status = cdrom_boot();

    // 失敗した場合
    if ( (status & 0x00ff) !=0 ) {
      print_cdromboot_failure(status);
      print_boot_failure(bootcd, bootdrv, 1, lastdrive);
      return 0x00000000;
      }
    // 成功した場合はセグメントとドライブ値を設定
    bootseg = read_word(ebda_seg,&EbdaData->cdemu.load_segment);
    bootdrv = (Bit8u)(status>>8);
    }


  // ハードディスクかフロッピーディスクから起動する場合
  if (bootcd == 0) {
    bootseg=0x07c0;

ASM_START
    push bp
    mov  bp, sp

    mov  ax, #0x0000
    mov  _int19_function.status + 2[bp], ax
    mov  dl, _int19_function.bootdrv + 2[bp]
    mov  ax, _int19_function.bootseg + 2[bp]
    mov  es, ax         ;; segment  ;; BootSegment:0x07c0
    mov  bx, #0x0000    ;; offset
    mov  ah, #0x02      ;; function 2, read diskette sector
    mov  al, #0x01      ;; read 1 sector
    mov  ch, #0x00      ;; track 0
    mov  cl, #0x01      ;; sector 1
    mov  dh, #0x00      ;; head 0
    int  #0x13          ;; read sector
    jnc  int19_load_done
    mov  ax, #0x0001
    mov  _int19_function.status + 2[bp], ax

int19_load_done:
    pop  bp
ASM_END
    // 失敗した場合
    if (status != 0) {
      print_boot_failure(bootcd, bootdrv, 1, lastdrive);
      return 0x00000000;
      }
    }

  // CMOS(0x38)でフロッピーディスクブートが指定
  // された場合のみ、signuatureをチェックする
  // bootchk = 1 : signature check disabled
  // bootchk = 0 : signature check enabled
  if (bootdrv != 0) bootchk = 0;
  else bootchk = inb_cmos(0x38) & 0x01;

  // CDブート時はsignatureチェックをしない
  if (bootcd != 0)
    bootchk = 1;

  if (bootchk == 0) {
    if (read_word(bootseg,0x1fe) != 0xaa55) {
      print_boot_failure(bootcd, bootdrv, 0, lastdrive);
      return 0x00000000;
      }
    }
  
  // 起動メッセージの表示
  print_boot_device(bootcd, bootdrv);

  // リターン値としてブートセグメントを返す
  return (((Bit32u)bootdrv) << 16) + bootseg;
}

 

(書きかけ)



FDCのレジスタ  

I/Oレジスタ周りの配置  

IOアドレス(FDC#1/#2)レジスタ名読み書き意味備考
3F0/370hステータスレジスタAR本家ATには無い
3F1/371hステータスレジスタBR本家ATには無い
3F2/372hディジタルアウトプットレジスタW
3F3/373hテープドライブレジスタRWテープサポートが無ければ関係ない
3F4/374hメインステータスレジスタR
3F4/374hデータレートセレクトレジスタW本家ATには無い
3F5/375hデータレジスタ(FIFO)RW
3F7/377hディジタルインプットレジスタR
3F7/377hコンフィグレーションコントロールレジスタW


I/Oレジスタの意味とビット配置  

FDCの制御手順  

FDCの動作は以下の3つのフェーズを経て行われます。

コマンド(C)フェーズ  

 FDCがアイドル状態(MSR=80h)にあるとき, CPUはFDCへのコマンドの書き込みを開始できます. コマンドは1~2バイトで, さらにパラメータが付いて最大9バイトを書き込みます. パラメータの省略はできないので, 必ず必要なバイト分すべてを書き込みます.
 コマンドの書き込みはMSRのRQM = "1", DIO = "0"を確認しながら行います. もしFDCがコマンド異常を検出すると, 最後のリザルトフェーズに移行しますが, このときにはDIO = "1" となるので, 異常発生がわかります.
 コマンドフェーズが終了すると, FDCはエグゼキューションフェーズに移行します. 例外は,
     ・SENSE INTERRUPT STATUS(直接リザルトフェーズに移行)
     ・SENSE DEVICE STATUS(直接リザルトフェーズに移行)
     ・SPECIFY(コマンドフェーズだけで終了)
などのFDDへのアクセスが不要なコマンド群です.

エグゼキューション(E)フェーズ  

 コマンドを受け取ると, FDCはエグザキューションフェーズに移行します. FDのリード/ライトや, ヘッドシーク(ヘッドの移動)などが行われます. DMAモードに設定していれば, FDのリード/ライト系コマンドのエグゼキューションフェーズでDMA転送要求が行われます.
 PCの場合, FDCとのデータ転送は, DMAを用いて行うのがふつうの使い方です. エグゼキューションフェーズが完了すると, 通常FDCはリザルトフェーズに移行するとともにホストに割り込みをかけます.
 例外はSEEKやRECALIBRATE(0トラックへのシーク), RELATIVE SEEKです. これらはRフェーズがないので, 動作完了後に割り込みが発生した後, SENSE INTERRUPT STATUSコマンドを発行して結果を引き取ります.

リザルト(R)フェーズ  

 コマンドの実行結果ステータスを通知するのがこのフェーズです. コマンドの種類に応じて1~7バイトのステータスを引き取ります.
 リザルトフェーズでは1バイトの転送ごとにMSRのRQMが "1" になり, またDIOビットは "1" になっています. ステータスはすべて引き取らないと, 次のコマンドが発行できません.
 ステータスが残っているときはDIO = "1", すべて引き取るとDIOビット="0"となるので, ステータスの引き取りが完了したかを判断することができます.

FDCコマンド/パラメータ  

READ DATA (MT/MF/SK/0/0/1/1/0)(ビット配置)  

こめんとらん  


コメントお名前NameLink


[リロード]   [トップ] [一覧] [単語検索] [最終更新]   [最終更新のRSS]