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)(ビット配置)  

READ DELETED DATA (MT/MF/SK/0/1/1/0/0)  

READ ID (0/MF/0/0/1/0/1/0)  

WRITE ID (0/MF/0/0/1/1/0/1)  

WRITE DATA (MT,MF,0,0,0,1,0,1)  

WRITE DELETED DATA (MT,MF,0,0,1,0,0,1)  

READ DIAGNOSTIC (0,0,0,0,0,0,0,0)  

SCAN EQUAL, SCAN LOW OR EQUAL, SCAN HIGH OR EQUAL (0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0)  

SEEK (0,0,0,0,0,0,0,0)  

RECALIBRATE (0,0,0,0,0,0,0,0)  

SENSE INTERRUPT STATUS (0,0,0,0,0,0,0,0)  

SENSE DEVICE STATUS (0,0,0,0,0,0,0,0)  

SPECIFY (0,0,0,0,0,0,0,0)  

CONFIGURE (0,0,0,0,0,0,0,0)  

DUMPREG (0,0,0,0,0,0,0,0)  

READ TRACK (0,0,0,0,0,0,0,0)  

RELATIVE SEEK (0,0,0,0,0,0,0,0)  

VERIFY (0,0,0,0,0,0,0,0)  

VERSION (0,0,0,0,0,0,0,0)  

MODE (0,0,0,0,0,0,0,0)  

NSC (0,0,0,0,0,0,0,0)  

FDCコマンドのパラメータ  

BFR (CMOS Disk Interface Buffer Enable)  

BST (Burst Mode Disable)  

C(Cylinder), H(Head), R(Record), N(Record Length)  

D (Data)  

DC0~DC3  

DENSEL (Density Select)  

DIR (Direction)  

DTL (Data Length)  

EC (Enable Count)  

EFF (Enable FIFO)  

EIS (Enable Implied Seeks)  

EOT (End Of Track)  

ETR (Extended Track Range)  

FRD (FIFO Read Disable)  

FWR (FIFO Write Disable)  

GAP, WG  

GPL (Gap Length)  

GSL (Gap Skip Length)  

HD (Head)  

Head Settle  

HLT (Head Load Time)  

HUT (Head Unload TIme)  

AF (Index Address Format)  

IPS (Implied Seek)  

LOWPWR (Low Power)  

MF (MFM Mode)  

MT (Multi-Track)  

NCN (New Cylinder Number)  

ND (Non-DMA)  

OW (Overwrite)  

PD (Polling Disable)  

PU (PUMP Pulse OUTput Diagnostic)  

PT0~PT3 (Present Track Number 0~3)  

PTN (Precompensation Track Number)  

R255 (Recalibrate Step Pluses)  

RCN (Relative Cylinder Number)  

RG (Read Gate Diagnostic)  

SC (Sector)  

SK (Skip)  

SRT (Step Rate Time)  

STP (Step)  

THR (Threshold)  

TMR (Timer Control)  

US1, US0 (Unit Select 0, 1)  

WLD (Scan Wilid Card)  

リザルトステータス  

3モードサポート  

2.88MBFD(垂直記録ドライブ)サポート  

こめんとらん  


コメントお名前NameLink


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