文档章节

A20总线

放个屁
 放个屁
发布于 2016/11/20 16:14
字数 3223
阅读 28
收藏 0
点赞 0
评论 0

A20总线

 

■产生背景:

1981年8月,IBM公司最初推出的个人计算机IBM PC使用的CPU是Intel8088。在该微机中地址线只有20根(A0 – A19)。在当时,内存RAM只有几百KB或不到1MB时,20根地址线已足够用来寻址这些内存。

在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中,当程序给出超过1M(100000H-10FFEFH)的地址时,系统并不认为其访问越界而产生异常,而是自动从重新0开始计算,环绕到0FFEFh,也就是说系统计算实际地址的时候是按照对1M求模的方式进行的,这种技术被称为wrap-around。

 

1985年,当IBM公司引入AT机时,使用的是Intel 80286 CPU,具有24根地址线(A0-A23),最高可寻址16MB,并且有一个与8088完全兼容的实模式运行方式。然而,在寻址值超过1MB时它却不能象8088那样实现地址寻址的环绕。

但是当时已经有一些程序是利用这种地址环绕机制进行工作的。为了实现完全的兼容性,IBM公司发明了使用一个开关(逻辑门)来开启或禁止100000h地址比特位。由于在当时的8042键盘控制器上恰好有空闲的端口引脚(输出端口P2,引脚P21),于是便使用了该引脚来作为与门控制这个地址比特位。该信号即被称为A20门。如果A20为零,则比特20及以上地址都被清除。从而实现了兼容性。毕竟A20Gate和键盘操作没有任何关系,在许多新型PC上存在着一种通过芯片来直接控制A20 Gate的BIOS功能。从性能上,这种方法比通过键盘控制器来控制A20Gate要稍微高一点。

当A20被禁止时:程序员给出100000H~10FFEFH间的地址,80286和8086/8088 的系统表现是一致的,即按照对1M求模的方式进行寻址,满足系统升级的兼容性问题;

当A20被开启时:程序员给出的100000H~10FFEFH间的地址,80286是访问的真实地址,而8086/8088是始终是按照对1M求模的方式进行的(这里注意,是始终)。

 

■A20与实模式,保护模式

实模式就是, 为了实现系统升级的兼容性,如80286的系统表现(包括80286以后的CPU)要与8086/8088 的系统表现一致,就需要80286 CPU访问100000H-10FFEFH之间的地址的时候, 按照对1M求模的方式进行, 无论A20地址线开启关闭与否, 这种内存访问情况 称为实模式。

保护模式就是, 以A20地址线开启为前提,80286 CPU访问100000H-10FFEFH之间的地址的时候, 是访问真实的内存地址,不是求模访问,如访问100001H,就是真真切切地 访问 0x 100001H,而不是求模的 0x000001H 地址, 这种内存访问情况称为保护模式;

如果A20Gate被禁止:对于80286来说,其地址为24bit,其地址表示为EFFFFF;对于80386极其随后的32-bit芯片来说,其地址表示为FFEFFFFF。这种表示的意思是如果A20Gate被禁止,则其第20-bit在CPU做地址访问的时候是无效的,永远只能被作为0;如果A20 Gate被打开:则其第20-bit是有效的,其值既可以是0,又可以是1。

所以,在保护模式下,如果A20 Gate被打开,则可以访问的内存则是连续的;如果A20Gate被禁止,则可以访问的内存只能是偶数段,因为是20位(从0始)总为零,所23~20位只能是0000、0010、0100、0110、1000、1010、1100、1110对应十六进制为0、2、4、6、8、A、C、E。对应的十六进制地址段是000000-0FFFFF,200000-2FFFFF,400000-4FFFFF…。

A20地址线并不是打开保护模式的关键,只是在保护模式下,不打开A20地址线,你将无法访问到所有的内存。

 

■简要整理

1.80286与8086兼容

2.80286处于实模式下时,防止用户程序访问到100000h~10FFEFh之间的内存(高端内存)

3.8086模式,A20关闭的情况下,访问超过1MB内存时,会自动回卷

4.8086模式下,A20打开的情况下,访问超过1MB内存,就真实的访问

5.保护模式下,A20关闭(始终为0),则用户的地址只能是:0 - (1MB-1), 2 - (3MB-1), 4 - (5MB-1),我们可以这样设想,A20为个位数(以1MB为单位),如果它始终为0,你永远不可能让这个数变成奇数。

5.保护模式下,A20开启,则可以访问全地址,没有奇偶MB的问题。

 

■打开A20总线

