PCI设备驱动和相关知识

在研究黑苹果驱动时,经常会看到修改Info.plist中的IOPCIMatch字段。需要研究一下相关内容。

PCI是一种外设部件互连标准总线,和USB总线差不多,可以将不同类型的设备连接到同一条总线上。

常见的PCI设备有显卡,网卡,声卡,IDE控制器,AHCI控制器,USB控制器等。

符合PCI标准的设备,都必须有一个VID和DID,在Windows设备管理器中,可以很方便地查看设备的硬件ID。

下图以网卡为例:

设备ID以PCI开头,表示这是PCI设备,VEN_10EC&DEV_8168,表示设备的VID=0x10EC,DID=0x8168。

VID是标识厂商的唯一代码,不同厂商是不同的,由一个神秘组织维护这些VID。知道VID就知道厂商名称。

比如0x10EC是RealTek,0x10DE是Nvidia,0x8086是Intel。

DID是标识不同的设备代码,相同厂商有不同和设备,需要用DID来区分。

比如这里的0x8168就是Realtek的以太网卡设备,Realtek还有声卡等其它设备,具有不同的DID。

一般情况下用VID和DID就可以匹配设备驱动程序了。

除此之外,还有Subsystem ID和Revision ID和Class Code。

Subsystem ID是次要的设备识别码,作用与VID和DID相同,长度为4字节。

Revision ID是版本号,长度为1字节。

Class Code是设备类型代码,由神秘组织定义的设备类型代码,长度为3字节。

关于设备类型代码,在这里有说明:http://pci-ids.ucw.cz/read/PD

 

================================================

大概了解了PCI设备的知识后,再来看看Windows驱动程序,Windows驱动一般由一个sys文件和inf文件组成。

inf描述了设备驱动程序的安装过程,以及对应的设备ID。

我找来了刚才的网卡驱动,找到里面关于设备ID的字段如下(部分内容):

;8168B
%RTL8168.DeviceDesc%    = RTL8168.ndi,      PCI\VEN_10EC&DEV_8168&REV_01
%RTL8168.DeviceDesc%    = RTL8168.ndi,      PCI\VEN_10EC&DEV_8168&SUBSYS_816810EC&REV_01
;8112
%RTL8112.DeviceDesc%    = RTL8168.ndi,      PCI\VEN_10EC&DEV_8168&SUBSYS_83851043&REV_01

;8168D
%RTL8168D.DeviceDesc%   = RTL8168D.ndi,     PCI\VEN_10EC&DEV_8168&REV_03
%RTL8168D.DeviceDesc%   = RTL8168D.ndi,     PCI\VEN_10EC&DEV_8168&SUBSYS_816810EC&REV_03
;8112L
%RTL8112L.DeviceDesc%   = RTL8168D.ndi,     PCI\VEN_10EC&DEV_8168&SUBSYS_83A31043&REV_03

;8168E
%RTL8168E.DeviceDesc%   = RTL8168E.ndi,     PCI\VEN_10EC&DEV_8168&REV_06
%RTL8168E.DeviceDesc%   = RTL8168E.ndi,     PCI\VEN_10EC&DEV_8168&SUBSYS_816810EC&REV_06

从这里可以看出来,当设备的VID和DID是相同的时候,还需要由SUBSYS和REV来区分不同的版本。

Windows安装驱动程序的时候,会检测到我的网卡ID符合下面这条内容:

%RTL8168E.DeviceDesc%   = RTL8168E.ndi,     PCI\VEN_10EC&DEV_8168&REV_06

因此会为我的网卡安装这个驱动程序。

 

========================================================

那么再看看Mac OS X系统下面的驱动程序:

一个Mac系统的驱动程序是一个后缀为.kext的文件夹,里面有Content和Info.plist。

关于设备描述的内容在Info.plist里面,如何匹配设备标识,先看一下开发者文档吧。

苹果开发者文档里更具体的描述:https://developer.apple.com/documentation/kernel/iopcidevice?language=objc

IOPCIMatch:匹配设备VID和DID,或者子系统ID

IOPCIPrimaryMatch:匹配VID和DID

IOPCISecondaryMatch:匹配子系统ID

IOPCIClassMatch:匹配设备类型代码,默认掩码0xFFFFFF00

IONameMatch:匹配设备名称

我找来了几个驱动为参照:

<key>IOPCIMatch</key>
<string>0x10EA8086 0x10EB8086 0x10EF8086 0x10F08086 0x15028086 0x15038086 0x153A8086 0x153B8086 0x155A8086 0x15598086 0x15A08086 0x15A18086 0x15A28086 0x15A38086 0x156F8086 0x15708086 0x15B78086 0x15B88086 0x15D78086 0x15D88086 0x15E38086 0x15D68086 0x15BD8086 0x15BE8086 0x15BB8086 0x15BC8086 0x15DF8086 0x15E08086 0x15E18086 0x15E28086</string>

这里是IOPCIMatch方式,这个驱动支持的设备ID不止一个。

其中0x10EA8086表示VID=0x8060,DID=0x10EA的设备。

 

再来看这个AppleHDA驱动里的:

<key>IOClass</key>
<string>AppleHDAController</string>
<key>IOPCIClassMatch</key>
<string>0x04020000&amp;0xFFFE0000</string>

IOPCIClassMatch匹配设备类型值:0x04020000&0xFFFE0000

表示掩码0xFFFE000表示用你的PCI设备类型值“按位与”计算出的结果等于0x04020000则匹配成功。

注意:0x0402&0xFFFE和0x0403&0xFFFE结果都是0x0402,所以这个HDA驱动对类型为0x0402和0x0403都有效。

从类型值表查到0x04表示多媒体设备,0x02/0x03表示Computer telephony device/Audio device

 

再来看设备名称匹配,比如这样的:

<key>IONameMatch</key>
<array>
<string>EHC1</string>
<string>EHC2</string>
</array>

这里的ECH1和EHC2就是表示USB 2.0控制器设备,这个名字从哪里来的呢?

我猜是DSDT吧,因为从导出的DSDT文件里有EHC1这个名字,还有对应的设备地址等信息。

 

除此之外还有这样匹配设备名的,看上去像VID和DID号:

<key>IOClass</key>
    <string>BCM5701Enet</string>
	<key>IOMatchCategory</key>
	<string>IODefaultMatchCategory</string>
	<key>IONameMatch</key>
	<array>
		<string>pci14e4,1641</string>
		<string>pci14e4,1642</string>
		<string>pci14e4,1643</string>
		<string>pci14e4,1644</string>
		<string>pci14e4,1645</string>
    </array>

kext驱动文件有两个标准目录一个是/L/E,另一个是/S/L/E,

/L/E目录是第三方驱动的存放路径,建议自己的驱动都放这里。

/S/L/E是苹果原生驱动的路径。

安装方法是把kext复制到/L/E目录,然后修复权限,参考命令如下:

sudo cp -R demo.kext /Library/Extensions/
sudo chown -R root:wheel /Library/Extensions/demo.kext
sudo touch /Library/Extensions/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值