A20是什么
1981年8月,IBM 公司最初推出的个人计算机所使用的 CPU 是 Intel 8088。在该微机中地址线只有 20 根(A0~A19)。当时,计算机的 RAM 只有几百 KB 或不到 1MB 时,20 根地址线已足够用来寻址。其所能寻址的最高地址是0xffff:0xffff
,即0x10ffef
。对于超出 0x100000(1MB)
的寻址地址, 将默认回卷到0x0ffef
。
IBM 公司于 1985 年引入 AT 机时,使用的是 Intel 80286 CPU,具有 24 根地址线,最高可寻址 16MB,并且有一个与 8088 完全兼容的实模式运行方式。
然而,在寻址值超过 1MB 时它却不能象 8088 那样实现地址的回卷。但是当时已经有一些程序是利用这种地址环绕机制进行工作的。为了实现完全的兼容性,IBM 公司发明了一种方法——使用一个开关来开启或禁止地址线的比特位20到23。
由于当时的 8042 键盘控制器上恰好有空闲的端口引脚(输出端口P2,引脚名是 P21 ),于是便使用了该引脚来作为与门控制这个地址比特位。该信号被称为 A20。如果它为零,则比特 20 及以上地址都被清除。
在机器启动时,默认条件下,A20 地址线是禁止的,所以操作系统必须使用适当的方法来开启它。但是由于各种兼容机所使用的芯片集不同,要做到这一点是非常麻烦的,通常要在几种控制方案中选择。
怎样控制A20
方案一:键盘控制器
对 A20 信号线进行控制的常用方法是通过设置键盘控制器的端口值。
比如以下代码可以开启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
empty_8042:
.word 0x00eb,0x00eb !机器码,跳转到下一句,为了延时
in al,#0x64 ! 8042 status port
test al,#2 ! is input buffer full?
jnz empty_8042 ! yes - loop
ret
方案二:端口0x92
有些操作系统将 A20 的开启和禁止作为实模式与保护模式之间进行转换的标准过程的一部分。由于键盘控制器的速度很慢,因此就不能使用键盘控制器对 A20 线来进行操作。为此引进了一个 A20 快速门选项(Fast Gate A20),它使用 I/O 端口 0x92 来处理 A20 信号线。
比如
in al,0x92 ;南桥芯片内的端口
or al,0000_0010B
out 0x92,al ;打开A20
方案三:INT 15 中断
/*
* 打开A20
* 返回结果:
* 成功:CF=0, AH=0
* 失败:CF=1, AH=0x01 键盘控制器处于secur模式
* AH=0x86 功能不支持
*/
mov ax, 0x2401
int 0x15
方案四:0xee端口
还有一种方式是通过读 0xee 端口来开启 A20 信号线,写该端口则会禁止 A20 信号线。
in al,0xee ;开启A20