在引导系统时,BIOS先打开A20总线来统计和测试所有的系统内存。而当BIOS准备将计算机的控制权交给操作系统时会先将A20总线关闭。所以操作系统必须使用适当的方法来开启它。但是由于各种兼容机所使用的芯片集不同,要做到这一点却是非常的麻烦。因此通常要在几种控制方法中选择。对A20信号线进行控制的常用方法是通过设置键盘控制器的端口值。

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

 

 

流程如下:

 1. 禁止中断;

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

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

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

 5. 发送读取8042 OutputPort命令;

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

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

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

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

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

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

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

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

 14. 打开中断。

 

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

enable_a20:

cli ; 1. 禁止中断;

call wait_input_empty; 2. 等待,直到8042 Inputbuffer为空为止;

movb $0xAD, %al; 3. 发送禁止键盘操作命令到8042Input buffer;

outb $0x64 #disableKeyboard

call wait_input_empty; 4. 等待,直到8042 Inputbuffer为空为止;

movb $0xD0, %al; 5. 发送读取8042 OutputPort命令;

outb $0x64 #command-read 8042 output port

call wait_output_full; 6. 等待,直到8042 Outputbuffer有数据为止;

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

pushb %al; 7. 读取8042 Outputbuffer,并保存得到的字节;

call wait_input_empty; 8. 等待,直到8042 Inputbuffer为空为止;

movb $0xD1, %al; 9. 发送Write 8042Output Port命令到8042 Input buffer;

outb $0x64 #command-write 8042 output port

call wait_input_empty; 10. 等待,直到8042 Inputbuffer为空为止;

popb %al

orb $0x02, %al #enable A20 Gate;andb $0xfd 关闭A20

outb $0x60; 11. 将从8042 OutputPort得到的字节的第2位置1(OR 2),然后写入8042 Input buffer;

call wait_input_empty; 12. 等待,直到8042 Inputbuffer为空为止;

movb $0xAE, %al; 13. 发送允许键盘操作命令到8042Input buffer;

outb $0x64 #enableKeyboard

sti; 14. 打开中断。

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

 

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

movw $0x2401, %ax

int $0x15

 

MOV AX, 2401H

INT 15H

 

INT 15的2400,2401,2402命令被用来关闭,开启和返回A20线状态。

2400和2401(关闭、开启)命令返回状态:

CF = clear if success #如果成功则清空

AH = 0  #

CF = set on error       #如果被设置则表明发生了错误

#AH中保存的是状态码,01=键盘控制器在安全模式,0x86=功能不被支持

2042命令返回状态

CF = clear if success   #如果成功则清空

#AH中保存的是状态码,01=键盘控制器在安全模式,0x86=功能不被支持

#AL表示A20线的当前状态,00=关闭,01=开启

#CX值如果是0xffff则表明键盘控制器在0xc000次尝试中均没准备好。

CF = set on error       #发生错误进CF会置位

 

关闭A20总线

push ax

mov ax, 0x2400

int 0x15

pop ax

 

开启A20总线:

push ax

mov ax, 0x2401

int 0x15

pop ax

 

检查A20总线

push ax

push cx

mov ax, 0x2402

int 0x15

pop cx

pop ax

 

操作 System Control Port A,这种最常见。

    MCA, EISA and other systems can also control A20 via port 0x92.

    Bits 0,1,3,6,7 seem to have the same meaning everywhere this port is implemented.

    Bit 0 (w): writing 1 to this bit causes a fast reset (used to switch back to real mode; for MCA this took 13.4 ms).

    Bit 1 (rw): 0: disable A20, 1: enable A20.

    Bit 3 (rw?): 0/1: power-on password bytes (stored in CMOS bytes 0x38-0x3f or 0x36-0x3f) accessible/inaccessible. This bit can be written to only when it is 0.

    Bits 6-7 (rw): 00: hard disk activity LED off, 01,10,11: hard disk activity LED on.

    Bits 2,4,5 are unused or have varying meanings. (On MCA bit 4 (r): 1: watchdog timeout occurred.)

 

使用系统0x92端口

这个方法是十分危险的,因为它可以导致和其他硬件冲突并强制关机。

 

0x92端口位功能

 

Bit 0 - Setting to 1 causes a fast reset  #为1时快速启动

Bit 1 - 0: disable A20, 1: enable A20  #为0时关闭A20线,为1时开启A20线

Bit 2 - Manufacturer defined  #工厂定义

Bit 3 - power on password bytes. 0: accessible, 1: inaccessible  #口令开机,0表示使用,1表示禁止

Bits 4-5 - Manufacturer defined  #工厂定义

