setup 程序打开 A20 实现32位寻址

setup 程序打开 A20 实现32位寻址

目录

教学视频

1. 打开A20实现32位寻址

2. Linux内核–A20地址线

直达底部

教学视频

Linux内核启动过程:setup程序打开A20实现32位寻址

1. 打开A20实现32位寻址

打开 A20,意味着 CPU 可以进行32位寻址,最大寻址空间为4 GB。内存寻址范围从5个F扩展到 8 个F,即 0xFFFFFFFF——4 GB。

setup 程序打开 A20 实现32位寻址

setup 程序打开 A20 实现32位寻址

早期 Linux 最大只能支持 16 MB 的物理内存,但是其线性寻址空间已经是4 GB。

代码实现如下

setup 程序打开 A20 实现32位寻址

实模式下 CPU 寻址范围为0~0xFFFFF,共 1 MB 寻址空间,需要0~19号共20根地址线。进入保护 模式后,将使用 32 位寻址模式,即采用 32 根地址线进行寻址,第21根(A20)至第32根地址线的 选通控制将意味着寻址模式的切换。

注意, 早期的微机80286 有24根物理线进行寻址,所以最多物理内存访问支持24bit地址空间,即0XFFFFFF,也就是16MB。早期的Linux 运行在早期主机,所以物理寻址才是 16MB,而不是4GB

实模式下,当程序寻址超过 0xFFFFF 时,CPU将“回滚”至内存地址起始处寻址(注意, 在只有 20 根地址线的条件下,0xFFFFF+ 1= 0x00000,最高位溢出)。这样,此处对 A20 地址线的启用相当于关闭 CPU 在实模式下寻址的“回 滚” 机制。 后面代码中也将利用此特点来验证A20地址线是否确实已经打开。

返回目录

2. Linux内核--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 根地址线(6个F), 最高可寻址16MB, 并且有一个与8088完全兼容的实模式运行方式。然而,在寻址值超过 1MB 时却不能象 8088 那样实现地址寻址的环绕。

但是当时已经有一些程序是利用这种地址环绕机制进行工作的。为了实现完全的兼容性,IBM 公司发明了使用一个开关来开启或禁止 0x100000 地址比特位。由于在当时的 8042 键盘控制器上恰好有空闲的端口引脚(输出端口 P2,引脚 P21),于是便使用了该引脚来作为与门控制这个地址比特位。该信号即被称为 A20。如果它为零, 则比特 20 及以上地址都被清除, 从而实现了兼容性。

由于在机器启动时,默认条件下,A20 地址线是禁止的,所以操作系统必须使用适当的方法来开启它。但是由于各种兼容机所使用的芯片集不同,要做到这一点却是非常的麻烦。因此通常要在几种控制方法中选择。对 A20 信号线进行控制的常用方法是通过设置键盘控制器的端口值。这里的 setup.s 程序即使用了这种典型的控制方式。对于其它一些兼容微机还可以使用其它方式来做到对 A20 线的控制。

有些操作系统将 A20 的开启和禁止作为实模式与保护运行模式之间进行转换的标准过程中的一部分。由于键盘的控制器速度很慢,因此就不能使用键盘控制器对 A20 线来进行操作。为此引进了一个A20 快速门选项(Fast Gate A20),它使用 I/O 端口 0x92 来处理 A20 信号线,避免了使用慢速的键盘控制器操作方式。对于不含键盘控制器的系统就只能使用 0x92 端口来控制, 但是该端口也有可能被其它兼容微机上的设备(如显示芯片)所使用,从而造成系统错误的操作。还有一种方式是通过读 0xee 端口来开启 A20 信号线,写该端口则会禁止 A20 信号线。

返回目录