1个不稳定版本
0.1.0 | 2024年4月29日 |
---|
#223 在 硬件支持
160 每月下载次数
255KB
3.5K SLoC
pci-info
pci-info
crate提供了一个简单的API,用于在“桌面”操作系统(Linux、Windows、MacOS等)上枚举PCI设备,或从文件或内存缓冲区解析PCI头部。
它支持解析PCI元数据和各种字段的可用性(包括可能整个设备的标准PCI配置空间);支持的水平取决于使用的枚举器的功能。
它仅使用用户模式API,可由普通用户访问(即不需要root/管理员权限)。所有代码都是从头开始通过公开可用的文档实现的。因此,它通常提供的数据比一些替代方案(例如libpci)少,但要求不那么严格(在许可和某些平台上的可用属性方面)。
PCI设备类别、子类和接口函数作为可选的rust枚举公开,以便快速匹配,并且已经从公开可用的文档中实现。
PCI供应商和设备ID保留为u16
,需要手动解释或使用其他crate将其转换为字符串;有意不包括公开可用的PCI供应商和设备列表,以避免crate大小(完整的列表很大)和许可问题(此crate为MIT+Apache双许可,列表为GPL+BSD双许可)。
提供的功能摘要
- 使用Windows、Linux和MacOS上的OS用户模式API枚举设备,并将添加更多平台。请参阅
PciInfo
类型。 - 从PCI配置空间的字节数组开始解析PCI头部。请参阅
pci_headers
模块。 - 从它们的代码解析PCI设备类别、子类和接口函数。请参阅
pci_enums
模块。
示例
使用默认枚举器使用库很简单
use pci_info::PciInfo;
pub fn main() {
// Enumerate the devices on the PCI bus using the default
// enumerator for the current platform. The `unwrap()` panics if
// the enumeration fatally fails.
let info = PciInfo::enumerate_pci().unwrap();
// Print out some properties of the enumerated devices.
// Note that the collection contains both devices and errors
// as the enumeration of PCI devices can fail entirely (in which
// case `PciInfo::enumerate_pci()` would return error) or
// partially (in which case an error would be inserted in the
// result).
for r in info {
match r {
Ok(device) => println!("{device:?}"),
Err(error) => eprintln!("{error}"),
}
}
}
使用自定义枚举器
如果需要,可以使用自定义枚举器,使用 enumerate_pci_with_enumerator
方法,该方法属于 PciInfo
类型。
例如
// NOTE: This example runs only on Windows as it uses a platform
// specific PCI enumerator.
use pci_info::PciInfo;
#[cfg(target_os = "windows")]
pub fn main() -> Result<(), PciInfoError> {
// Enumerate the devices by accessing the `enumerate_pci_with_enumerator`
// method of the `PciInfo` type.
let info = PciInfo::enumerate_pci_with_enumerator(enumerators::WindowsWmiPciEnumerator)?;
for r in info {
match r {
Ok(device) => println!("{device:?}"),
Err(error) => eprintln!("{error}"),
}
}
}
或者,您可以直接调用 enumerate_pci
,这是 PciEnumerator
特性的方法。虽然推荐的语法是通过 PciInfo::enumerate_pci_with_enumerator
方法。
// NOTE: This example runs only on Linux as it uses a platform
// specific PCI enumerator.
use pci_info::PciInfo;
#[cfg(target_os = "linux")]
pub fn main() -> Result<(), PciInfoError> {
// Create a Linux-specific custom enumerator.
let enumerator = LinuxProcFsPciEnumerator::Fastest;
// Enumerate the devices by accessing the `enumerate_pci`
// method of the `PciEnumerator` trait. Works but using
// `PciInfo::enumerate_pci_with_enumerator` is preferred.
let info = enumerator.enumerate_pci()?;
for r in info {
match r {
Ok(device) => println!("{device:?}"),
Err(error) => eprintln!("{error}"),
}
}
}
枚举器
枚举器提供的PCI设备属性各不相同。
枚举器 | 平台 | PCI ID | PCI位置 | 修订版本 | 设备类 | PCI子系统 | 分配的IRQ | 操作系统驱动 |
---|---|---|---|---|---|---|---|---|
LinuxProcFsPciEnumerator(最快) | Linux | ✅ | ✅2 | ❌ | ❌ | ❌ | ✅ | ✅ |
LinuxProcFsPciEnumerator(只包含头文件) | Linux | ✅ | ✅2 | ✅ | ✅ | ✅ | ❌ | ❌ |
LinuxProcFsPciEnumerator(跳过非公共头文件) | Linux | ✅ | ✅2 | ✅ | ✅ | ❌ | ✅ | ✅ |
LinuxProcFsPciEnumerator(完全枚举) | Linux | ✅ | ✅2 | ✅ | ✅ | ✅ | ✅ | ✅ |
MacOsIoKitPciEnumerator3 | macOS | ✅ | ⚠️1, 2 | ✅ | ✅ | ✅ | ❌ | ❌ |
WindowsSetupApiPciEnumerator | Windows | ✅ | ⚠️1, 2 | ✅ | ✅ | ✅ | ❌ | ❌ |
WindowsWmiPciEnumerator | Windows | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | ❌ |
备注
- (1) = 在此枚举器上,PCI位置是从可读字符串中解析出来的;这种解析可能会失败,或者信息可能是不正确的。
- (2) = 在此枚举器上,PCI位置可能不支持多个PCI段/域。
- (3) = 显然,大多数Apple硅Mac上的设备都不是PCI/PCIe。因此,在Apple硅计算机上进行的PCI枚举返回的列表相当短。
功能
可以通过以下功能配置crate
crate功能 | 默认 | 描述 |
---|---|---|
pci_class_debug_strings |
YES | 包含对 pci_enums::PciDeviceClass 变体的可读调试字符串。禁用以减小二进制文件大小。 |
pci_subclass_debug_strings |
YES | 包含对 pci_enums::PciDeviceSubclass 变体的可读调试字符串。禁用以减小二进制文件大小。 |
pci_interface_func_debug_string |
YES | 包含对 pci_enums::PciDeviceInterfaceFunc 变体的可读调试字符串。禁用以减小二进制文件大小。 |
变更日志
0.1.0
首次发布版本,包含Linux、Windows和macOS的基本枚举器。
依赖项
~0–36MB
~538K SLoC