A20地址线的一点理解
A20地址线 Linux内核实现及系统启动引导
A20地址线
先来看看A20地址线的由来和历史遗留问题(纯搬运):
1981年8月,IBM公司最初推出的个人计算机IBM PC使用的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公司发明了使用一个开关来开启或禁止0x100000地址比特位。由于在当时的8042键盘控制器上恰好有空闲的端口引脚(输出端口P2,引脚P21),于是便使用了该引脚来作为与门控制这个地址比特位。该信号即被称为A20。如果A20为零,则比特20及以上地址都被清除。从而实现了兼容性。
由于在机器启动时,默认条件下,A20地址线是禁止的,所以操作系统必须使用适当的方法来开启它。但是由于各种兼容机所使用的芯片集不同,要做到这一点却是非常的麻烦。因此通常要在几种控制方法中选择。
A20地址线的控制
对A20信号线进行控制的常用方法是通过设置键盘控制器的端口值。下面引用一段linux0.11的源码(setup.s):
call empty_8042
mov al,#0xd1
out #0x64,al
call empty_8042
mov al,#0xdf
out #0x60,al
call empty_8042
...
empty_8042:
.word 0x00eb,0x00eb
in al,#0x64
test al,#2
jnz empty_8042
ret
贴一下啊head.s中的代码(这里转成Intel汇编格式,源码是AT&A汇编,看着蛋疼。。):
xor eax,eax
l:
inc eax
mov [0x000000],eax;
cmp [0x100000],eax;
je lb
向0x000000字节处数据改为1,查看0x100000处数据是否同时变成了1,若是则A20地址线没用开启;否则开启成功。
Intel 8042芯片
解释一下Intel 8042芯片(又是搬运。。。):
ntel8024是intel公司的一款键盘控制器芯片,它为x86系统中的标准配置.虽然名为键盘控制器,但是鼠标也是由其控制的. 键盘通常使用IRQ1.鼠标通常使用IRQ12.IRQ1和IRQ12都是连接在键盘控制器上的.对应intel8042的两个端口.
配给键盘控制器的I/O端口有四个,分别是0x60~0x64.在大部分情况中,只会使用到0x60和0x64.其余0x61~0x64的存在主要是为了兼容XT.可以将0x64看做是状态寄存器.0x60看成是数据寄存器.有时在给键盘控制器下指令的时候,这两个端口都要用到.两者配合来达到下指令与参数的目的.
向i8042发送命令:
- 我们需要先把命令发送到0x64端口,
- 然后紧接着把这个命令的参数发送到0x60端口,
- 然后我们可以通过读0x60端口,获得i8042返回给我们的数据。