打开A20地址线
还记得实模式下的wrap-around吗?也就是地址回绕。咱们一起来复习一下。实模式下内存访问是采取“段基址:段内偏移地址”的形式,段基址要乘以16后再加上段内偏移地址。实模式下寄存器都是16位的,如果段基址和段内偏移地址都为16位的最大值,即0xFFFF:0xFFFF,最大地址是0xFFFF0+0xFFFF,即0x10FFEF。由于实模式下的地址线是20位,最大寻址空间是1MB,即0x00000~0xFFFFF。超出1MB内存的部分在逻辑上也是正常的,但物理内存中却没有与之对应的部分。为了让“段基址:段内偏移地址”策略继续可用,cpu采取的做法是,将超过1MB的部分自动回绕到0地址,继续从0地址开始映射。相当于把地址对1MB求模。超过1MB多余出来的内存被称为高端内存区HMA。
这种地址回绕是如何做到的呢?要分两种情况分别讨论啦。
对于只有20位地址线的cpu,不需要任何额外操作便能自动实现地址回绕。
地址(Address)地址线是从0开始编号,在8086/8088中,只有20位地址线,即A0~A19。20位地址线表示的内存是2的20次方,即最大是1MB,即0x0~0xFFFFF。内存若超过1MB,是需要第21条地址线支持的。所以说,若地址进位到1MB以上,如0x100000,由于没有第21位地址线,相当于丢掉了进位1,变成了0x00000。这一“缺陷”甚至成了当时很多程序员利用的技巧。如图
对于80286后续的CPU,通过A20GATE来控制A20地址线 。
cpu发展到了 80286后,虽然地址总线从原来的20位发展到了24位,从而能够访问的内存范围可达到2的24次方等于16MB。但任何时候,Intel都会把兼容放在第一位。80286是第一款具有保护模式的cpu,它在实模式下时,其表现也应该和8086/8088一模一样。按照兼容的要求,这意味着80286以及后续cpu的实模式都应该与8086/8088完全一样,即:仍然只使用20条地址线。但80286有24条地址线,即A0~A23,也就是说A20地址线是开启的。如果访问0x100000~0x10FFEF之间的内存,系统将直接访问这块物理内存,并不会象8086/8088那样回绕到0。
为了解决此问题,IBM在键盘控制器上的一些输出线来控制第21根地址线(A20)的有效性,故被称为A20Gate:
- λ如果A20Gate被打开,当访问到0x100000~0x10FFEF之间的地址时,cpu将真正访问这块物理内存。
- λ如果A20Gate被禁止,当访问0x100000~0x10FFEF之间的地址时,cpu将采用8086/8088的地址回绕。
上面描述了地址回绕的原理,但地址回绕是为了兼容8086/8088的实模式。如今我们是在保护模式下,我们需要突破第20条地址线(A20)去访问更大的内存空间。而这一切,只有关闭了地址回绕才能实现。而关闭地址回绕,就是上面所说的打开A20Gate。
说了半天,其实打开A20Gate的方式是极其简单的,将端口0x92的第1位置1就可以了,以下三个步骤就可以实现啦。
- in al,0x92
- or al,0000_0010B
- out 0x92,al
我们离保护模式越来越近了,为了给大家一个盼头,剧透一下,其实我们距32位地址空间只差一步,下一节中我们将播出有关内容,欢迎大家准时收看^_^