早的PC总线是IBM公司1981年在PC/XT 电脑采用的系统总线,它基于8bit的8088 处理器,被称为PC总线或者PC/XT总线。在1984年的时候,IBM 推出基于16-bit Intel 80286处理器的PC/AT 电脑,系统总线也相应地扩展为16bit,并被称呼为PC/AT 总线。而为了开发与IBM PC 兼容的外围设备,行业内便逐渐确立了以IBM PC 总线规范为基础的ISA(工业标准架构:Industry Standard Architecture )总线。
ISA总线又称AT总线,是在PC/AT微机上所配备的扩展系统总线。ISA 是8/16bit 的系统总线,传输速率仅为8MB/s ,但允许多个CPU 共享系统资源。由于兼容性好,它在上个世纪80年代是广泛采用的系统总线,不过它的弱点也是显而易见的,比如传输速率过低、CPU占用率高、占用硬件中断资源等。后来在PC‘98 规范中,就开始放弃了ISA 总线,而Intel 从i810 芯片组开始,也不再提供对ISA 接口的支持。
随着科技的高速发展,相比PCI总线,ISA在速度以及功能上以及相形见绌。这时我们只需重新编写ISA设备的驱动程序就可使设备在Windows/Nt操作系统下正常工作。开发的驱动程序是Win32 Drivers Mode(WDM)类型,使用的开发工具是微软提供的Device Driver Kit(DDK)和Vc++6.0,在进行驱动程序的调试时使用Numega公司的SoftIce产品。
(1)ISA总线与PCI总线的比较
ISA总线
ISA总线接口由于I/O速度较慢,随着上世纪90年代初PCI总线技术的出现,很快被淘汰了。目前在市面上基本上看不到有ISA总线类型的网卡。不过近期出现一种复古现象,就是在一些品牌的的i865系列芯片组主板中居然又提供了几条ISA插槽,真是令人费解!
普通的总线是ISA总线,即工业标准结构总线。16位ISA总线频率为8MHz左右。它的应用范围很广,几乎所有的主板都保留了ISA总线的扩展槽。
PCI总线
PCI是Intel公司开发的一套局部总线系统,它支持32位或64位的总线宽度,频率通常是33MHz。目前快的PCI2.0总线速度是66MHz。PCI总线允许十个接插件,同时它还支持即插即用。是目前主流的一种接口类型。因为它的I/O速度远比ISA总线型的卡快(ISA仅为33MB/s,而目前的PCI 2.2标准32位的PCI接口数据传输速度可达133MB/s),所以在这种总线技术出现后很快就替代了原来老式的ISA总线。PCI是Intel公司开发的一套局部总线系统,它支持32位或64位的总线宽度,频率通常是33MHz。目前快的PCI2.0总线速度是86MHz。
目前主流的PCI规范有PCI2.0、PCI2.1和PCI2.2三种,PC机上用的32位PCI网卡,三种接口规范的卡外观基本上差不多(主板上的PCI插槽也一样)。服务器上用的64位PCI网卡外观就与32位的有较大差别,主要体现在金手指的长度较长。
(2)ISA设备和PCI设备的Windows驱动程序的不同点
①ISA设备与PCI设备驱动程序获得硬件资源途径不同
一个ISA设备驱动程序的资源是固定不变的,它是通过。inf文件的[logconfig]节来配置的。如下面的例子:
[Xxx.LogConfig]
IOConfig=220-22f
IRQConfig=6
.inf中此节说明此硬件资源的I/O地址范围是220H到22FH,IRQ为6。一个PCI设备驱动程序的资源是操作系统自动分配的,它是通过设备ID号和厂商ID号获得设备的物理位置:总线号、器件号和功能号,并利用它们寻址PCI配置空间,接着从配置空间获得硬件资源,其中包括:中断号、端口地址等。
②ISA设备与PCI设备驱动程序对中断处理的不同
一个ISA设备驱动程序的中断模式可以是LevelSensitive也可以是Latched,而且中断向量是否与其它设备共享都可以。但是一个PCI设备驱动程序的中断模式必须是LevelSensitive,而且中断向量必须是共享的。
③ISA设备与PCI设备驱动程序安装时需要编写的。inf文件不同
对于ISA设备,在安装时。inf文件必须有[logconfig]节,而对于PCI设备,在安装时。inf文件必须有[Manufacturer]节,来指明设备ID号和厂商ID号,以便使硬件获取系统资源。如:
[Manufacturer]
%PLX% = PLX.Mfg
[PLX.Mfg]
"PCI 9052RDK-860 Board" =DDInstall_9052,PCI\VEN_10b5&DEV_9050
其设备ID号为9050H,厂商ID号为10B5H。
(三)驱动程序的实现
通过上面的比较,我们知道只要对原有的ISA设备的驱动程序的获取资源部分作一定的改变,并在安装时对inf文件进行必要的修改就可以完成PCI模式的驱动程序。
以下示例仅供参考。
NTSTATUS StartDevice(PDEVICE_OBJECT fdo,
PCM_PARTIAL_RESOURCE_LIST ResourceListRaw,
PCM_PARTIAL_RESOURCE_LIST ResourceListTranslated)
{
U32 i;
NTSTATUS status;
KIRQL irql; // interrupt level
KINTERRUPT_MODE mode; // interrupt mode
KAFFINITY affinity; // processor affinity for interrupt
PDEVICE_EXTENSION dx=(PDEVICE_EXTENSION)fdo->DeviceExtension;
PCI_COMMON_CONFIG pciRegs;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceRaw;
PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceTranslated;
ResourceRaw = ResourceListRaw->PartialDescriptors;
ResourceTranslated = ResourceListTranslated->PartialDescriptors;
// Read PCI Config Register
PciConfigRegisterBufferRead(
fdo,
&pciRegs,
0,
sizeof(pciRegs)
);
for (i = 0; i < ResourceListTranslated->Count;++i,++ResourceTranslated++ResourceRaw)
{
switch (ResourceTranslated->Type)
{
case CmResourceTypePort:
dx->PortStartAddress = ResourceTranslated->u.Port.Start;
dx->PortLength = ResourceTranslated->u.Port.Length;
dx->PortNeedsMapping = (ResourceTranslated->Flags&CM_RESOURCE_PORT_IO)==0;
break;
case CmResourceTypeInterrupt:
dx->InterruptIrql = (KIRQL)ResourceTranslated->u.Interrupt.Level;
dx->InterruptVector = ResourceTranslated->u.Interrupt.Vector; dx->
InterruptAffinity = ResourceTranslated->u.Interrupt.Affinity;
dx->InterruptMode = LevelSensitive;
dx->InterruptConnected = false;
break;
case CmResourceTypeNull:
case CmResourceTypeDma:
case CmResourceTypeDeviceSpecific:
case CmResourceTypeBusNumber:
// NonArbitrated & ConfigData are currently #defined as the same number
case CmResourceTypeConfigData:
case CmResourceTypeDevicePrivate:
case CmResourceTypePcCardConfig:
case CmResourceTypeMfCardConfig:
//加入自己的代码
break;
default:
break;
}
}
/* Device has been completely initialized and is ready to run. */
// Get the Vendor and Device ID
status = PciConfigRegisterBufferRead(
fdo,
&i,
0,
sizeof(U32)
);
if (!NT_SUCCESS(status))
{
dx->Device.VendorId = 0xFFFF;
dx->Device.DeviceId = 0xFFFF;
}
else
{
// Record the Vendor and Device ID */
dx->Device.VendorId = i & 0x0000FFFF;
dx->Device.DeviceId = i 》 16;
}
// Get the bus number and the slot number
status = GetBusSlotNumber(
dx->pPhysicalDeviceObject,
dx
);
if (!NT_SUCCESS(status))
{
return status;
}
return STATUS_SUCCESS;
}
共享中断向量只需将IoConnectInterrupt函数的第九个参数值置为TRUE就可以。
实践证明以上方法是可行的。
共享中断向量只需将IoConnectInterrupt函数的第九个参数值置为TRUE就可以。
实践证明以上方法是可行的。
免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。