下面的代码片段为JOS启用A20。它有一个让我困惑的问题。"$0xdf"是命令,而不是数据。它应该输出到端口0x64,这是命令端口。实际上,It端口为0x60,这是数据端口。这里,存在两种方法(Method 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
这似乎是一个标准的程序。正如我在评论中所说,端口0x60是与键盘相关的。但这并不是它的唯一功能。
经典A20控制,通过键盘控制器
键盘控制器的输出端口具有多项功能。位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
来源: A20——从过去痛苦
要向PS/2控制器发送命令,只需将命令字节写入IO端口0x64。如果有"下一个字节",那么在下一个字节需要写入IO端口0x60后,确保控制器准备好了(通过确保状态寄存器的第1位是明确的)。
这样0xd1发送到0x64端口后,0xdf命令被发送到0x60端口,使能A20。
如果有响应字节,则需要在确保响应字节已经到达(通过确保设置状态寄存器的0位)之后从IO端口0x60读取响应字节。
来源:PS/2_Controller - osdev wiki