Bits 6-7 - 00: HDD activity LED off, 01 or any value is "on"  #为00时表示HDD访问LED关闭,其他值为开启。

 

 

通过0x92端口开启A20总线的代码

push ax

mov al, 2

out 0x92, al

pop ax

 

关闭A20总线

mov al, 0

out 0x92, al

 

 

AMI BIOS (不通用)

    Bit 7 = 1: Weitek math coprocessor present

    Bit 6 = 1: Floppy drive seek at boot disabled

    Bit 5 = 1: System boot sequence A:,C: (otherwise C:,A:)

    Bit 4 = 1: System boot CPU speed high

    Bit 3 = 1: External cache enabled

    Bit 2 = 1: Internal cache enabled

    Bit 1 = 1: Fast gate A20 operation enabled

    Bit 0 = 1: Turbo switch function enabled

 

■检测总线是否被打开

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

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

# exits with zf = 0.

#

# The memory addressused, 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 # Lowmemory

decw %cx

movw %cx, %gs # Highmemory 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

 

检测程序2:

; NASM

[bits 16]

org 0x7c00

    mov ax, cs

    mov ds, ax

    mov es, ax

    call check_a20

    test ax, ax

    mov ax, A20On

    jnz Print           ; Enabled

    mov ax, A20Off

Print:

    mov bp, ax

    mov cx, 16

    mov ax, 0x1301

    mov bx, 0x000c

    mov dl, 0

    int 0x10

   

    cli                 ; Shutdown

    hlt

 

check_a20:

    push ds

    push es

    push di

    push si

    cli

    xor ax, ax ; ax = 0

    mov es, ax

    not ax ; ax = 0xFFFF

    mov ds, ax

    mov di, 0x0500

    mov si, 0x0510

    mov al, byte [es:di]

    push ax

    mov al, byte [ds:si]

    push ax

    mov byte [es:di], 0x00

    mov byte [ds:si], 0xFF

    cmp byte [es:di], 0xFF

    pop ax

    mov byte [ds:si], al

    pop ax

    mov byte [es:di], al

    mov ax, 0

    je check_a20__exit

    mov ax, 1

check_a20__exit:

    pop si

    pop di

    pop es

    pop ds

    ret

A20On:

    db "A20 is On        "

A20Off:

    db "A20 is Off       "

times 510-($-$$) db 0

db 0x55

db 0xaa

 

(完)

 

© 著作权归作者所有

共有 人打赏支持
放个屁
粉丝 123
博文 176
码字总数 285078
作品 0
日本
程序员
转帖:FLASH位宽为8、16、32时,CPU与外设之间地址线的连接方法

写在前面, 在调试qualcomm 平台上flash的时候因为没注意到这个接线的方式,走一很多弯路,, 转帖:FLASH位宽为8、16、32时,CPU与外设之间地址线的连接方法 FLASH连接CPU时,根据不同的数据...

echor ⋅ 2011/12/14 ⋅ 0

深度解析:全志A20双核处理器倍受国内外开源

作为领先的移动处理器供应商,全志科技单双四核处理器不仅被广泛应用于平板电脑、智能播放盒和安防等领域,还倍受OpenHW/CNX-Software等国内外开源社区的青睐,近期更是有多块基于A20的开源开...

bananapi ⋅ 2014/03/29 ⋅ 1

liunx之:wps for liunx的安装经验

首先是下载正确的安装包 WPS For Linux : 社区下载:http://community.wps.cn/download/ 社区最新包下载:http://wps-community.org/download.html 根据自己系统是32还是64位 正确选择安装包...

无信不立 ⋅ 2016/08/24 ⋅ 0

XV6 - bootsect.S

#include "asm.h" #include "memlayout.h" #include "mmu.h" .code16 .globl start start: cli # 关中断, 防止干扰开启A20, 和保证设置GDT的完整性 # 初始化寄存器 xorw %ax,%ax # 将ax清零,......

Pagination ⋅ 2014/06/12 ⋅ 0

oracle数据库查询数据库快照点id间隔

set pagesize 150; col instart_fmt format a30 col inst_name format a20 col db_name format a20 col snap_id for 999999999999 col snapdat format a30 col lvl for 999999999999 select ......

18620626259 ⋅ 04/02 ⋅ 0

ibatis3 因为ognl解析慢,导致性能下降

ibatis3的sql语句写在xml里,ibatis3使用了ognl解析器。 1:当sql里有多个时,大概有30个吧,明显感觉速度慢下 例子 update a a1=#{a1} a2=#{a2} a3=#{a3} a4=#{a4}...

