相关服务

  • 《现代电子技术》2006年第16期摘录:万鸿俊等:DOS下PCI卡内存

如发现有乱码,请点击下面链接浏览原文
正文摘录:

万鸿俊等:DOS下PCI卡内存映射空间的访问方法大小、段属性等。把选择子赋值给一个段寄存器在保护模式中实际上是给段寄存器装载了对应的描述符,这个段的特性由描述符决定。接下来用描述符指定的基地址加上给定的偏移量就得到了线性地址,这就是分段管理机制。分页管理机制并不是保护模式必须的,如果禁用。线性地址就直接等于物理地址。这就是虚拟地址到物理地址的转换过程。。。圜◇西岭园◇茵图1保护模式下的地址转换机制在D()S实模式下.寻址方式是大家比较熟悉的段基址*16+偏移址。但是实际上这种地址生成机制和保护模式在原理上是一致的。只是实模式下系统将段描述符的界限值自动赋值为0xFFFF,将给出的段寄存器的基地址*16送入段描述符的基地址值.这样就形成了实模式下每个段大小只能为64k并且可访问最大地址为1M的“假象”口j。3PCI内存映射局部空间的访问DOS操作系统只能工作于处理器的实模式,因此一般情况下,运行于DOS操作系统的软件最多只能访问】M以内的内存空间,其余的物理内存对于他来说都是不可见的。另一方面,PCI设备的内存空间基地址是由系统自动配置的,并且基地址通常会被分配到1M以上的内存空间(如0xFF9F0000)。这样,在DOS的实模式下就无法访问到这一段内存,从而无法操作PCI板卡。下面介绍解决这一问题的2种方法。3.10x15B10S中断调用中断号为0x15的BIOS中断调用实现了存储器块移动的功能。首先在存储器中分配保护模式下使用的GDT表所需要的内存空间,定义传送源段描述符和目标段描述符,然后把GDT表的地址装入寄存器对ES:Sl中,传送的字计数装入CX寄存器,再将块移动功能调用号0x87装入AH寄存器,最后执行0x15中断完成内存数据块移动.从而实现1M以上内存的访问。表1GDT表结果OOH08HlOH18H20H28H(描述符0)空描述符(描述符1)GD'I’R的基地址和大小(描述符2)源段描述符(描述符3)目标段描述符(描述符4)代码段描述符(描述符5)栈段描述符如表1所示为功能调用所需要的GDT表结构.其中描述符0.1,4,5可以都设置为0,描述符2和描述符3分别设置传送源段和目标段的地址信息。且数据段的低8位44属性必须设置为93H。0x15中断调用的块移动功能实际上也是建立在保护模式传送机制上的,每传送一次数据都需要完成实模式一进入保护模式传送数据一返回实模式这样一个流程,因此在效率上比较低。但是这种方法在微处理器的实模式和虚拟8086模式下都可以运行。因此即使系统装载了EMM386.exe或是在Windows98下的MS—DOS窗口,此方法都是可行的。下面给出一段例程,用此方法实现了在任意2个32位线性地址之间传递数据块。程序采用TC2.0编译,在Pentium4处理器平台运行成功。typedefstruetDescriptorstruct{unsignedintsize;unsignedintbase—low—word;unsignedcharbase—mid~byte;unsignedcharattrl;unsignedcharattr2;unsignedcharbase—high—byte;}Descriptor;typedefstructGDTStruct{DescriptorBlankDsc;DescriptorGDTDse:DescriptorSrcDsc;DeseriptorDstDse;DescriptorBiosCS;DescriptorBiosSS;}GDT;//描述符结构//GDT表结构GDTMoveGDT={{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0x93,0x40,0),{0,0,0,0x93,0x40,0},{0.0,0,0,0,0},{0,0,0,0,0,0}};voidSetSrcAddr((;DT*mcb,unsignedlongaddr,unsignedsize)//设置源段描述符{mcb一>SreDse.baseIowword—addr&0x0000ffff;mcb一>SrcD8c.basemidbyte=addr>>16;meb一>SrcDse.size—size;mcb一>SrcDsc.basehighbyte=addr>>24;}voidSetDstAddr((;DT*meb,unsignedlongaddr,unsignedsize)//设置目标段描述符{mcb一>DstD812..baselowword—addr&0x0000ffff;mcb一>DstDse.basemidbyte=addr>>16;mcb一>DstDsc.size—size;mcb一>DstDsc.basehighbyte=addr>>24;)voidMoveData(GDTmcb,unsignedsize)//Int15H传送数据{structREGPACKreg;reg.res—FPSEG(&hieb);reg.rsi—FPOFF(&meb);reg一一cx=size>>1;reg.rax一0x8700;intr(0x15.&reg);}voidmemmove(unsignedlongSOUaddr,unsignedlongdesad—dr,unsignedintnum)//数据移动函数{SetSrcAddr(&MoveGDT,SOUaddr,hum);SetDstAddr(&MoveGDT.desaddr,num):MoveData(MoveGDT,num);}3.2DOS程序中嵌入保护模式程序段基于第2节的讨论,由于实模式和保护模式在内存管理机制上的共性,可以在D()S实模式下先自行进入保护模式给一个段寄存器(比如FS)装载自定义的段描述符,(下转第48页)

阅读此文(图):   点击此处在线翻阅