1. 配置
在配置内核时,如果选择了CONFIG_DMI选项,会将DMI(Desktop Management interface)功能添加到内核中。此功能代码在drivers/firmware/Dmi_scan.c文件中。
2. 功能实现
2.1 函数调用关系
dmi_scan_machineàdmi_presentàdmi_walk_earlyàdmi_tableàdmi_decode
dmi_scan_machine函数在地址空间0xF0000~0x100000之间通过调用dmi_present函数判断DMI表是否存在;
dmi_present函数检查标识_DMI_并计算CRC值来确定DMI表是否正确。当此表正确时,通过表头信息得到dmi_num、dmi_len、dmi_base值;
dmi_walk_early函数通过dmi_num、dmi_len、dmi_base信息,调用dmi_table对DMI表信息进行解析;
dmi_table函数调用dmi_decode函数完成DMI信息的解析和存储;
dmi_decode解析DMI信息,包含BIOS Information、System Information、Base Board Information、Chassis Information、Onboard Devices Information、OEM Strings、IPMI Device Information、Onboard Devices Extended Information,并且将这些信息存储起来;
2.2 DMI信息使用
通过dmi_decode函数,已经将相关信息进行了存储。当内核中其他模块需要使用DMI信息时,可以调用相关函数,比如dmi_check_system。此函数会调用dmi_matches,如果BIOS中存储的DMI信息与需要查找的信息相匹配,dmi_matches函数会返回真,否则dmi_matches函数会返回假。当dmi_matches函数返回真时,dmi_check_system会调用函数参数中提供的回调函数。这样,DMI功能模块与使用DMI功能信息的模块之间就建立起联系通道了。如下面代码段所示:
static bool pci_use_crs = true;
//此函数为回调函数
static int __init set_use_crs(const struct dmi_system_id *id)
{
pci_use_crs = true;
return 0;
}
static const struct dmi_system_id pci_use_crs_table[] __initconst = {
/* http://bugzilla./show_bug.cgi?id=14183 */
{
.callback = set_use_crs,
.ident = "IBM System x3800",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
},
},
/* https://bugzilla./show_bug.cgi?id=16007 */
/* 2006 AMD HT/VIA system with two host bridges */
{
.callback = set_use_crs,
.ident = "ASRock ALiveSATA2-GLAN",
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "ALiveSATA2-GLAN"),
},
},
{}
};
void __init pci_acpi_crs_quirks(void)
{
……
dmi_check_system(pci_use_crs_table);
……
}
3. DMI信息查看
在操作系统中,可以通过dmidecode命令查看DMI信息。此命令并没有调用内核中的任何接口去获得DMI信息,而是与内核中相关代码一样,直接在地址空间0xF0000~0x100000之间查找DMI信息是否存在并进行解析。