Assembly 为什么在切换到保护模式之前在引导加载程序中测试端口0x64?

Assembly 为什么在切换到保护模式之前在引导加载程序中测试端口0x64?,assembly,x86,bootloader,osdev,real-mode,Assembly,X86,Bootloader,Osdev,Real Mode,在我的麻省理工学院操作系统课程(686)中,我发现了一些我不懂的代码。我试图理解boot/boot.S中的指令inb$0x64,%al。 我的理解是它从数据端口0x64读取一个字节到AL,什么是端口0x64?它正在测试哪个设备或机制繁忙?我对代码中的注释感到困惑,忙吗?评论的意思是什么?它指的是什么 # Enable A20: # For fascinating historical reasons (related to the fact that # the earliest 808

在我的麻省理工学院操作系统课程(686)中,我发现了一些我不懂的代码。我试图理解boot/boot.S中的指令
inb$0x64,%al
。 我的理解是它从数据端口0x64读取一个字节到AL,什么是端口0x64?它正在测试哪个设备或机制繁忙?我对代码中的注释感到困惑,忙吗?评论的意思是什么?它指的是什么

# Enable A20:
#   For fascinating historical reasons (related to the fact that
#   the earliest 8086-based PCs could only address 1MB of physical memory
#   and subsequent 80286-based PCs wanted to retain maximum compatibility),
#   physical address line 20 is tied to low when the machine boots.
#   Obviously this a bit of a drag for us, especially when trying to
#   address memory above 1MB.  This code undoes this.

seta20.1:       inb     $0x64,%al               # Get status
                testb   $0x2,%al                # Busy?
                jnz     seta20.1                # Yes
                movb    $0xd1,%al               # Command: Write
                outb    %al,$0x64               #  output port
seta20.2:       inb     $0x64,%al               # Get status
                testb   $0x2,%al                # Busy?
                jnz     seta20.2                # Yes
                movb    $0xdf,%al               # Enable
                outb    %al,$0x60               #  A20
什么是端口0x64

端口0x64是键盘控制器的IO端口

键盘控制器有两个端口0x64和0x60

端口0x64(命令端口)用于向键盘控制器(PS/2)发送命令

端口0x60(数据端口)用于向/从PS/2(键盘)控制器或PS/2设备本身发送数据

它正在测试哪个设备或机制繁忙?我对这件事感到困惑 代码中的注释忙吗?评论的意思是什么?它的作用是什么 它指的是什么

这里的代码使CPU轮询PS/2键盘控制器,查看它是否忙

inb     $0x64,%al               # Get status
上述指令读取长度为8位的PS/2控制器状态寄存器。具体来说,它试图读取输入缓冲区的状态-位1

testb   $0x2,%al                # Busy?
这里测试从上一条inb指令返回的字节。这里检查输入缓冲区的状态,看它是满的还是空的-位1(0x2)

上面的线程详细解释了这里提到的端口0x64和0x60

下面的链接还详细讨论了如何使用IO端口。

端口0x64是原始IBM PS/2系统中8042键盘控制器使用的端口。因为8042是一个通用的微控制器,可以运行程序并具有可编程的引脚,IBM工程师决定将额外的引脚用于不相关的功能——其中一个引脚用于重置CPU,使其输入引导代码

另一个功能是A20门-由于80286在地址总线中添加了4位,因此有一些程序是为8086编写的,并且期望地址在1048575(2^20-1)之后返回到0。因此IBM工程师想出了一个聪明的解决方案——他们使用了键盘控制器的一个额外pin,在引导后设置为0,并在地址行20中添加了一个and门,该门使用A20地址行和来自键盘控制器的该行作为其输入-基本上,通向内存控制器的CPU地址总线的第20位归零,除非A20门启用引脚已启用

当然,如果您想像任何现代操作系统一样,实际寻址所有内存,那么您需要重新启用它


惯例是询问控制器是否忙,当它不再忙时,向它发送命令(如果你在忙时向它写入命令,那么可能会发生各种事情,包括它忽略命令或被锁定在奇怪的状态)。

它与8042微控制器握手,如果8042尚未读取其数据,则该位为1。因此,在发送下一个命令字节之前,它需要等待位清除。非常感谢您,Hans Passant!我看了一下8042控制器,它是键盘控制器。虽然我知道PS/2控制器输出端口中的第1位是A20门,但我不明白为什么PS/2控制器可以控制操作系统是否启用A20?它的输出端口上有一个引脚,没有用于任何其他用途,所以他们将其连接到A20门。@HansPassant,非常感谢!现在我明白了!下面的帖子回答了所有的问题。
Status Register - PS/2 Controller
Bit Meaning
0   Output buffer status (0 = empty, 1 = full) (must be set before attempting to read data from IO port 0x60)

1   Input buffer status (0 = empty, 1 = full) (must be clear before attempting to write data to IO port 0x60 or IO port 0x64)

2   System Flag - Meant to be cleared on reset and set by firmware (via. PS/2 Controller Configuration Byte) if the system passes self tests (POST)

3   Command/data (0 = data written to input buffer is data for PS/2 device, 1 = data written to input buffer is data for PS/2 controller command)

4   Unknown (chipset specific) - May be "keyboard lock" (more likely unused on modern systems)

5   Unknown (chipset specific) - May be "receive time-out" or "second PS/2 port output buffer full"

6   Time-out error (0 = no error, 1 = time-out error)

7   Parity error (0 = no error, 1 = parity error)