2015-10-17 47 views
4

在OSDev wiki for enabling the A20 line的一些代碼片段中,我們有cli中斷命令。在其他一些我們沒有他們。爲什麼我們需要在有時啓用A20時禁用中斷?

E.g.當通過舊的鍵盤控制器方法設置A20線時,整個代碼被clisti組合包圍。我可以想象這會發生,因爲我們通過端口使用鍵盤通信,並且鍵盤中斷也可能會改變端口上的數據。但這是真的嗎?我只猜對了......

enable_A20: 
    cli 

    call a20wait 
    mov  al,0xAD 
    out  0x64,al 

    call a20wait 
    mov  al,0xD0 
    out  0x64,al 

    call a20wait2 
    in  al,0x60 
    push eax 

    call a20wait 
    mov  al,0xD1 
    out  0x64,al 

    call a20wait 
    pop  eax 
    or  al,2 
    out  0x60,al 

    call a20wait 
    mov  al,0xAE 
    out  0x64,al 

    call a20wait 
    sti 
    ret 

a20wait: 
    in  al,0x64 
    test al,2 
    jnz  a20wait 
    ret 


a20wait2: 
    in  al,0x64 
    test al,1 
    jz  a20wait2 
    ret 

然後在代碼測試A20線(如果已激活),中斷被禁止,但從未啓用。我想不啓用它們是一個錯誤?在這種情況下,我可以想象我們必須禁用中斷,因爲中斷可能會跳轉到我們在這段代碼中修改的內存位置,並且所有內容都會崩潰?

check_a20: 
pushf 
push ds 
push es 
push di 
push si 
cli 

xor ax, ax ; ax = 0 
mov es, ax 

not ax ; ax = 0xFFFF 
mov ds, ax 

mov di, 0x0500 
mov si, 0x0510 

mov al, byte [es:di] 
push ax 

mov al, byte [ds:si] 
push ax 

mov byte [es:di], 0x00 
mov byte [ds:si], 0xFF 

cmp byte [es:di], 0xFF 

pop ax 
mov byte [ds:si], al 

pop ax 
mov byte [es:di], al 

mov ax, 0 
je check_a20__exit 

mov ax, 1 

check_a20__exit: 
pop si 
pop di 
pop es 
pop ds 
popf 

ret 

另一方面,快速A20門的片段不包含任何中斷禁用。但我們也與港口溝通(閱讀和寫作)。因此,如果我對鍵盤控制器的猜測是真實的,那麼在我們讀完之後並在寫回之前,是否也會發生某些中斷會改變端口0x92的狀態?所以基本上我們會覆蓋中斷處理程序想要改變的內容。

fast_a20_gate: 
in al, 0x92 
test al, 2 
jnz after 
or al, 2 
and al, 0xFE 
out 0x92, al 
after: 

是否有拇指任何規則很容易地決定當我必須cli中斷,何時不?目前,我完全失去了這個決定,只能複製我能看到的東西。

+1

在進入自舉程序時,我通常會立即禁用中斷。有很多情況下他們需要被禁用,忘記其中一個可能會導致一個難以追蹤的錯誤。然後,在進入內核時,會進行一些初始化,一旦IDT設置完成,將執行'sti'。這僅適用於32/64位x86機器。 8086 <=處理器<80286,即實模式,當然是不同的話題。 – Downvoter

+3

是的,這是必要的,你不能承受硬件中斷處理程序也與端口0x60猴子。它也被鍵盤控制器使用。第二個片段*會重新啓用中斷,popf指令會恢復它。 –

+0

我喜歡拆開鍵盤IRQ:'cli'' mov al,2''out 21h,al''sti' –

回答

0

當您與鍵盤控制器通話時,您肯定希望將整個命令作爲不間斷序列發送給它。所以你必須阻止任何人打斷(!)你。

fast_a20_gate沒有這個問題。這不是一個序列,而只是一個命令 - 實際上只有一個命令。如果有人碰巧幹擾了這一點,那麼最終你仍然會設置它。

相關問題