dos下枚举 pci设备.docx
- 文档编号:11782253
- 上传时间:2023-04-01
- 格式:DOCX
- 页数:17
- 大小:21.07KB
dos下枚举 pci设备.docx
《dos下枚举 pci设备.docx》由会员分享,可在线阅读,更多相关《dos下枚举 pci设备.docx(17页珍藏版)》请在冰豆网上搜索。
dos下枚举pci设备
dos下枚举pci设备
一、PCI配置空间
PCI设备有三个空间——内存地址空间、IO地址空间和配置空间。
由于PCI支持即插即用,所以PCI设备不是占用固定的内存地址空间或I/O地址空间,而是可以由操作系统决定其映射的基址。
怎么配置呢?
这就是配置空间的作用。
DW|Byte3|Byte2|Byte1|Byte0|Addr
---+---------------------------------------------------------+-----
0| DeviceID | VendorID | 00
---+---------------------------------------------------------+-----
1| Status | Command | 04
---+---------------------------------------------------------+-----
2| ClassCode | RevisionID | 08
---+---------------------------------------------------------+-----
3| BIST |HeaderType|LatencyTimer|CacheLine| 0C
---+---------------------------------------------------------+-----
4| BaseAddress0 | 10
---+---------------------------------------------------------+-----
5| BaseAddress1 | 14
---+---------------------------------------------------------+-----
6| BaseAddress2 | 18
---+---------------------------------------------------------+-----
7| BaseAddress3 | 1C
---+---------------------------------------------------------+-----
8| BaseAddress4 | 20
---+---------------------------------------------------------+-----
9| BaseAddress5 | 24
---+---------------------------------------------------------+-----
10| CardBusCISpointer | 28
---+---------------------------------------------------------+-----
11| SubsystemDeviceID | SubsystemVendorID | 2C
---+---------------------------------------------------------+-----
12| ExpansionROMBaseAddress | 30
---+---------------------------------------------------------+-----
13| Reserved(CapabilityList) | 34
---+---------------------------------------------------------+-----
14| Reserved | 38
---+---------------------------------------------------------+-----
15| Max_Lat | Min_Gnt | IRQPin | IRQLine | 3C
-------------------------------------------------------------------
配置空间中最重要的有:
VendorID:
厂商ID。
知名的设备厂商的ID。
FFFFh是一个非法厂商ID,可它来判断PCI设备是否存在。
DeviceID:
设备ID。
某厂商生产的设备的ID。
操作系统就是凭着VendorID和DeviceID找到对应驱动程序的。
ClassCode:
类代码。
共三字节,分别是类代码、子类代码、编程接口。
类代码不仅用于区分设备类型,还是编程接口的规范,这就是为什么会有通用驱动程序。
IRQLine:
IRQ编号。
PC机以前是靠两片8259芯片来管理16个硬件中断。
现在为了支持对称多处理器,有了APIC(高级可编程中断控制器),它支持管理24个中断。
IRQPin:
中断引脚。
PCI有4个中断引脚,该寄存器表明该设备连接的是哪个引脚。
关于配置空间的详细说明请参考《PCILocalBusSpecification》的第六章。
二、如何访问配置空间
如何访问配置空间呢?
可通过访问CF8h、CFCh端口来实现(《PCILocalBusSpecification》的3.2.2.3.2)。
CF8h:
CONFIG_ADDRESS。
PCI配置空间地址端口。
CFCh:
CONFIG_DATA。
PCI配置空间数据端口。
CONFIG_ADDRESS寄存器格式:
31 位:
Enabled位。
23:
16位:
总线编号。
15:
11位:
设备编号。
10:
8位:
功能编号。
7:
2位:
配置空间寄存器编号。
1:
0位:
恒为“00”。
这是因为CF8h、CFCh端口是32位端口。
现在有个难题——CF8h、CFCh端口是32位端口,可像TurboC之类的16位C语言编译器都不支持32位端口访问。
怎么办?
我们可以使用__emit__在程序中插入机器码。
每次都__emit__一下肯定很麻烦,所以我们应该将它封装成函数。
代码如下(注意66h是32位指令前缀):
/*读32位端口*/
DWORDinpd(intportid)
{
DWORDdwRet;
asmmovdx,portid;
asmleabx,dwRet;
__emit__(
0x66,0x50,//pushEAX
0x66,0xED,//inEAX,DX
0x66,0x89,0x07,//mov[BX],EAX
0x66,0x58);//popEAX
returndwRet;
}
/*写32位端口*/
voidoutpd(intportid,DWORDdwVal)
{
asmmovdx,portid;
asmleabx,dwVal;
__emit__(
0x66,0x50,//pushEAX
0x66,0x8B,0x07,//movEAX,[BX]
0x66,0xEF,//outDX,EAX
0x66,0x58);//popEAX
return;
}
三、枚举PCI设备
怎么枚举PCI设备呢?
我们可以尝试所有的bus/dev/func组合,然后判断得到的厂商ID是否为FFFFh。
下面这个程序就是使用该方法枚举PCI设备的。
同时为了便于分析数据,将每个设备的配置空间信息保存到文件,这样可以慢慢分析。
/*File:
epcip.cName:
访问CF8h、CFCh端口来枚举PCI设备Author:
zyl910Blog:
V1.0Updata:
2006-6-30
*/
#include
#include
typedefunsignedcharBYTE;
typedefunsignedintWORD;
typedefunsignedlongDWORD;
/*PCI设备索引。
bus/dev/func共16位,为了方便处理可放在一个WORD中*/
#definePDI_BUS_SHIFT8
#definePDI_BUS_SIZE8
#definePDI_BUS_MAX0xFF
#definePDI_BUS_MASK0xFF00
#definePDI_DEVICE_SHIFT3
#definePDI_DEVICE_SIZE5
#definePDI_DEVICE_MAX0x1F
#definePDI_DEVICE_MASK0x00F8
#definePDI_FUNCTION_SHIFT0
#definePDI_FUNCTION_SIZE3
#definePDI_FUNCTION_MAX0x7
#definePDI_FUNCTION_MASK0x0007
#defineMK_PDI(bus,dev,func)(WORD)((bus&PDI_BUS_MAX)< /*PCI配置空间寄存器*/ #definePCI_CONFIG_ADDRESS0xCF8 #definePCI_CONFIG_DATA0xCFC /*填充PCI_CONFIG_ADDRESS*/ #defineMK_PCICFGADDR(bus,dev,func)(DWORD)(0x80000000L|(DWORD)MK_PDI(bus,dev,func)<<8) /*读32位端口*/ DWORDinpd(intportid) { DWORDdwRet; asmmovdx,portid; asmleabx,dwRet; __emit__( 0x66,0x50,//pushEAX 0x66,0xED,//inEAX,DX 0x66,0x89,0x07,//mov[BX],EAX 0x66,0x58);//popEAX returndwRet; } /*写32位端口*/ voidoutpd(intportid,DWORDdwVal) { asmmovdx,portid; asmleabx,dwVal; __emit__( 0x66,0x50,//pushEAX 0x66,0x8B,0x07,//movEAX,[BX] 0x66,0xEF,//outDX,EAX 0x66,0x58);//popEAX return; } intmain(void) { intbus,dev,func; inti; DWORDdwAddr; DWORDdwData;FILE*hF; charszFile[0x10]; printf("\n"); printf("Bus#\tDevice#\tFunc#\tVendor\tDevice\tClass\tIRQ\tIntPin\n"); /*枚举PCI设备*/ for(bus=0;bus<=PDI_BUS_MAX;++bus) {for(dev=0;dev<=PDI_DEVICE_MAX;++dev) {for(func=0;func<=PDI_FUNCTION_MAX;++func) {/*计算地址*/ dwAddr=MK_PCICFGADDR(bus,dev,func);/*获取厂商ID*/ outpd(PCI_CONFIG_ADDRESS,dwAddr); dwData=inpd(PCI_CONFIG_DATA); /*判断设备是否存在。 FFFFh是非法厂商ID*/ if((WORD)dwData! =0xFFFF) { /*bus/dev/func*/ printf("%2.2X\t%2.2X\t%1X\t",bus,dev,func); /*Vendor/Device*/ printf("%4.4X\t%4.4X\t",(WORD)dwData,dwData>>16); /*ClassCode*/ outpd(PCI_CONFIG_ADDRESS,dwAddr|0x8); dwData=inpd(PCI_CONFIG_DATA); printf("%6.6lX\t",dwData>>8); /*IRQ/intPin*/ outpd(PCI_CONFIG_ADDRESS,dwAddr|0x3C); dwData=inpd(PCI_CONFIG_DATA); printf("%d\t",(BYTE)dwData); printf("%d",(BYTE)(dwData>>8)); printf("\n"); /*写文件*/ sprintf(szFile,"CI%2.2X%2.2X%X.bin",bus,dev,func); hF=fopen(szFile,"wb"); if(hF! =NULL){/*256字节的PCI配置空间*/ for(i=0;i<0x100;i+=4){ /*Read*/ outpd(PCI_CONFIG_ADDRESS,dwAddr|i); dwData=inpd(PCI_CONFIG_DATA); /*Write*/ fwrite(&dwData,sizeof(dwData),1,hF); } fclose(hF);}}}}} return0; } 对于我的电脑的枚举结果是: Bus#Device#Func#VendorDeviceClassIRQIntPin类代码的说明 000110631896000000Hostbridge 0101106B1686040000PCI-to-PCIbridge(实际上是PCI/AGP桥,AGP可看成一种特殊的PCI设备) 09014F1201378000111Simplecommunicationcontrollers 09114F1201378000111Simplecommunicationcontrollers 09214F1201378000111Simplecommunicationcontrollers 09314F1201378000111Simplecommunicationcontrollers 09414F1201378000111Simplecommunicationcontrollers 09514F1201378000111Simplecommunicationcontrollers 09614F1201378000111Simplecommunicationcontrollers 09714F1201378000111Simplecommunicationcontrollers 0100110630380C0300111USBcontroller: UniversalHostControllerSpecification 0101110630380C030052USBcontroller: UniversalHostControllerSpecification 0102110630380C030053USBcontroller: UniversalHostControllerSpecification 0103110631040C0320114USB2controller: IntelEnhancedHostControllerInterface 0110110631776010000ISAbridge 0111110657101018A2551IDEcontroller 0115110630594010053Audiodevice 01201106306520000111Ethernetcontroller 10010DE11030000111VGA-compatiblecontroller 总线编号为0的都是主板上固有的芯片(主要是南桥),非主板设备的典型是——显卡。 WindowsXP的设备管理器中也可以看到PCI信息。 启动“设备管理器”,最好将查看方式设为“依连接查看设备(V)”。 找到我的显卡,双击查看属性。 切换到“详细信息”页,定位组合框为“硬件Id”。 可看到其中一行为“PCI/VEN_10DE&DEV_0110&CC_030000”,表示厂商ID为“10DE”、设备ID为“0110”、类代码为“030000”,与程序得到的结果一致。 [Display.gif] 四、PCIBIOS 直接访问CF8h、CFCh端口的方法太底层。 为了提高兼容性,我们可以使用PCIBIOS。 PCIBIOS的中断号是1Ah,AH为B1,AL为功能号。 其功能列表为: 01h: INSTALLATIONCHECK 02h: FINDPCIDEVICE 03h: FINDPCICLASSCODE 06h: PCIBUS-SPECIFICOPERATIONS 08h: READCONFIGURATIONBYTE 09h: READCONFIGURATIONWORD 0Ah: READCONFIGURATIONDWORD 0Bh: WRITECONFIGURATIONBYTE 0Ch: WRITECONFIGURATIONWORD 0Dh: WRITECONFIGURATIONDWORD 0Eh: GETIRQROUTINGINFORMATION 0Fh: SETPCIIRQ 81h: INSTALLATIONCHECK(32-bit) 82h: FINDPCIDEVICE(32-bit) 83h: FINDPCICLASSCODE(32-bit) 86h: PCIBUS-SPECIFICOPERATIONS(32-bit) 88h: READCONFIGURATIONBYTE(32-bit) 89h: READCONFIGURATIONWORD(32-bit) 8Ah: READCONFIGURATIONDWORD(32-bit) 8Bh: WRITECONFIGURATIONBYTE(32-bit) 8Ch: WRITECONFIGURATIONWORD(32-bit) 8Dh: WRITECONFIGURATIONDWORD(32-bit) 8Eh: GETIRQROUTINGINFORMATION(32-bit) 8Fh: SETPCIIRQ(32-bit) 由于像TurboC这样的16位编译器访问32位寄存器很麻烦,所以建议使用WORD方式来访问PCI配置空间。 以下是09h号功能的详细说明(摘自RalfBrown'sInterruptList): --------X-1AB109----------------------------- INT1A-PCIBIOSv2.0c+-READCONFIGURATIONWORD AX=B109h BH=busnumber BL=device/functionnumber(bits7-3device,bits2-0function) DI=registernumber(0000h-00FFh,mustbemultipleof2)(see#00878) Return: CFclearifsuccessful CX=wordread CFsetonerror AH=status(00h,87h)(see#00729) EAX,EBX,ECX,andEDXmaybemodified allotherflags(exceptIF)maybemodified Notes: thisfunctionmayrequireupto1024byteofstack;itwillnotenable interruptsiftheyweredisabledbeforemakingthecall themeaningsofBLandBHonentrywereexchangedbetweentheinitial draftsofthespecificationandfinalimplementation BUG: theAwardBIOS4.51PG(dated05/24/96)incorrectlyreturnsFFFFhfor register00hifthePCIfunctionnumberisnonzero
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- dos下枚举 pci设备 dos 枚举 pci 设备