HPA初步认识与分析 编程及撰文:Lintel Ring整理/输入 一、前言
早在06年,我就开始有着手写关于HPA保护程序的打算,在07年暑假的资料大收集以及和天风等兄弟讨论之后,基本对HPA的原理以及操作方式有了一定的了解.写好了HPA创建程序之后,由于出现了重大的BUG一直没有解决,所以这个HPA计划一直耽搁了很久.最近因为天风大哥的提起,才继续完成下去,在此,我对天风致以深深的歉意...感谢Ring的辛苦整理和输入 在开始HPA的分析之前,我们必须知道一些必知的知识。
1、什么是HPA?
HPA,即Host Protected Area (主机保护区域)或Hidden Protected Area(隐藏保护区域),下文简称HPA。
HPA概念出现在ATA/ATAPI-4标准中ATA-4.2001年第21周),全称为AT Attachment with Packet Interface Extension(ATA/ATAPI),是由ANSI下属机构T13与硬盘生产商协定的。
HPA是定义在硬盘上的保护区域,它存在于硬盘的高端LBA区域。使用硬盘ATA命令进行设置,在设置了HPA的硬盘上,在表面看来,在使用中没有任何不同,只是一个容量“变小”的硬盘。由于是在硬盘本身设置,所以硬盘中的容量信息改变,因此,在BIOS和操作系统等环境下,是看不到隐藏的区域。
实质上,HPA就是设置最大的LBA值,以达到保护的目的。
2、CPU控制下的外设大家庭
计算机发展到今天,外设已经五花八门,硬盘、软盘、光盘、U盘、声卡、网卡、SD卡、手柄等等。真是层出不穷,这样外设给我们带来了便利,但同时也带来了问题。比如 ,主板上的接口个数有限,怎样保证这些外设能够正常与主机通信?怎样保证CPU(处理器)能一个不漏地控制每一个外设?CPU如何控制?如何保证CPU不会误操作?CPU控制外设到什么样地程度?如何保证控制下的外设不会“打架”?这些都是初学者要问的问题。请各位听我慢慢道来。
首先,每一个外设都有一个控制器,这些控制器都是数字控制器,在控制器里面有“寄存器”,这是存储单元,这些东东跟内存单元的结构不一样,但作用跟内存单元一样,都能保存信息,这些寄存器各有作用,各有分类,比如硬盘,在硬盘上有保存保存磁头号,磁道号,扇区号等参数的寄存器,这些寄存器用来告诉硬盘本次操作硬盘要读写的是哪个盘面,哪个磁道哪个扇区的数据,根据寄存器的作用,分为两类,分别叫控制寄存器和状态寄存器。控制寄存器的用来告诉外设,CPU让它干什么活,以及干活时需要的参数。状态寄存器用于外设向CPU报告外设目前的状态。比如目前是否在忙,在干什么活,在干活的过程发生了什么错误,状态寄存器不能主动告诉CPU外设的当前状态,只能被动地由CPU来读取信息,CPU把外设当前状态寄存器的信息读出来,就能够知道外设当前的工作状态。当然,外设也有主动报告CPU的能力。就是通过中断的方式,在此,我就省略了。
寄存器有的是只写,有的是只读,也有可读可写的。一般而言,控制寄存器的是只写活可读可写的,状态寄存器一般也只是只读的。
那么,CPU是如何一个不漏地控制多个外设呢?在80X86计算机中,外个外设和CPU都挂在一组系统总线上,每个外设分配一个地址,CPU拿某一个地址去访问某一个寄存器时,只有该寄存器发生回应,或接收总线上的数据,或把自己的数据送到总线上。同一个外设的寄存器或其他外设的寄存器都不会发生回应。这样,CPU用不同的地址就可以访问不同的寄存器,也就可以一个不漏地控制外设了。在访问某个寄存器时,别的寄存寄存器不会发生动作,所以,外设之间不会“打架”,不会互相干扰。同样的,CPU
访问内存时,其地址不是外设的寄存器地址。所有的外设不会有回应,所以CPU不会误操作外设。
根据外设的基本结构,你是否已经知道CPU是如何控制外设了。显然,CPU控制外设的方法无非就是读写外设的寄存器。比如,CPU要从硬盘读文件,那么CPU只需要把磁头号,磁道号,扇区号要读的数据量等参数写入硬盘对应的寄存器,然后向硬盘的命令寄存器填写一个开始命令,硬盘控制器就在接到命令控制磁头移动到对应的磁道,对准扇区,读取数据。送到硬盘的数据寄存器,至于磁头目前在什么位置,怎样移动,顺时针移动还是逆时针移动,以多快大速度移动,有多大的加速度达到目的扇区等等。这些都不是CPU所能控制的,也就是说CPU只能告诉外设要干什么活以及干活过程所需要的参数,
至于外设是怎么干活,如硬盘的磁头怎么移动这些事是CPU所不能控制的。
主板上的接口个数有限,怎样保证各种外设能连接主板并和CPU通信呢?答案是标准接口,如IDE接口、串口、USB、并口、PS/2、PCI接口等等。至于你拿的是USB接口的打印机还是游戏手柄还是USB鼠标还是别的什么东东,主板就管不了了。
如何判断外设是否正常,是否存在问题呢?我们经常说计算机BIOS进行自检,即检查计算机连接什么外设,这些外设是否正常工作,如果某个外设出现故障,BIOS能根据不同的故障发出不同的警报声。BIOS也是一段程序,它凭什么能做到上面所说的事情呢?原来,工程师在设计的时候,就考虑了自检功能。比如鼠标就设计了一个查询/应答命令。BIOS检查计算机是否存在鼠标时,只要向鼠标发一个查询命令,送到鼠标的命令寄存器。如果计算机连接有鼠标,那么鼠标就会进行回应,然后BIOS读状态寄存器。如果读出的值时0xff或0x00,则表示鼠标不存在或有故障。
现在知道了吧?CPU就是通过系统总线的I/O方式操作外设的。
二、硬盘操作必须知道的
通过上一部分,我们已经知道CPU时如何操作外设了。现在以下的时必须知道的。
1、ATA简介
硬盘接口IDE(Integrated Drive Electronies)也称AT总线接口,时当前硬盘常见的一种接口。(注意,S-ATA同样属于ATA的行列)。
IDE的概念最早由Texan 和 Compaq公司提出,目的是把硬盘控制器嵌入到驱动器中。
1988年10月,ANSI中的X3T9.2(即T13)工作组的一个委员会开始讨论IDE的有关问题,1993年2月发表了该标准的3.1版本。使其成为了一个正式的ANSI标准,并赋予了新名称—ATA(AT Attachment), 从概念上说,ATA与IDE具有相同的含义。
随着硬盘制作工艺的提高,ATA标准也在不断改进,目前最新的版本是ATA/ATAPI-8。
2.硬盘的ATA命令
IDE控制器中有2组寄存器;命令寄存器和控制寄存器。命令寄存器被用来接受命令和传送数据;控制寄存器组用作磁盘控制。这2个寄存器组CS1FX/和CS3FX/信号区分。CS1FX/的地址范围是1F0H~1F7H,CS3FX/的地址范围是3F0H~3F7H,具体如表2所示。
目前,许多计算机配置了2个IDE接口,对于第2个IDE接口,这2个信号的地址范围分别是170H~177H和370H~377H。
在ATA标准中以寄存器方式传送数据、命令和地址。这些寄存器除数据寄存器为16位以外,其它寄存器均为8位。PC机分配给寄存器的地址有二组,一组为1F0H~1F8H,另一组为170H~178H。通常ATA适配器采用IRQ14中断。
对于新的SATA的I/O地址,如果BIOS中提供了IDE模式的映射,那么其地址与IDE1口地址相同.
对于独立的SATA/RAID控制器,比如VIA 8237R 其地址可能为100H
⑴数据寄存器(1F0H R/W):这是一个16位PIO数据寄存器,用于对扇区的读、写和格式化操作。CPU通过该寄存器向硬盘控制寄存器写入或从硬盘控制寄存器读出扇区缓冲区的数据,如使用“REP OUTSW”或“REP INSW”指令,通过数据寄存器也可以进行DMA方式的数据传输。
错误寄存器(1F1H R):该寄存器是1个8位的寄存器,它反映控制寄存器在诊断方式或操作方式下的错误原因。在不同方式下有不同的意义。
①诊断方式:硬盘控制器在加电、复位或执行驱动器诊断命令以后的工作方式。此时驱动器包含诊断码,该代码反映了诊断后的结果,如表所示。
②操作方式:硬盘控制器执行除诊断命令以外的所有命令后进入该方式,如果状态寄存器的ERR=1,则该寄存器包含命令执行后的错误代码,错误寄存器的内容如表所示。
⑵特性寄存器(1F1H W):一般情况下不使用该寄存器,根据ATA标准它被用来设置接口的某些特征。
⑶扇区数寄存器(1F2 R/W):它记录读、写命令的扇区数。当多扇区传输时,每完成1个扇区操作,该寄存器自动减1,直至为0,如果初值为0,则表示256。如果有错误发生,该寄存器包含已经操作成功的扇区数。
⑷扇区号寄存器(1F3H R/W):它记录读、写和校验命令指定的起始扇区号。如果驱动器使用逻辑块寻址(LBA,logical lock address)方式,该寄存器记录逻辑扇区号的0字节。
⑸柱面号寄存器:(1F4H 1F5H R/W):它记录读、写、校验、寻址和格式化命令指定的柱面号,ATA标准允许65536柱面,但早期的IDE控制器中只允许1024个柱面。低8位在1F4H寄存器中,高8位在1F5H寄存器中。如果是LBA寻址方式,这2个寄存器包含起始扇区的1和2字节。
⑹驱动器/磁头寄存器(1F6H R/W):它记录读、写、校验、寻址和格式化命令指定的驱动器号、磁头号和寻址方式。其定义如表所示。
⑺状态寄存器(1F7H R):它放映硬盘驱动器执行命令后的状态,该寄存器要清除中断请求信号,如果要避免清除中断,可以读辅助状态寄存器3F6H,这2个寄存器的内容完全相同,其定义如表所示。
命令寄存器(1F7H W):该寄存器接收处理器输出的HDC命令,命令格式和含义如表7所示。其中12种是强制性的(M),其它是选择性的(O)。有些命令有2个操作码,后1个是早期操作码,有的驱动器上仍在使用,如CON-NER驱动器。
辅助状态寄存器(3F6H R):它包含与状态寄存器相同的内容,但读该寄存时不会清除中断请求信号。
硬盘控制寄存器(3F6H W):该寄存器定义如表所示。
驱动地址寄存器(3F7H R):该寄存器包含命令执行后的某些信息,它与软盘驱动器共享,D7位是软盘驱动器的更换磁盘位。寄存器的所有位都是负逻辑。其定义如表所示。
关于SATA口的定义I/O地址,还有待测试证明验证
硬盘的编址方式
ATA标准允许65536个柱面,每个扇区512B。扇区寻址有2种方式:物理寻址方式和逻辑寻址方式。
物理寻址方式(CHS方式):用柱面、磁头和扇区表示1个特定的扇区。起始扇区是0磁道、0磁头、1扇区,接下来是2扇区,知道EOF扇区,接下来是同一柱面1头、1扇区……
逻辑地址方式(LBA方式):对于参数寄存器来说,其柱面值最大为65536,磁头数最大为16,扇区最大为255。因此参数寄存器可支持的最大磁盘容量为65536*16*255=13.69GB。而BIOS所能支持的最大值分别为1024、255、63,支持的最大容量为1024*255*63=8.4GB。
IDE接口对磁盘的容量限制是由BIOS和参数寄存器二者结合产生的。因此柱面、磁头和扇区数被限制在1024、16、63,最大只能支持1024*16*63=528MB。采用逻辑块方式寻址可以突破528MB的容量限制。该方式以28位的宽度可寻址到2^28=268435455块扇区,容量达137GB。如图10所示。
逻辑块地址与物理地址的关系为:LBA地址=(柱面号*磁头数+磁头号)*扇区数+扇区数-1
采用LBA方式寻址,没有磁头和磁道的转换操作,在访问连扇区时,操作速度比物理地址方式要快。
LBA寻址方式虽然需要BIOS做些修改,但它与Microsoft和IBM的INT13功能扩展规范是兼容的。为了能够用LBA方式存取大于528MB的硬盘,IDE提供了二种方式供主机系统选择,这二种方式均在CMOS中设置。
第1种方式称为自动配置,这主要是向那些不用BIOS存取磁盘的操作系统(如Netware和UNIX)提供的。它运用标准DPT(磁盘参数表)从IDE驱动器上获取有关驱动器容量的信息传向操作系统。
第2种方式是为了DOS和WINDOWS设计的,称为自动转换。在CMOS设置中选择这种类型、主机加电初始化时,BIOS会创建1张EDPT(增强型磁盘参数表)。EDPT表包含2组驱动器参数:一组来自Identify命令获取的驱动器信息;另一组则是BIOS给操作系统的,这些信息不是驱动器返回信息的简单拷贝,它还要做些转换。根据Identify命令返回的信息,BIOS将实际的CHS转换成IDE的CHS或者转换成LBA的CHS,能够支持的最大磁盘容量为8.4GB,而且BIOS改动最小。
3.编程环境下的硬盘I/O操作
三、实践硬盘I/O操作
1.MBR代码的操作
2.编写HPA Boot Loader
本文参考以下资料:
<ATA接口技术>
<Information Technology -AT Attachment with Packet Interface Extension > (ATA/ATAPI-4)
<BIOS研发技术剖析(基本概论与设置)>
<“El Torito” Bootable CD-ROM Format Specification Version 1.0>
<FAT32文件系统程序和说明>
<自己动手写操作系统>
转载请注明原出处,谢谢合作.
如果本文有遗漏,错误.请跟贴说明或者请联系我:
lintel77@qq.com
(未完,整理中)
[ 本帖最后由 lintel 于 2008-8-2 15:05 编辑 ] |