Linux如何定位BIOS提供的SMBIOS表

SMBIOS(System Management BIOS)是由BIOS/UEFI在初始化系统的时候收集的关于系统信息的一组结构化的表,并且存放在内存中,提供给操作系统使用。在Linux中,可以通过dmidecode命令查看,不同类型的SMBIOS子表通过type数值来区分。如下所示:

从SMBIOS的spec中可以看到,对于基于Legacy BIOS的系统而言,系统软件可以通过在物理内存范围000F0000h ~ 000FFFFFh内搜索指定的字符串来定位到SMBIOS表的入口点。对于SMBIOS 2.1而言,这个字符串是"_SM_",对于SMBIOS 3.0而言,这个字符串为"_SM3_"。
而对于基于UEFI的系统而言,EFI configuration table (EFI_CONFIGURATION_TABLE)包含了指向SMBIOS table的指针。

在SMBIOS Entry Point这个表的offset 10h中包含了指向真正的SMBIOS表位置的指针

SMBIOS表可以位于内存的任何位置,都是通过SMBIOS Entry Point提供的指针找到。SMBIOS表内的所有子表都是以紧凑的方式打包在一起,即每个子表都有一个固定格式的头,这个头包含了该子表的长度,而紧接在这个子表后面的就是下一个子表,这样就完全不会浪费内存。

在内核代码中,查找定位SMBIOS表的动作位于drivers/firmware/dmi_scan.c:dmi_scan_machine()函数中,它会在内核启动的时候被调用到,其调用关系为:
arch/x86/kernel/head64.S -> arch/x86/kernel/head64.c:x86_64_start_kernel() -> arch/x86/kernel/head64.c:x86_64_start_reservations -> init/main.c:start_kernel() -> arch/x86/kernel/setup.c:setup_arch() -> dmi_scan_machine()
在dmi_scan_machine()的源码中,它会判断当前系统是基于UEFI还是Legacy BIOS,如果是UEFI的话,则会直接后在EFI Configuration Table中直接找到SMBISO表的指针。

对于Legacy的系统而言,则会按照SMBIOS spec里面规定的方法,在0x000F0000 ~ 0x000FFFFF的物理地址范围内寻找SMBIOS表的Anchor Sthing,即"_SM3_"或者"_SM_",定位SMBIOS表。

通过该方法,Linux内核就可以找到UEFI或者Legacy BIOS提供的SMBIOS表了。

欢迎关注同名微信公众号“河马虚拟化”第一时间获取最新文章。

猜你喜欢

转载自blog.csdn.net/lindahui2008/article/details/82215221
今日推荐