根据PCI 规范,Windows 9x/NT/XP系统,通过VID、DID、SID、SVID、RID及CC等6个识别代码对某一个PCI设备进行最终身份识别,并通过这些代码引导操作系统检测设备状态、发现新设备,安装设备不同版本的驱动等工作,并最终确保设备在系统平台内正常安全运行。这6个由十六进制代码编写的识别ID,就组成了PCI IDs(“s”表示复数)。
●VID:全称Vendor Identification,又称Vendor ID,是代表发明设备的专利所有者(技术厂商)的识别码,即常说的厂商ID,这个ID是PCI-SGI组织统一编制命名的,是唯一的厂商标识,不允许重名。例如:ATI的VID是0x1002,而NVIDIA的VID则是0x10DE。
●DID:全称Device Identification,又称Device ID,是针对设备本身标识的代码,即常说的设备ID。这个ID标识主要区别同类设备的不同型号,一般由技术发明厂商按PCI规范命名,不同厂商的设备可以有重名(由于不同厂商都有唯一的VID,因此并不会混淆身份)。例如:同样研发代号为R350的ATI 9800和ATI 9800XT,设备ID却不同,分别为:0x4E48和0x4E4A。
●SID:全称 Subsystem-Identification,又称Sub-ID子(次要)系统(设备)识别码,是授权被制造的设备的二次编码。和DID的区别是这个代码不是原技术厂商设备的代码,而是二级制造厂商代工设备的代码。有时候,如果是由技术厂商自己组织制造设备,这个编码也可以和DID同名。
●SVID:全称 Subsystem-Vendor Identification,又称Sub-Vendor ID子(次要)系统厂商识别码,是由PCI-SGI组织认证的二级制造厂商的识别码,同样是唯一的厂商标识,不允许重名,但同一家技术厂商的VID和SVID可以重名。SID和SVID代码通常放在一起,作为设备二次认证的IDs。例如:8139网卡的Subsystem IDs组合是0x813910EC,前面的8139是SID,后面的10EC是SVID。
●RID:全称Revision ID,又称Rev ID。即通常所说的版本号:REV.X.
●CC:全称Class-Code,类型代码,是区别不同类或者同类不同规格设备类型的编码。对于每一种设备如显示、声卡、SCSI、USB设备等等都有各自的标准分类。例如:Class-Code:000c0300,代表UHCI类型的USB设备;而Class-Code: 000c0310,则代表OHCI类型的USB设备。
上述的ID信息,我们可以通过BIOS自检画面或者WCPUID之类的系统信息检测软件看到。
从图1中,我们可看到整个系统内设备的基本信息,按照从左到右的顺序,分别是总线号、设备号、功能号、VID、DID、RID、SID/SVID、中断号和设备名称。
这里需要注意的是:由于SID和SVID属于次要系统的ID识别,在技术厂商自己进行制造产品并符合行业规范的前提下,一个PCI设备只要具备VID、DID、RID和CC就足够了。因此,SID和SVID只是PCI设备的附加识别IDs,并不是必须的,例如图中的PCI-PCI Bridge,其Subsystem ID为“0000000h”,表示无SID和SVID。这在后文的驱动IDs对比分析中,我们会进一步详述。
PnP(Plug and Play)即插即用技术,目前广泛运用于Windows系统平台。该技术能使系统自动侦测周边设备和板卡并自动安装设备驱动程序,做到插上就能用,无须人工干预。而PnP-PCI连接正是实现这一技术的关键。按照PCI规范,每个PCI设备都由一个总线号、一个设备号和一个功能号来确定。PCI设备可以访问三类地址空间:PCI的I/O空间、PCI的存储空间和PCI的配置空间。前两者可由PCI总线上的所有设备共享,后者则是唯一的。PCI的配置空间由256个字节构成,其布局是标准化的,它的前64个字节是必须的,记录了PCI设备的基本信息(图3),PnP就是通过这个配置空间实现与PCI设备的连接,进而实现其即插即用的功能。
你知道吗?
关于PCI-SIG组织
PCI-SIG的全称为Peripheral Component Interconnect Special Interest Group,它是一个以技术为主导的非盈利性组织。成立于1992年,专门制定和管理PCI标准。该组织目前拥有850多个会员,理事会成员共有9名,由会员推举选出,负责该组织的正常运作。目前该组织理事会主席由Microsoft公司代表担任,总经理为IBM公司代表,其它各理事会员是AMD、HP、Intel、LSI Logic、Phoenix、Sever Works、TI与VTM等。PCI-SIG所承担的责任包括:维持所有PCI修正版和追加版本的兼容性;协助PCI成为业界标准并延续PCI架构在市场上的寿命;确保PCI规格的单纯性、简易性和稳定性以确保更大程度地支持该规格普及的原设计理念;促进PCI标准的推进和改革。通过互通性测试和技术支持,编制和认证标准的厂商和设备IDs,促进其成员能够生产高质量高规格的产品,取得相对主动的市场竞争力。PCI第一个技术规范1.0版本在1992年6月22日面世,2.0修改版于1993年4月发布,2.1修改版于1995年一季度发布, 2.2修改版于1998年12月完成,2002年11月PCI-SIG组织公布新一代PCI规范PCI Express的最终草案,2003年7月PCI-SIG制定并发表了用于由PCI Express向PCI和PCI-X进行总线连接的标准规格“PCI Express to PCI/PCI-X Bridge Specification Revision 1.0”,2003年8月PCI-X 2.0规格出台。
从配置图中可以看到:Vendor ID、Device ID、Revision ID、Class Code域处于最前端(其中VID和DID独占最前端的16个字节),它们是读取和确认设备身份的关键,这些信息必须存在。SID和SVID域则处于配置空间的后面,属于对设备追加确认的部分,这两个信息可定义为“00000000h”(即无Subsystem ID)。其它比较重要的还有:Command和Status域—分别给出了对PCI设备的控制命令和当前状态、Base Address Register域—指示此PCI设备按I/O方式还是内存方式进行读写以及需要的地址空间大小、Interrupt Line和Interrupt Pin域—分别指明了设备使用的中断号和中断引脚。
从配置空间中前64个字节的分布情况来看,我们不难发现Windows系统对这6个ID识别代码是连续并按顺序来读取的,即读取的顺序是VID→DID→RID→CC→SVID→SID。PnP-PCI连接检测设备的基本过程如下:
1.系统BIOS自检载入PCI驱动程序到内存,扫描主板PCI Bus(总线)及设备。其实这个PCI驱动是操作系统调用的一个PCI的初始化代码(initial code),并非真正的设备驱动程序,以下我们统一称为:PCI初始化代码。
2.PCI初始化代码,从PCI总线0开始通过读取PCI槽位上所有PCI设备(包括PCI-PCI Bridge桥接设备)的Vendor ID和Device ID代码,通过CC(Class Code)验证设备是否存在(“000000h”表示Device不存在,即该插槽处于空闲状态),并通过PCI BIOS代码确认每个设备所占的槽位。最后,通过建立一个PCI_DEV数据结构,并把它链接到已知PCI设备的列表中。这就是对PCI设备身份确认的初始过程,称之为Great IDS:创建身份。
3.PCI初始化代码通过发现新硬件,进一步确认PCI设备的RID版本,是否存在SID/SVID,开始寻找匹配该设备的驱动程序INF安装文件。
4.PCI初始化代码通过设备驱动INF里的IDs代码进行PCI设备的驱动安装,并完成驱动在系统内的装载。
5.PCI设备自身的驱动程序,在安装过程中,根据驱动设定,进行特征设置。
6.PCI初始化代码通知PCI设备进行安装驱动后的初始值相关设定,操作系统根据设定提示重启后对PCI设备状态进行最终确认。
从上述PCI设备IDs身份确认的过程,我们可以看到位于最前端的VID和DID是最重要的两个代码,没有这两个代码,或者和硬件驱动INF文件里的IDs代码不符合,Windows系统将拒绝认证该设备并将该设备作为不可识别的设备或者拒绝安装不符合IDs标识的驱动程序。这也是我们改造硬件的同时需要修改设备固件以及驱动程序中这两个代码的主要原因。
驱动程序中的IDs标示规则
为便于理解,下面我们统一将VID和DID分别称为技术厂商ID和技术设备ID;将SVID和SID分别称为制造厂商ID和制造设备ID。根据Windows系统技术规范,PCI设备驱动INF里的IDs命名标准为:“PCI\VEN_VID&DEV_DID&SUBSYS_SIDSVID”,即技术厂商IDs必须在前,制造厂商IDs在后,这是跟上述PnP-PCI连接检测设备IDs的顺序是一致的。其中,VID和DID用十六进制“0xAAAA”编码,SIDSVID用十六进制的“0xAAAABBBB”编码(表1)。
图3和图4分别是D_Link和联想两家公司生产的网卡驱动INF文件截图。其中,由于D_LINK属于技术厂家并且也是制造厂家,因此其驱动INF里的IDs标识中技术厂商IDs和SVID是一致的,只有SID有所区别;而在联想网卡驱动的INF文件里,标识的技术厂商IDs和Subsystem ID均不是联想公司,而是其他的2家公司,即表示联想的这款网卡是被技术厂商授权的第三方厂商OEM制造的产品。
//P8A-1-6.jpg 图6 DCN_550GT网卡DID、VID和SVID的查询结果:授权技术厂商DID为“0x0022”,授权技术厂商VID为“0x1008”,制造厂商SVID为“0x1113”。///
从查询结果来看,D_Link公司的网卡,VID和DID均为技术厂商D_Link system Inc公司所有;而联想的网卡授权技术厂商DID和VID为National Semiconductor(美国国家半导体公司)所有,而制造厂商(OEM)的SVID(0x1113)为Accton Technology (下转104页)(上接97页)Corporation(台湾智邦科技公司)。从DID的查询来看,不同厂商的设备(例如0x0022)可以同名,但通过唯一的VID则可以很容易区分各自的身份。这样我们进一步证实了VID是唯一的厂商代码,DID则跟随VID进行确认。这也符合Windows对驱动进行选择安装的规范,即优先认证跟随VID的DID/SID/SVID设备驱动。通过PCI IDs查询,我们还能够通过参照PCI设备的检测信息,找到技术和制造厂家,从而安装设备匹配的驱动程序。
通过上述分析和了解,我们再回头看硬件DIY,就基本上能找到一个明确的思路。下面我们以ATI R3xx显卡硬改为例,进一步阐述这个思路。目前硬改显卡的一般思路就是连接硬件标识电阻,修改BIOS代码,安装原装驱动,实现显卡硬升级。
硬件标识电阻的修改,根据以往经验,我们知道修改的是ASIC DID,即硬件ID。这个硬件ID必须要和BIOS中的Device ID同步改变才能实现改造目的。从图7中可以看到,需要修改的关键值是Device ID,即设备ID,代码为“4X4X”。例如我们可以将9800SE的代码“4148”修改为9800的代码“4E48”或者9800XT的代码“4E4A”;与渲染管线相关的代码,我们可以将其看做是DID代码的附属代码,因为“4E48”或“4E4A”这个设备代码中的“E”规定了8条渲染管线的存在,而“8”和“A”才是设备型号识别的代码;而作为同一厂家的设备,其Vendor ID我们完全没有必要修改。通过硬件ID和BIOS中DID代码的成功修改,我们能实现显卡设备ID的变更,使BIOS顺利检测VID和DID后,调用相应的RID和Class-Code进行进一步的设备身份确认。最后,进入系统调用具有同样IDs识别代码的INF文件,使之顺利安装设备驱动;如果硬件ID连接失败或BIOS代码修改错误,我们从BIOS刷新画面中可以看到:ASIC DID和BIOS DID不相符合时,则只能调用设备原有或已知的RID和Class-Code确认。如果出现“414A”之类的非法DID,则由于ATI公司无此设备代码,而被windows系统视作未知设备,并导致驱动无法安装。
DIY中的IDs原理
在PC系统里将硬件IDs作为身份识别代码,是符合标准化、简易化,减少设备冲突和误操作的一个必要途径。只有认识这些身份代码,我们才能让各个PCI设备及周边设备相安无事。通过对PCI IDs的认识,我们也能掌握硬件破解改造的关键,从而更科学、更安全地进行DIY尝试
发表评论(对文章涉及的知识点还有疑问,可以在这里留言,老高看到后会及时回复的。)