以下代码段为启用A20 for JOS。它有一个让我感到困惑的问题。 “$ 0xdf”是一个命令,而不是数据。 它应该是端口0x64,这是命令端口。实际上,它的端口为0x60,即数据端口。 这里存在两种方法(方法3.1和方法3.2): http://www.brokenthorn.com/Resources/OSDev9.html
所以,我的问题是:为什么最后端口到0x60(outb%al,%0x60)?
seta20.1:
inb $0x64,%al # Wait for not busy
testb $0x2,%al
jnz seta20.1
movb $0xd1,%al # 0xd1 -> port 0x64
outb %al,$0x64
seta20.2:
inb $0x64,%al # Wait for not busy
testb $0x2,%al
jnz seta20.2
movb $0xdf,%al # 0xdf -> port 0x60
outb %al,$0x60
答案 0 :(得分:1)
这似乎是一个标准程序。正如我的评论中所述,端口0x60与键盘相关。但它不是唯一的功能。
键盘控制器的输出端口具有许多功能。 位0用于复位CPU(进入实模式) - 发生复位 当位0为0.位1用于控制A20 - 它在启用时启用 位1为1,当位1为0时禁用。一个设置的输出端口 键盘控制器首先写入0xd1到端口0x64,然后是 输出端口到端口0x60的所需值。人们通常会看到 值0xdd和0xdf用于禁用/启用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
答案 1 :(得分:1)
要将命令发送到PS / 2控制器,只需将命令字节写入IO端口0x64即可。如果有一个"下一个字节"然后在确保控制器准备就绪之后,需要将下一个字节写入IO端口0x60(通过确保状态寄存器的第1位清零)。
因此,在将0xd1发送到端口0x64后,命令0xdf被发送到端口0x60,从而启用A20。
如果有响应字节,则在确认它已到达之后需要从IO端口0x60读取响应字节(通过确保设置状态寄存器的位0)。