不可行,因需root权限且现代内核默认启用config_strict_devmem,/dev/mem仅映射前1mb而dmi表所在区域常被uefi标记为reserved;可靠方式是读取/sys/class/dmi/id/(用户可读)或/sys/firmware/dmi/tables/dmi(需root)。

Linux下用/dev/mem直接读取DMI表是否可行?
不可行,除非你以root运行且内核未启用CONFIG_STRICT_DEVMEM(现代发行版默认开启)。即使绕过,/dev/mem只暴露物理内存前1MB,而DMI表地址由固件在启动时通过ACPI或SMBIOS规范写入特定内存位置(如0x000F0000–0x000FFFFF),但该区域在UEFI系统中通常被标记为reserved,mmap()会失败并返回Invalid argument。
真正可靠的方式是走内核提供的抽象层:
-
/sys/firmware/dmi/tables—— 包含dmidecode所用的原始二进制数据(需root) -
/sys/class/dmi/id/—— 用户可读的解析后字段(如product_name、bios_version),无需特权
如何用C++安全读取/sys/class/dmi/id/下的字符串字段
这是最轻量、最兼容的做法。所有字段都是ASCII文本,换行符结尾,读取即用:
#include <fstream>
#include <string>
#include <filesystem><p>std::string read_dmi_field(const std::string& field) {
std::ifstream f("/sys/class/dmi/id/" + field);
if (!f.is_open()) return "";
std::string s;
std::getline(f, s); // 自动截断换行符
return s;
}</p>
<p>// 使用示例:
// auto bios_ver = read_dmi_field("bios_version");
// auto vendor = read_dmi_field("sys_vendor");
</p></filesystem></string></fstream>
注意:std::filesystem::exists()不能代替open()检查——某些字段(如chassis_asset_tag)可能根本不存在,read_dmi_field返回空串即表示缺失,不是错误。
需要完整SMBIOS结构体(比如Type 17内存设备)时怎么办?
必须调用libdmidecode或自己解析/sys/firmware/dmi/tables/DMI。后者更可控,但要注意三点:
- 该文件是原始SMBIOS表二进制流,开头是32字节的SMBIOS Entry Point Structure(校验和、表长度、起始地址等)
- 实际结构表从
EntryPoint->TableAddress开始,但/sys/firmware/dmi/tables/DMI已将整个表(含Entry Point)打包为单个文件,直接read()即可 - 解析必须严格按SMBIOS spec 3.6+处理:每个结构以
00 00结尾,字符串区以00分隔,偏移0x19后的“String Index”字段指向字符串区索引而非地址
不建议手写完整解析器。若必须自研,优先复用dmidecode源码中的smbios_decode()逻辑,而不是从零推导——不同厂商对“optional field present”标志的实现有细微差异,容易漏判结构长度。
Windows平台怎么拿到等效信息?
没有对应/sys/class/dmi/id/的用户态直通接口。唯一稳定路径是WMI:
SELECT * FROM Win32_BIOS SELECT * FROM Win32_ComputerSystem
C++中需用COM调用 IWbemServices::ExecQuery(),初始化开销大、代码冗长,且要求目标机器启用WMI服务(WinPE或极简安装可能关闭)。如果只是获取BIOS版本或主板型号,GetSystemFirmwareTable('RSMB', 0, buf, size)更轻量——但它只返回原始SMBIOS表(同Linux的/sys/firmware/dmi/tables/DMI),仍需自行解析。
跨平台项目别试图统一解析逻辑:Linux用/sys/class/dmi/id/兜底,Windows用WMI查关键字段,仅当真需要Type 4(处理器)或Type 127(结束标志)这类底层结构时,才共用二进制解析模块。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











