开启A20线

在查看或编写操作系统内核时一定会遇到A20线这个问题。本人对此一直都是似懂非懂的,查了些资料,决定弄明白于是有了这篇文章。其中前一部分是翻译一篇外国博文,但光有这篇文章依旧不能清楚地说明A20线的问题。所以将另一些资料也放在一起,这样看的人应该会明白A20线的问题了。

A20 gate

开启A20线(翻译)

原文地址:http://kernelx.weebly.com/a20-address-line.html

When IBM PC AT System was introduced ,the new Intel 286 processor was not compatible with the old x86 processor. The older x86 micro-processors(Intel 8086) had address bus of 20bits which would total and give access up to 1megabyte of memory. The Intel 386 and above had address bus up to 32 bits allowing 4 Gigabytes of memory. But the old 8086 processors did not have such a big address bus. To keep in compatible with the older processors and solve the problem the Intel introduced a logical OR gate at the 20 bit of the address bus which could be enabled a or disabled. So, to keep in compatible with the older processors and programs the A20 is disabled at the startup.

当ibm pc at系统被制造出来时,新的286处理器以及以后版本和旧有x86处理器并不兼容。旧的X86处理器(Intel 8086)有20位地址总线,这样可以访问最高1M内存。而386和以后版本有32地址总线,这样可以访问最高4G的内存。但是旧的8086处理器没有这么大的地址总线。为了保持兼容性Intel在地址线的第20位上制造了一个逻辑OR门,以便可以开启或关闭超过20位的地址总线。这样,为了兼容旧的处理器,在机器开启时A20被禁止的。

NOTE:BIOS
actually enables the A20 for counting and testing the available
memory and then disables it before booting again to keep in
compatible with older processors.

注意:BIOS在计算和测试可用内存时实际上是开启了A20线的,然后在启动系统之前又关闭了它以保持兼容旧的处理器。

The
A20 gate is an electronic OR gate which can be disabled and enabled
and placed at the 20th bit of the address bus. It is connected
through a P21 line of the keyboard controller which made it possible
for the keyboard controller to enable or disable the A20 Gate.

A20线是一个OR逻辑电路门,被放置在第20位的地址总线上,而且可以开启或关闭。这是通过键盘控制器的P21线来完成的,这样,通过键盘控制器可以开启开关闭A20线。

In
the current generations, there is a need to have memory lot more than
just 1MB. The applications, games,etc need a lot of memory. Even a
operating system kernel might eat up the whole 1MB. So it is
something like impossible to run modern programs in 1MB of memory.
Looks like the A20 is an important feature for good functional of the
operating system.

在当前情况下,多于1M的内存是必须的。各种应用,游戏或者其他程序等都需要更多的内存。甚至一个操作系统的内核都可能会用尽整整1M的内存。所以在1M内存以内运行一个当下的程序有点怪。看起来对于一个功能良好的操作系统A20线就象是一个重要的特性。

To
enable the A20 gate there are 3 methods or you can skip this step by
using the high memory managers such as HIMEM.sys or using bootloaders
such as GRUB(GRUB will set up you up with protected mode with A20
enabled)

开启A20线有三种方法。或者你可以通过使用象HIMEM.sys或者象GRUB这样的bootloaders来跳过这些步骤(GRUB会设置你的机器开启A20线并进入保护模式)。

The
3 methods for enabling the A20 Gate are

开启A20线的三种方法:

1.
Keyboard Controller

1、通过键盘控制器

2.
BIOS Function

2、调用BIOS功能

3.
System Port

使用系统端口

===============================================================================================

Keyboard
Controller:

键盘控制器:

This
is the most common method of enabling A20 Gate. The keyboard
micro-controller provides functions for disabling and enabling A20.
Before enabling A20 we need to disable interrupts to prevent our
kernel from getting messed up. The port 0x64 is used to send the
command byte.

这是开启A20线通常的作法。键盘的微控制器提供了一个关闭或开启A20线的功能。在开启A20线之前需要关闭中断以防止我们的内核陷入混乱。命令字节是通过端口0x64来发送的。

Command
Bytes and ports

命令字和端口

