有时候启用A20时为什么需要禁用中断?

4
在OSDev wiki的一些代码片段中,例如启用A20线,我们使用cli中断命令。但在其他一些代码中,我们没有使用它们。
例如,在通过旧的键盘控制器方法设置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 <= processor < 80286,即实模式,是另一个话题,当然。 - cadaniluk
3
是的,这是必要的,你不能让硬件中断处理程序也操纵0x60端口。这个端口也被键盘控制器使用。第二段代码确实重新启用了中断,popf指令恢复了它。 - Hans Passant
我喜欢禁用键盘IRQ:cli``mov al,2``out 21h,al``sti - Dirk Wolfgang Glomp
1个回答

1
当您与键盘控制器交流时,一定要将整个命令作为不间断序列发送。因此,您需要阻止任何人打断您。 fast_a20_gate没有这个问题。它不是一个序列,而只是一个命令 - 实际上只有一个位。如果有人干扰并翻转了该位,最终您仍然会将其设置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接