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信号线进行控制的常用方法是通过设置键盘控制器的端口值。下面引用一段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芯片(又是搬运。。。):

ntel8024是intel公司的一款键盘控制器芯片,它为x86系统中的标准配置.虽然名为键盘控制器,但是鼠标也是由其控制的.
键盘通常使用IRQ1.鼠标通常使用IRQ12.IRQ1和IRQ12都是连接在键盘控制器上的.对应intel8042的两个端口.

 

配给键盘控制器的I/O端口有四个,分别是0x60~0x64.在大部分情况中,只会使用到0x60和0x64.其余0x61~0x64的存在主要是为了兼容XT.可以将0x64看做是状态寄存器.0x60看成是数据寄存器.有时在给键盘控制器下指令的时候,这两个端口都要用到.两者配合来达到下指令与参数的目的.

 

如果我们想向i8042发送命令:

1:我们需要先把命令发送到0x64端口,
2:然后紧接着把这个命令的参数发送到0x60端口,
3:然后我们可以通过读0x60端口,获得i8042返回给我们的数据。

你可能感兴趣的:(linux,工作,汇编,IBM,X86,linux内核)