home ホーム search 検索 -  login ログイン  | reload edit datainfo version cmd icon diff delete  | help ヘルプ

Assembler/なぜx86ではMBRが"0x7C00"にロードされるのか?

Assembler/なぜx86ではMBRが"0x7C00"にロードされるのか?

Assembler / なぜx86ではMBRが"0x7C00"にロードされるのか?
id: 610 所有者: msakamoto-sf    作成日: 2010-03-09 22:45:45
カテゴリ: Assembler 

重要:本記事で調査不足で曖昧だった点を解決した完全版をUPしました。ぜひこちらの方を参照して下さい。


x86アーキテクチャで、ブートローダ周りを調べ始めると必ず、

0x7C00

というマジックナンバーに遭遇する。"セグメント:オフセット"形式で

07C0:0000

という表記も見かける。

これはフロッピーディスク又はHDDのMBRが展開されるアドレスで、ブートローダ(MBRにインストールされる)はこのアドレスから始まることを想定して作成される。

一体誰がこのマジックナンバーを決定したのか?その起源と、確かな証拠を探してみた。

結論

x86アーキテクチャのPCの原型であるIBM PC 5150 (1981年発表) の BIOS は、ディスケット(フロッピーディスク)の先頭セクタ1つ分(今のMBR)を 0x7C00 にロードし、ブートローダとして実行するよう作成されていた。これが起源と思われる。
以降のIBM PC(およびその互換機)もその仕様を維持し、結果としてPC/AT互換機およびその上で動作するBIOSに引き継がれていった。

解説

"IBM Personal Computer XT Technical Reference manual" *1 の Appendix-A に BIOS の全ソースコード(アセンブラ)が記載されている。

大雑把な流れ:

  1. システムチェック
    1. ディスクチェック → INT 19h
  2. INT 19h : ディスケットの先頭1セクタ分を 0x7C00 にロード
    1. うまくロード出来れば、0x7C00 にJMPする。
    2. ロード出来なければ、 INT 18h で ROM BASIC を立ち上げる。

システムチェック ~ ディスクチェック → INT 19h

1142行目から "DISKETTE ATTACHMENT TEST" が始まり、この中で"INT 19h"が実行される。
1151行目の

F9:

ラベルからチェックが始まり、途中からPRINTERやRS232のチェックも始まる。

うまくいけば、1306 - 1307行の

1306: F21:           ; LOAD_BOOT_STRAP:
1307:     INT 19H    ; GO TO THE BOOT LOADER

で "INT 19h" が実行される。

INT 19h

ディスケットからトラック0, セクタ0番を 0x7C00 上に読み込む。

まず 0x7C00 というマジックナンバーは、63, 64行目で定義されている。

  63: ORG 7C00H
  64: BOOT_LOCN   LABEL FAR

INT 19hの割り込みハンドラは1417行目から始まり、その中で上のBOOT_LOCNを使ってブートローダを読み込んでいる。(ソースコード上は"BOOTSTRAP"という表記もあるが、とりあえずこの記事の日本語中では「ブートローダ」に統一しておく)
以下に該当コードを載せるが、"H1:"ラベルで始まるブロックで最初のセクタを0x7C00にロードし、成功すれば"H4:"ラベルでBOOT_LOCN、つまり0x7C00にJMPしている。

1417: ASSUME CS:CODE,DS:AB50
1418:             ORG 0E6F2H
1419: 
1420: BOOT_STRAP PROC NEAR
1421:         STI             ; ENABLE INTERRUPTS
1422:         SUB AX,AX       ; ESTABLISH ADDRESSING
1423:         MOV DS,AX
1424: 
1425: ;--- RESET THE DISK PARAMETER TABLE VECTOR
1426: 
1427:         MOV WORD PTR DISK_POINTER, OFFSET DISK_BASE
1428:         MOV WORD PTR DISK_POINTER + 2, CS
1429: 
1430: ; --- LOAD SYSTEM FROM DISKETTE -- CX HAS RETRY COUNT
1431: 
1432:         MOV CX,4        ; SET RETRY COUNT
1433:     H1:                 ; IPL_SYSTEM
1434:         PUSH CX         ; SAVE RETRY COUNT
1435:         MOV AH, 0       ; RESET THE DISKETTE SYSTEM
1436:         INT 13H         ; DISKETTE_IO
1437:         JC H2           ; IF ERROR, TRY AGAIN
1438:         MOV AX, 201H    ; READ IN THE SINGLE SECTOR
1439:         SUB DX, DX      ; TO THE BOOT LOCATION
1440:         MOV ES,DX
1441:         MOV BX,OFFSET BOOT_LOCN
1442:                         ; DRIVE 0, HEAD 0
1443:         MOV CX, 1       ; SECTOR 1, TRACK 0
1444:         INT 13H         ; DISKETTE_IO
1445:     H2:
1446:         POP CX          ; RECOVER RETRY COUNT
1447:         JNC H4          ; CF SET BY UNSUCCESSFUL
1448:         LOOP H1         ; DO IT FOR RETRY TIMES
1449: 
1450: ;----- UNABLE TO IPL FROM THE DISKETTE
1451: 
1452:     H3:
1453:         INT 18H         ; GOTO RESIDENT BASIC
1454: ;---- IPL HAS SUCCESSFUL
1455: 
1456:     H4:
1457:         JMP BOOT_LOCN
1458: BOOT_STRAP ENDP

他にBIOSのソースを確認出来たのは同マニュアルの改訂版、およびPC-JrのTechnical Reference manualの二つ。
細かい違いはあるが、INT 19h で 0x7C00 以降にブートローダをロード成功後JMPする、という流れは全て同じだった。

参考URL


*1: 参考にしたファイル名には"ibm5160"とあった。その一つ手前、5150のTechnical Reference manualは入手出来なかった。

プレーンテキスト形式でダウンロード
現在のバージョン : 2
更新者: msakamoto-sf
更新日: 2010-03-16 13:10:26
md5:23764cfd7aed0edba58b55cfb2e39924
sha1:5b4b48d30c9ea07cdf73304d7d33954ced5a7415
コメント
コメントを投稿するにはログインして下さい。