沃梦达 / IT编程 / 移动开发 / 正文

如何定制虚拟机smbios信息

如何定制虚拟机smbios信息在某些需要给机器做认证和加密的场景下,会需要读取机器的厂家和主板等信息,这些信息都存放在SMBIOS信息中。在虚拟化场景下可以定制虚拟机的SMBIOS信息。 SMBIOS是什么SMBIOS(System Man...

如何定制虚拟机smbios信息

在某些需要给机器做认证和加密的场景下,会需要读取机器的厂家和主板等信息,这些信息都存放在SMBIOS信息中。在虚拟化场景下可以定制虚拟机的SMBIOS信息。
SMBIOS是什么

SMBIOS(System Management BIOS)是由工业化组织DMTF提出的通过系统固件传递管理信息的标准。详见 https://www.dmtf.org/cn/standards/smbios
在SMBIOS标准中规定了若干的Type,每种Type都包含特定信息。例如:

BIOS Information (Type 0)

System Information (Type 1)

Baseboard (or Module) Information (Type 2)

System Enclosure or Chassis (Type 3)

Processor Information (Type 4)

Memory Controller Information (Type 5, Obsolete)

Memory Module Information (Type 6, Obsolete)

OEM Strings (Type 11)

在libvirt中可以定制Guest的smbios信息,首先填写smbios的mode,然后定制sysinfo。

指定smbios mode

在中指定:

......

<smbios mode='sysinfo'/>

这里的mode有三种取值:

“emulate”: 让qemu自动产生

“host” :从宿主机上拷贝SMBIOS的 Block 0和Block 1(UUID除外)

“sysinfo” :(使用sysinfo单元中指定的值)

填写sysinfo单元

<sysinfo type='smbios'>
   <bios>
      <entry name='vendor'>myvendor</entry>
    </bios>
    <system>
      <entry name='manufacturer'>manufacturer01</entry>
      <entry name='product'>test</entry>
      <entry name='version'>0.1</entry>
    </system>
    <baseBoard>
      <entry name='manufacturer'>manufacturer02</entry>
      <entry name='product'>0101010101</entry>
      <entry name='version'>0202020202</entry>
      <entry name='serial'>abcdefgh</entry>
    </baseBoard>
  <chassis>
    <entry name='manufacturer'>Dell Inc.</entry>
    <entry name='version'>2.12</entry>
    <entry name='serial'>65X0XF2</entry>
    <entry name='asset'>40000101</entry>
    <entry name='sku'>Type3Sku1</entry>
  </chassis>
  <oemStrings>
    <entry>myappname:some arbitrary data</entry>
    <entry>otherappname:more arbitrary data</entry>
  </oemStrings>
</sysinfo>
————————————————

其中:

bios:对应SMBIOS标准中的 BIOS Information (Type 0)

system:对应SMBIOS标准中的 System Information (Type 1)

baseBoard:对应SMBIOS标准中的 Baseboard (or Module) Information (Type 2)

chassis:对应SMBIOS标准中的 System Enclosure or Chassis (Type 3)

oemStrings:对应SMBIOS标准中的 OEM Strings (Type 11)

(chassis和oemStrings从libvirt4.1.0开始支持)

在虚拟机内部查看

可以看到在虚拟机中查询到的每一个type和我们在libvirt的domain中定制的完全相同。

SeaBIOS是一个开源的16bit x86 BIOS程序,它可以运行在模拟器上,或者是在x86硬件平台上和coreboot一起使用。这里主要介绍其运行在QEMU+KVM这样的虚拟化模拟器上的情况,对coreboot的情况暂时不说明。

BIOS程序是计算机上电后,CPU第一个开始运行的程序,完全运行在裸金属上,用于完成对系统硬件的初始化,并且为启动OS做好准备。BIOS程序跟具体的硬件具有很高的耦合度,基本上不同的硬件架构都会对应不同的BIOS程序,所以一般计算机厂商都会自己开发BIOS程序,虽然可能有很多部分是可以共用的,但是每个厂商设计的计算机硬件架构都会有区别,所以还是有一部分需要自己定制。SeaBIOS虽然是运行在模拟器上,但是也有自己适配的一套硬件架构,理解SeaBIOS适配的硬件架构(下一篇文章会讲)对于理解SeaBIOS的代码具有很重要的作用。

SeaBIOS也像正常的BIOS一样,在虚拟机上电的时候,会被加载到地址空间0xFFFFFFF0处,并且该处是一条跳转指令,虚拟机的虚拟CPU会去执行SeaBIOS的代码,完成虚拟硬件的初始化,中断服务函数的设置,ACPI表、SMBIOS表等的创建,最后引导启动OS。

SeaBIOS和正常BIOS的区别在于其运行的环境是一个由Hypervisor模拟出来的环境,有很多地方可以简化,主要表现为:

虚拟化环境中对硬件设备进行模拟的对象是硬件设备的功能及对外的接口,并不需要去模拟硬件设备的内部运行机制和设备的物理特性,所以就可以大大简化一些模拟设备的配置和初始化,其中包括:

芯片配置上,传统的BIOS需要对主板上的各个芯片,如CPU、南桥芯片、北桥芯片等进行各种配置,让其能够正常运行起来。而在虚拟化环境中,这些物理芯片一般都是不存在的,所以那些涉及到芯片内部运行机制、芯片物理特性的配置都将不再需要,SeaBIOS只需要关注和芯片功能相关的配置即可。

内存配置上,传统的BIOS都会包含MRC代码(内存厂商提供)用于对内存进行初始化,但是在虚拟化环境中,内存已经完全配置好了,所以SeaBIOS里面根本找不到内存初始化的代码,最多只是对e820表进行配置,或对内存的属性进行更改。

总线配置上,计算机上的总线,特别是一些较高速的总线如PCI,DMI,PCIe,QPI之类的总线,都会分成物理层、链路层、传输层等多层结构,为了让物理总线能够正常运行起来,传统的BIOS都需要对这些总线各个层的寄存器进行配置,对总线的运行模式、运行速率等参数进行调整、训练(training),这也是一个比较耗时的操作。但是在虚拟化环境中,这些总线物理特性上的配置和初始化都可以省去,因为并没有真正的物理总线存在,SeaBIOS要做的就是对这些总线在软件层面上的接口进行配置,如PCI总线的配置空间。

从SeaBIOS提供给OS的各种信息表上看,如APCI表、SMBIOS表、E820表等,传统的BIOS基本上都得靠自己去探索系统的所有信息逐步建立这些信息表,这可能是一个比较漫长的过程。而在虚拟化环境中,这些表很多并不需要SeaBIOS自己去逐步建立,很多可以是Hypervisor就可以通过特定的方式将这些表传给SeaBIOS,SeaBIOS只需要在有必要的时候对这些表的某些信息进行更新。

所以,总的来说,可以将SeaBIOS看成简化版的BIOS,主要从上面说的几个方面进行了简化。

本文标题为:如何定制虚拟机smbios信息