A20 Gate

来源:互联网 发布:在淘宝上怎么买vpn 编辑:程序博客网 时间:2024/06/08 17:58

很多稀奇古怪的东西都是由于系统升级时,为了保持向下兼容而产生的,A20 Gate就是其中之一。

在8086/8088中,只有20根地址总线,所以可以访问的地址是2^20=1M,但由于8086/8088是16位地址模式,能够表示的地址范围是0-64K,所以为了在8086/8088下能够访问1M内存,Intel采取了分段的模式:16位段基地址:16位偏移。其绝对地址计算方法为:16位基地址左移4位+16位偏移=20位地址。

 

但这种方式引起了新的问题,通过上述分段模式,能够表示的最大内存为:FFFFh:FFFFh=FFFF0h+FFFFh=10FFEFh=1M+64K-16Bytes(1M多余出来的部分被称做高端内存区HMA)。但8086/8088只有20位地址线,如果访问100000h~10FFEFh之间的内存,则必须有第21根地址线。所以当程序员给出超过1M(100000H-10FFEFH)的地址时,系统并不认为其访问越界而产生异常,而是自动从重新0开始计算,也就是说系统计算实际地址的时候是按照对1M求模的方式进行的,这种技术被称为wrap-around。

 

到了80286,系统的地址总线发展为24根,这样能够访问的内存可以达到2^24=16M。Intel在设计80286时提出的目标是,在实模式下,系统所表现的行为应该和8086/8088所表现的完全一样,也就是说,在实模式下,80286以及后续系列,应该和8086/8088完全兼容。但最终,80286芯片却存在一个BUG:如果程序员访问100000H-10FFEFH之间的内存,系统将实际访问这块内存,而不是象过去一样重新从0开始。


为了解决上述问题,IBM使用键盘控制器上剩余的一些输出线来管理第21根地址线(从0开始数是第20根),被称为A20 Gate:如果A20 Gate被打开,则当程序员给出100000H-10FFEFH之间的地址的时候,系统将真正访问这块内存区域;如果A20 Gate被禁止,则当程序员给出100000H-10FFEFH之间的地址的时候,系统仍然使用8086/8088的方式。绝大多数IBM PC兼容机默认的A20 Gate是被禁止的。由于在当时没有更好的方法来解决这个问题,所以IBM使用了键盘控制器来操作A20 Gate,但这只是一种黑客行为,毕竟A20 Gate和键盘操作没有任何关系。在许多新型PC上存在着一种通过芯片来直接控制A20 Gate的BIOS功能。从性能上,这种方法比通过键盘控制器来控制A20 Gate要稍微高一点。

 

上面所述的内存访问模式都是实模式,在80286以及更高系列的PC中,即使A20 Gate被打开,在实模式下所能够访问的内存最大也只能为10FFEFH,尽管它们的地址总线所能够访问的能力都大大超过这个限制。为了能够访问10FFEFH以上的内存,则必须进入保护模式。(其实所谓的实模式,就是8086/8088的模式,这种模式存在的唯一理由就是为了让旧的程序能够继续正常的运行在新的PC体系上)

1. A20 Gate in Protected Mode

从80286开始,系统出现了一种新的机制,被称为保护模式。到了80386,保护模式得到了进一步的完善和发展,并且对于80386以后的芯片,保护模式的变化就非常小了。

 

我们在上一节已经谈到,如果要访问更多的内存,则必须进入保护模式,那么,在保护模式下,A20 Gate对于内存访问有什么影响呢?

 

为了搞清楚这一点,我们先来看一看A20的工作原理。A20,从它的名字就可以看出来,其实它就是对于20-bit(从0开始数)的特殊处理(也就是对第21根地址线的处理)。如果A20 Gate被禁止,对于80286来说,其地址为24bit,其地址表示为EFFFFF;对于80386极其随后的32-bit芯片来说,其地址表示为FFEFFFFF。这种表示的意思是如果A20 Gate被禁止,则其第20-bit在CPU做地址访问的时候是无效的,永远只能被作为0;如果A20 Gate被打开,则其第20-bit是有效的,其值既可以是0,又可以是1。

所以,在保护模式下,如果A20 Gate被禁止,则可以访问的内存只能是奇数1M段,即1M,3M,5M…,也就是00000-FFFFF, 200000-2FFFFF,300000-3FFFFF…。如果A20 Gate被打开,则可以访问的内存则是连续的。

2. How to Enable A20 Gate

多数PC都使用键盘控制器(8042芯片)来处理A20 Gate。

 

从理论上讲,打开A20 Gate的方法是通过设置8042芯片输出端口(64h)的2nd-bit,但事实上,当你向8042芯片输出端口进行写操作的时候,在键盘缓冲区中,或许还有别的数据尚未处理,因此你必须首先处理这些数据。

 

