關於A20

ARM的程式設計師敲著詩歌的夢發表於2020-04-04

A20是什麼

1981年8月,IBM 公司最初推出的個人計算機所使用的 CPU 是 Intel 8088。在該微機中地址線只有 20 根(A0~A19)。當時,計算機的 RAM 只有幾百 KB 或不到 1MB 時,20 根地址線已足夠用來定址。其所能定址的最高地址是0xffff:0xffff,即0x10ffef。對於超出 0x100000(1MB)的定址地址, 將預設回捲到0x0ffef

IBM 公司於 1985 年引入 AT 機時,使用的是 Intel 80286 CPU,具有 24 根地址線,最高可定址 16MB,並且有一個與 8088 完全相容的真實模式執行方式。

然而,在定址值超過 1MB 時它卻不能象 8088 那樣實現地址的回捲。但是當時已經有一些程式是利用這種地址環繞機制進行工作的。為了實現完全的相容性,IBM 公司發明了一種方法——使用一個開關來開啟或禁止地址線的位元位20到23。

由於當時的 8042 鍵盤控制器上恰好有空閒的埠引腳(輸出埠P2,引腳名是 P21 ),於是便使用了該引腳來作為與門控制這個地址位元位。該訊號被稱為 A20。如果它為零,則位元 20 及以上地址都被清除。

在機器啟動時,預設條件下,A20 地址線是禁止的,所以作業系統必須使用適當的方法來開啟它。但是由於各種相容機所使用的晶片集不同,要做到這一點是非常麻煩的,通常要在幾種控制方案中選擇。

怎樣控制A20

方案一:鍵盤控制器

對 A20 訊號線進行控制的常用方法是通過設定鍵盤控制器的埠值。
比如以下程式碼可以開啟A20

    call empty_8042
    mov al,#0xD1        ! command write
    out #0x64,al
    call empty_8042
    mov al,#0xDF        ! A20 on
    out #0x60,al
    call empty_8042

empty_8042:
    .word   0x00eb,0x00eb !機器碼,跳轉到下一句,為了延時
    in  al,#0x64          ! 8042 status port
    test al,#2            ! is input buffer full?
    jnz empty_8042        ! yes - loop
    ret

方案二:埠0x92

有些作業系統將 A20 的開啟和禁止作為真實模式與保護模式之間進行轉換的標準過程的一部分。由於鍵盤控制器的速度很慢,因此就不能使用鍵盤控制器對 A20 線來進行操作。為此引進了一個 A20 快速門選項(Fast Gate A20),它使用 I/O 埠 0x92 來處理 A20 訊號線。

比如

    in al,0x92                         ;南橋晶片內的埠 
    or al,0000_0010B
    out 0x92,al                        ;開啟A20

方案三:INT 15 中斷

/*
 * 開啟A20
 * 返回結果:
 *    成功:CF=0,  AH=0
 *    失敗:CF=1, AH=0x01   鍵盤控制器處於secur模式
 *               AH=0x86   功能不支援
 */
    mov ax, 0x2401
    int 0x15

方案四:0xee埠

還有一種方式是通過讀 0xee 埠來開啟 A20 訊號線,寫該埠則會禁止 A20 訊號線。

    in al,0xee   ;開啟A20