8

在我的 MIT OS 课程 (686) 中,我发现了一些我不理解的代码。我试图理解boot / boot.Sinb $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
4

2 回答 2

8

什么是端口 0x64?

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

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

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

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

它正在测试哪个设备或机制是否繁忙?我对代码忙碌中的评论感到困惑?评论是什么意思,它指的是什么?

此处的代码使 CPU 轮询 PS/2 键盘控制器以查看它是否忙。

inb     $0x64,%al               # Get status

上述指令读取 PS/2 控制器的状态寄存器,其长度为 8 位。具体来说,它正在尝试读取输入缓冲区的状态 - 位 1。

testb   $0x2,%al                # Busy?

上一条 inb 指令返回的字节在这里进行测试。这里检查输入缓冲区的状态以查看它是满还是空 - 位 1(0x2)。

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)

x86 汇编代码 的语法 上面的线程详细解释了这里提到的端口 0x64 和 0x60。

以下链接还详细讨论了如何使用 IO 端口。 I/O 端口地址和数据如何发送?

于 2015-11-23T02:43:19.237 回答
3

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

另一个功能是 A20 门 - 因为 80286 在地址总线中添加了 4 位,所以有一些程序是为 8086 编写的,并期望地址在 1048575 (2^20 - 1) 之后回绕到 0。因此,IBM 工程师想出了一个聪明的解决方案, 可怕的 hack - 他们使用了键盘控制器的一个额外引脚,在启动后设置为 0,并在使用 A20 地址线的地址线 20 上添加了一个门,这条线来自键盘控制器作为其输入——本质上,进入内存控制器的 CPU 地址总线的第 20 位为零,除非启用了 A20 门启用引脚

当然,如果您想像任何现代操作系统一样真正解决所有内存问题,那么您需要重新启用它。

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

于 2019-11-13T15:57:36.003 回答