2015-10-17 48 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没有这个问题。这不是一个序列,而只是一个命令 - 实际上只有一个命令。如果有人碰巧干扰了这一点,那么最终你仍然会设置它。

相关问题