0xDD
Enable A20 Address Line

0xDD可以开启A20线

0xDF
Disable A20 Address Line

0xDF关闭A20线

0x64
Port of the 8042 micro-controller for sending commands

8042微控制器的0x64端口用来发送命令

Using
the keyboard to enable A20:

使用键盘来开启A20线:

EnableA20_KB:

cli    ;Disables interrupts #关中断

push ax    ;Saves AX #保存AX寄存器

mov al, 0xdd ;Look at the command list #开启命令

out 0x64, al ;Command Register #将命令发送到0x64端口

pop ax    ;Restore's AX #恢复AX寄存器

sti    ;Enables interrupts #开中断

ret

Using the BIOS functions to enable the A20 Gate:

使用BIOS功能开启A20线:

The
INT 15 2400,2401,2402 are used to disable,enable,return status of the
A20 Gate respectively.

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

Return
status of the commands 2400 and 2401(Disabling,Enabling)

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

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

AH
= 0 #

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

AH
= status (01=keyboard controller is in secure mode, 0x86=function not
supported)

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

Return
Status of the command 2402

2042命令返回状态

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

AH
= status (01: keyboard controller is in secure mode; 0x86: function
not supported)

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

AL
= current state (00: disabled, 01: enabled)

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

CX
= set to 0xffff is keyboard controller is no ready in 0xc000 read
attempts

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

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

Disabling
the A20

关闭A20线

push ax

mov ax, 0x2400

int 0x15

pop ax

Enabling the A20

开启A20线:

push ax

mov ax, 0x2401

int 0x15

pop ax

Checking A20

检查A20线

push ax

push cx

mov ax, 0x2402

int 0x15

pop cx

pop ax

=====================================================================================

Using
System Port 0x92

使用系统0x92端口

This
method is quite dangerous because it may cause conflicts with some
hardware devices forcing the system to halt.

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

Port
0x92 Bits

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关闭,其他值为开启。

Code
to enable A20 through port 0x92

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

push ax

mov al, 

out 0x92, al

pop ax

注:通过以上可以看出,0x92端口由于可能存在的风险,所以一般不使用。而通过BIOS功能来开启或关闭A20线会影响多个标志位,所以实际系统中多使用键盘控制器的方式来开启或关闭A20线。而实际工作的代码要比上面的例子复杂些,因为还要考虑到键盘缓冲区中是否有内容,键盘控制器是否已准备好等等情况。

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

所以,激活A20地址线的流程为:

1.禁止中断;

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

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

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

5.向P2写入数据,将OR2置1。

下面是JOS系统和LINUX0.11中使用的开启A20线代码:

JOS中开启A20线的代码

seta20.:

inb $0x64,%al #等待直到键盘不忙 取0x64端口状态值

testb $0x2,%al #测试第2位是否为0

jnz seta20. #测试指令,与运算。判断第二位是否为0,如为0,则代表8042是空的

movb $0xd1,%al # 0xd1 -> port 0x64 将0xd1放在al中

outb %al,$0x64 #将0xd1发送到0x64端口,D1的意思是向8042端口的P2写数据,这样,下面的命令才能有效

seta20.:

inb $0x64,%al # Wait for not busy 取0x64端口状态值

testb $0x2,%al #

jnz seta20.

movb $0xdf,%al # 0xdf -> port 0x60 将0xdf放在al中

outb %al,$0x60    #将0xdf发送到0x60端口,DF为11011111,A20位置1,开通A20线

LINUX0.11中开启A20线代码:

call    empty_8042

mov    al,#0xD1    ! command write

out    #0x64,al

call    empty_8042

mov    al,#0xDF    ! A20 on

out    #0x60,al

call    empty_8042

empty_8042:

.word    0x00eb,0x00eb

in    al,#0x64    !  status port

test    al,#    ! is input buffer full?

jnz    empty_8042    ! yes - loop

ret