坐定定 ⋅ 2010/11/01 ⋅ 2

手机字库(HTC)

字库,又称FLASH,为Flash ROM闪速只读存储器。 它以代码的形式装载了手机的基本程序和各种功能程序。至今字库这个名词概念混,很不清楚,到底字库是什么呢? 实际上我们可以这样区分,把它们...

晨曦之光 ⋅ 2012/03/01 ⋅ 0

手机字库(HTC)

字库,又称FLASH,为Flash ROM闪速只读存储器。 它以代码的形式装载了手机的基本程序和各种功能程序。至今字库这个名词概念混,很不清楚,到底字库是什么呢? 实际上我们可以这样区分,把它们...

长平狐 ⋅ 2013/01/06 ⋅ 0

手机字库(HTC)

字库,又称FLASH,为Flash ROM闪速只读存储器。 它以代码的形式装载了手机的基本程序和各种功能程序。至今字库这个名词概念混,很不清楚,到底字库是什么呢? 实际上我们可以这样区分,把它们...

鉴客 ⋅ 2012/03/09 ⋅ 0

oracle查看用户登录失败次数及详细信息

oracle查看用户登录失败次数及详细信息 一、 具体步骤 查看用户信息 查看默认PROFILE的策略 查看XYSOUL用户登录的失败次数 select lcount from user$ where name='DPM'; 下面开启审计,并查看...

18620626259 ⋅ 05/15 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

MySQL主从复制原理、半同步操作步骤及原理

1.1 企业Linux运维场景数据同步方案 1.1.1 文件级别的异机同步方案 1、scp/sftp/nc 命令可以实现远程数据同步。 2、搭建ftp/http/svn/nfs 服务器,然后在客户端上也可以把数据同步到服务器。...

xiaomin0322 ⋅ 19分钟前 ⋅ 0

Oracle10g 数据及文件迁移过程[原]

QL*Plus: Release 10.2.0.1.0 - Production on 星期三 5月 11 10:22:35 2011 Copyright (c) 1982, 2005, Oracle. All rights reserved. 连接到: Oracle Database 10g Enterprise Edition Re......

harrypotter ⋅ 25分钟前 ⋅ 0

nginx安装

1:安装工具包 wget、vim和gcc yum install -y wget yum install -y vim-enhanced yum install -y make cmake gcc gcc-c++ 2:下载nginx安装包 wget http://nginx.org/download/nginx-1......

壹丶贰 ⋅ 28分钟前 ⋅ 0

ideaVim安装及配置

1.安装插件 File-Settings-Plugins,Browse Repositories,输入ideavim,安装。 重启后,在Tools-Vim Emulator启用。 2.快捷键设置 ideaViim键与idea快捷键有冲突,可以在Settings-Other Se...

Funcy1122 ⋅ 32分钟前 ⋅ 0

MySQL中B+Tree索引原理

B+树索引是B+树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引。B+树中的B代表平衡(balance),而不是二叉(binary),因为B+树是从最早的平衡二叉树演化而来的。在讲B...

浮躁的码农 ⋅ 47分钟前 ⋅ 0

两道面试题,带你解析Java类加载机制

在许多Java面试中,我们经常会看到关于Java类加载机制的考察,例如下面这道题: class Grandpa{ static { System.out.println("爷爷在静态代码块"); }} cl...

1527 ⋅ 51分钟前 ⋅ 0

SpringCloud(Data Flow)

dataflow-server

赵-猛 ⋅ 今天 ⋅ 0

深入理解Java虚拟机

这本书我读到第8章,之后就是在读不下去了。 读到后面是一种痛苦的体验,太多的东西是不全面的,大量的专有名词是没有解释的,读到最后很多东西仅仅是一个侧面,所以我觉得,这本书不适合初学...

颖伙虫 ⋅ 今天 ⋅ 0

NanoPi NEO core/ Ubuntu16.04单网卡配置3个IP地址(2个静态,1个动态)

配置 root@NanoPi-NEO-Core:/etc/network# cat interfacesauto loiface lo inet loopbackallow-hotplug eth0iface eth0 inet static address 172.31.188.249 netmask 255.......

SamXIAO ⋅ 今天 ⋅ 0

三步为你的App集成LivePhoto功能

摘要:LivePhoto是iOS9新推出的一种拍照方式,类似于拍摄Gif图或录制视频片段生成图片。如果没有画面感,可以联想《哈利波特》霍格沃茨城堡的壁画,哈哈,很炫酷有木有,但坑爹的是只有iphone6S以...

壹峰 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部