流程如下:

 1. 禁止中断;

 2. 等待,直到8042 Input buffer为空为止;

 3. 发送禁止键盘操作命令到8042 Input buffer;

 4. 等待,直到8042 Input buffer为空为止;

 5. 发送读取8042 Output Port命令;

 6. 等待,直到8042 Output buffer有数据为止;

 7. 读取8042 Output buffer,并保存得到的字节;

 8. 等待,直到8042 Input buffer为空为止;

 9. 发送Write 8042 Output Port命令到8042 Input buffer;

 10. 等待,直到8042 Input buffer为空为止;

 11. 将从8042 Output Port得到的字节的第2位置1(OR 2),然后写入8042 Input buffer;

 12. 等待,直到8042 Input buffer为空为止;

 13. 发送允许键盘操作命令到8042 Input buffer;

 14. 打开中断。

 

下面代码是一个相关实现:

enable_a20:

sti

 

call wait_input_empty

movb $0xAD, %al

outb $0x64 #disable Keyboard

 

call wait_input_empty

movb $0xD0, %al

outb $0x64 # command-read 8042 output port

 

call wait_output_full

inb $0x60 # got the value of 8042 output port and save it

pushb %al

 

call wait_input_empty

movb $0xD1, %al

outb $0x64 # command-write 8042 output port

 

call wait_input_empty

popb %al

orb $0x02, %al # enable A20 Gate

outb $0x60

 

call wait_input_empty

movb $0xAE, %al

outb $0x64 #enable Keyboard

 

cli

ret

 

wait_input_empty:

rp1: inb $0x64

testb %al, 0x02

jnz rp1

ret

 

wait_output_full:

rp2: inb $0x64

testb %al, 0x01

jz rp2

ret

 

以上描述的是一种和IBM PC完全兼容的,通过键盘控制器控制A20 Gate的方法。但是,正象我们在前面所提到的,A20 Gate与键盘操作完全没有关系,IBM之所以将A20 Gate的功能控制放在键盘控制器上,完全是一种为了弥补Intel 80286与Intel 8086/8088不完全兼容的缺陷,而采取的Hacker行为,所以在许多新型PC上存在着一种通过芯片来直接控制A20 Gate的BIOS功能,我们在Real Mode下只需要调用BIOS中断就可以实现A20 Gate的控制功能。

这个BIOS中断为 INT 15h, AX=2401h。被称为Fast A20。

 

movw $0x2401, %ax

int $0x15

3. How to Detect if A20 Gate has been Enabled?

 

我们在之前已经提到,如果A20 Gate被打开了,则在实模式下,程序员可以直接访问100000H~10FFEFH之间的内存,如果A20 Gate被禁止,则在实模式下,若程序员访问100000H~10FFEFH之间的内存,则会被硬件自动转换为0H~0FFEFH之间的内存,所以我们可以利用这个差异来检测A20 Gate是否被打开。

 

# This routine tests whether or not A20 is enabled. If so, it

# exits with zf = 0.

#

# The memory address used, 0x200, is the int $0x80 vector, which

# should be safe.

 

A20_TEST_ADDR = 4*0x80

A20_TEST_LOOPS = 3

 

a20_test:
pushw %cx
pushw %ax
xorw %cx, %cx
movw %cx, %fs # Low memory
decw %cx
movw %cx, %gs # High memory area
movw $A20_TEST_LOOPS, %cx
movw %fs:(A20_TEST_ADDR), %ax
pushw %ax

 

a20_test_wait:
incw %ax
movw %ax, %fs:(A20_TEST_ADDR)
call delay # Serialize and make delay constant
cmpw %gs:(A20_TEST_ADDR+0x10), %ax
loope a20_test_wait

popw %fs:(A20_TEST_ADDR)
popw %ax
popw %cx
ret

 

delay:
outb %al,$0x80
ret

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 硫酸铬钾中毒怎么办 门锁能扭动却打不开怎么办 防盗门保险坏了怎么办 厦门工会卡过期怎么办 阴雨天被子受潮怎么办 衣服晾臭了怎么办 喷砂机油水分离泵有油怎么办 水太烫玻璃瓶盖打不开怎么办 玻璃罐的玻璃盖打不开怎么办? 开红酒没有开瓶器怎么办 手机卡突然坏了怎么办 滚筒洗衣机打不开门怎么办 全自动洗衣机门开不开怎么办 好期待评分不足怎么办 单片机数码管亮度低怎么办 猫的同轴灯不亮怎么办 楼下邻居太吵怎么办 冰箱冷却液内露怎么办 冷却水没有了会怎么办 金立m7信号不好怎么办 csgo凉了饰品怎么办 模型拟合度低怎么办 石膏线用发泡胶怎么办 电表上显示err10怎么办 电表显示欠压怎么办 tcl电视遥控器失灵怎么办 玩具汽车遥控器失灵怎么办 玩具车遥控丢了怎么办 按压扣坏了怎么办 电脑用不了鼠标怎么办 多肉上的肉虫子怎么办 警察被取消警衔怎么办 隐形眼镜带歪了怎么办 gta5正在加载慢怎么办 gta5线上卡住了怎么办 皮子掉的颜色怎么办 gta5死了之后车怎么办 潜水口里有水怎么办 800度近视潜水怎么办 不会游泳深潜怎么办 高度近视浮潜怎么办