开启A20线(部分译)的更多相关文章

  1. 实模式切换到保护模式,为什么要开启A20地址线(系统升级产生的兼容性问题)

    [-1]写在前面: 以下部分内容总结于 http://blog.csdn.net/ruyanhai/article/details/7181842 complementary: 兼容性是指运行在前期C ...

  2. node开启 https线上服务你不会吗?

    var https=require("https");//https服务var fs = require("fs")var express = require( ...

  3. 保护模式下pmtest1.asm的理解

    整个代码对应内存线性地址分为四段,[gdt] [code32] [video32] [code16] 代码先在实模式[code16]下运行,code16中的cs就是系统分配的该程序物理地址的基址. 编 ...

  4. A20地址线问题

    [0]README text description from Zhaojiong's perfect analysis of Linux kernel . [1]A20地址线问题(干货来了) 198 ...

  5. A20地址线科普【转载】

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

  6. Android耳机线控具体解释,蓝牙耳机button监听(仿酷狗线控效果)

    转载请注明出处:http://blog.csdn.net/fengyuzhengfan/article/details/46461253 当耳机的媒体按键被单击后.Android系统会发出一个广播.该 ...

  7. Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量

    Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量 一丶线程的理论知识 什么是线程:    1.线程是一堆指令,是操作系统调度 ...

  8. ASM:《X86汇编语言-从实模式到保护模式》第17章:保护模式下中断和异常的处理与抢占式多任务

    ★PART1:中断和异常概述 1. 中断(Interrupt) 中断包括硬件中断和软中断.硬件中断是由外围设备发出的中断信号引发的,以请求处理器提供服务.当I/O接口发出中断请求的时候,会被像8259 ...

  9. CPU与内存的那些事

    下面是网上看到的一些关于内存和CPU方面的一些很不错的文章. 整理如下: 转: CPU的等待有多久? 原文标题:What Your Computer Does While You Wait 原文地址: ...

随机推荐

  1. pandas.DataFrame排除特定行

    使用Python进行数据分析时,经常要使用到的一个数据结构就是pandas的DataFrame 如果我们想要像Excel的筛选那样,只要其中的一行或某几行,可以使用isin()方法,将需要的行的值以列 ...

  2. j2ee log4j集中式日志解决方案logpool-v0.2

    下一个小版本会进行清理. war包下载地址 http://pan.baidu.com/s/1nvGmORn

  3. 为什么我会认为SAP是世界上最好用最牛逼的ERP系统,没有之一?

    为什么我认为SAP是世界上最好用最牛逼的ERP系统,没有之一?玩过QAD.Tiptop.用友等产品,深深觉得SAP是贵的有道理! 一套好的ERP系统,不仅能够最大程度承接适配企业的管理和业务流程,在技 ...

  4. 解析Jquery取得iframe中元素的几种方法

    iframe在复合文档中经常用到,利用jquery操作iframe可以大幅提高效率,这里收集一些基本操作,需要的朋友可以参考下   DOM方法:父窗口操作IFRAME:window.frames[&q ...

  5. asp.net mvc 之旅 —— 第六站 ActionFilter的应用及源码分析

    这篇文章我们开始看一下ActionFilter,从名字上其实就大概知道ActionFilter就是Action上的Filter,对吧,那么Action上的Filter大概有几个呢??? 这个问题其实还 ...

  6. 从零自学Hadoop系列索引

    本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,SourceLink 从零自学Hadoop(01):认识Hadoop ...

  7. php-cgi not found

    错误描述 用PHPStorm运行PHP脚本的时候浏览器提示"502 Bad Gateway",PHPStorm提示"php-cgi not found". 系统 ...

  8. 6-3 bash脚本编程之五 字符串测试及for循环

    1. 字符测试 ==:等号两边要有空格,否则会被认为是赋值. !=:  测试是否相等,记住如果不等为真,等为假. -n string: 测试指定字符串是否为空,空位真,不空为假. -s string: ...

  9. win 7下建立FTP

    1.安装FTP服务 鼠标桌面右击个性化-卸载程序-打开或关闭windows功能 2.在IIS控制面板里添加FTP站点 下一步 下一步 鼠标右击 下一步 下一步 3.配置ftp站点 4.测试站点是否正常 ...

  10. 异步HTTPHandler的实现

    使用APM的方式实现 using System; using System.Web; using System.Threading; class HelloWorldAsyncHandler : IH ...