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

时间:2014-01-12 19:02:36

标签: assembly x86 bootloader osdev real-mode

在我的麻省理工学院OS课程(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

2 个答案:

答案 0 :(得分:4)

  

什么是端口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)

Syntax of x86 assembly code 上面的主题详细解释了这里提到的端口0x64和0x60。

以下链接还详细讨论了如何使用IO端口。 How are I/O port addresses and data sent?

答案 1 :(得分:2)

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

另一个功能是A20门-当80286向地址总线中添加了4位时,有一些程序是为8086编写的,并期望在1048575(2 ^ 20-1)之后地址会回绕为0。因此,IBM工程师找到了一个聪明的解决方案 可怕的骇客-他们使用了键盘控制器上的一个额外的引脚,该引脚在启动后设置为0,并添加了一个与门使用A20地址线并将来自键盘控制器的该线作为输入的地址线20进行“与”门操作-除非A20门启用,否则基本上将通往内存控制器的CPU地址总线的第20位清零。引脚已启用

当然,如果您想像所有现代操作系统一样真正寻址所有内存,则需要重新启用它。

惯例是询问控制器是否繁忙,并且当不再繁忙时,向其发送命令(如果您在繁忙时向其写入命令,则全部可能会发生各种事情,包括忽略命令或将其锁定在怪异状态)。