UEFI在各种平台上实施的问题和功能

自2000年发布第一个EFI规范以来,已经过去了十九年。该界面花了十年时间才进入用户市场并获得了立足点。目前,您几乎看不到主板固件中没有UEFI的现代计算机。接口标准在官方文档中增加了“内容”和数千页。对于普通用户,除了偶尔启用了安全启动的冲突之外,什么都没有改变。但是,如果工作面转向发展,一切都会变得更加有趣。



UEFI模块化体系结构的概念本身就意味着这些模块不仅可以在标准配置中使用,还可以下载自己的模块。文件系统驱动程序(不限于原生eFi-shy FAT?),外围设备驱动程序,应用程序,引导加载程序-您可以手动加载所有内容,最好加载一些Shell。您可以更“深入”一步,查看固件的内容,从而避免自己因使用SecureBoot而舞动,也无需编写脚本层(集线器页面上有足够的文章)。

在此基础上,产生了在加载操作系统之前创建执行各种安全功能的功能模块的想法,该功能模块可以进一步结合并成为一种集成的受信任的引导环境,从而影响引导和运行时接口的服务,从而使固件中的模块与磁盘上的模块之间相互兼容。没有低水平的干预,只有得到安全管理员的允许,才能“推动”任何事情。

这个想法的实现使我们了解到UEFI的许多细微差别和微妙之处-从许多未记录的或记录不充分的功能,错误开始,到所有开发人员都钟爱的未定义行为结束。让我们按顺序开始。

平台依赖




在集成到平台中时,首先需要了解的是我们是否可以使用它? UEFI规范的版本很重要,在大多数设备上,它的显示范围是2.1到2.7。较新的产品尚未投放市场。发现了较旧的版本,由于缺少必要的协议或弯曲的编写驱动程序以实现其性能,因此其性能可能受到限制。例如,UnicodeCollat​​ion通常是不够的,当访问smbios时,存在未记录的错误,通过SetVariable()进行的语言更改功能不起作用。任何事情都可能发生,这取决于供应商和新鲜程度,因为有时您甚至必须将协议放在相对较新的板上。

即使在我们的实践中,我也很幸运地偶然发现了两台装有Intel Bay Trail D和32位固件的小型计算机。这种情况很少见,但有一次需要紧急重新编译模块。实际上,就像问题一样:将来我们会不会遇到具有相同容量的更现代的平台?如果我们见面,那在哪里?

下一步是确定如何集成。模块内置在固件中,固件位于主板上的SPI芯片中,带有Intel ME的PCH位于附近。这里出现了最有趣的问题-如何到达那里?好的老程序员带着“鳄鱼”-这很好,很可靠。即使您没有赶上最后,也可以随时查看板上的发光LED,它们有足够的电量来自程序员。除某些较旧的HP型号外,它几乎可以完美地工作,带有固件的mikruha SOIC-16十分容易取用,因此,将适配器设计和焊接到她的腿上比挤压夹子更容易。



我知道在哈布雷(Habré)上有一些人为flashrom的写作做出了贡献,这要归功于他们。

但是,尽管程序员可以可靠地进行转储删除,但是如果您需要在多台计算机上的UEFI中安装某些内容,或者如果您的桌面上没有安装目标平台,则此方法不适合。对我们来说幸运的是,制造商留下了本机固件实用程序:英特尔(CS)ME系统工具套件中的FPT(闪存编程工具),以及American Megatrends中Aptio的AFU(AMI固件更新)。这些实用程序是从EFI环境以及Windows,Linux和DOS操作系统启动的。这些实用程序在某种程度上是可以互换的,两者都可以使您确定图像,即使不是整个图像,也可以是某些区域。有时他们甚至会让您回信。



他写,不写

这是整合路径上第一个严重的绊脚石出现的地方。并非所有主板都允许您读取整个固件,从而禁止访问 ME区域(ME几乎是神圣的,Intel不允许以良好的方式读取它,但是以糟糕的方式,我们并不总是希望读取)。甚至更少-甚至将一些东西倒入BIOS区域,除非它是一个带符号的胶囊。成功的可能性取决于芯片组的制造商和新鲜程度而有很大差异。在某些型号的主板上,您会看到一张有趣的图片:旧供应商板上未记录的图片在新时代飞逝。

有时IFR解析器有助于对抗写保护,这为隐藏的设置和变量打开了帷幕。有时,只有硬核跳线才有帮助,允许访问录音或“关闭” ME(如果提供的话)。

系统的复杂性


在大多数情况下,Acer,Asus,AsRock和技嘉主板的编写都没有不必要的困难。英特尔,惠普和服务器硬件脱颖而出。HP不仅不允许以编程方式自行编写,而且还承诺任何尝试修改固件(CodeRush 关于查找和禁用完整性检查的文章)。英特尔或多或少地记录了第87个芯片组,然后对打开BIOS区域门的要求充耳不闻。

对于英特尔,第一次很有趣。使用UEFITool实用程序将模块导入到固件中,我们遇到了一个有趣的错误:如果在所有自由格式之后在DXE卷的末尾插入ffs模块,则组装后的图像会使面板“变砖”。解决方案是在任何本机DXE驱动程序之后添加模块。我们并没有立即解决这个问题,起初看起来像是英特尔正在监视固件的完整性,例如HP。后来很明显,没有自动导入模块的实用程序是无法做到的,编写此问题后问题就消失了。

同时,服务器端硬件更简单,更复杂。一方面,总有其他方法可以更新和修改服务器上的BIOS,另一方面,这些相同的BIOS中的自定义量非常庞大,因为它们不会在服务器上跳过并安装容量非常大的闪存芯片,并且通常还会对其进行备份。

在服务器上安装时,能够通过IPMI远程更新BIOS总是很高兴。没错,为此,您需要一个许可证,当然要付费。如果未在正确的时间出现,很可能会陷入一种类似于我们在Supermicro服务器BIOS中引入模块的情况。

引入模块后,由于安全模块之一的阻塞,负载被紧紧冻结(它们没有考虑服务器BIOS的笨拙行为,因此不会发生这种情况!)。在没有能力通过IPMI来回滚BIOS的情况下,这只手对程序员来说是很困难的,但是运气不好-标准的SOIC-8夹不足以用于SOIC-16芯片!好吧,因为在理论上服务器主板可以从连接的媒体进行备份,因此可以从根目录中提取SUPER.ROM映像。但是这种机制无法启动,因为根据系统,一切正常,一切正常,因此不需要BIOS回滚!该怎么办?!..故事最终在城市中流传,以寻找正确的剪辑,紧急重新焊接电线,中国人以一种难以理解的顺序涂抹了我们,最后-闪烁着。

联想出来更有趣。在从供应商处收到的交换机上,在外壳的下面发现一个控制板,带有两个用于固件的“ mikruh”,一个用于操作系统的SSD和一个固定电池。事实证明,BIOS是一个棘手的问题,我不想以任何方式吃掉修改过的映像,只屈从于程序员。在尝试写下一些东西的过程中,他们将带有控制台ubuntu的闪存驱动器插入到交换机中(终端未提供图形),并非常安全地启动。完成所需的操作后,他们使用旧内存中的halt -p命令关闭了系统。由于缺少电源,该交换机本质上不适合任何关机,因此尚未做好准备,也不想再启动。脸上的连接一次烧毁,风扇安静地沙沙作响,所有端口都没有发出声音。重新刷新没有帮助,电池像手套一样坐着-我们害怕打破固定座。结果,一块薄薄的介电板在毅力和言语激励下在触点下方爬行,擦除了易失性存储器,使开关栩栩如生。

对从两种碎屑中提取的倾销进行的研究显示出很多有趣的事情。特别是,主固件的NVRAM中有大量“无效”条目,而备份中有多个类似的条目。好吧,这不是使用DXE驱动程序在卷中以前遇到的数据哈希。一个人只能猜测启动开关问题的确切原因。

通常,软件部分很少会失去意想不到的细微差别。在第87个芯片组之前(来自不同制造商)的许多主板都具有令人不愉快的功能,当在Shell控制台中输入“ dh -v”命令时,会产生无尽的错误流。手动输入并不重要,但是在将数据收集到文件中时,不幸的是挂起。在这两种情况下,您都必须重新启动计算机。我很高兴与此同时数据文件不会膨胀到巨大的大小。



事实证明,带有华擎H81M-DGS主板的Kraftway BIOS非常任性。因此,它通过挂起来响应Ctrl Alt Del Del,只有Reset可以从中输出它。在Shell'e中跳过启动脚本<startup.nsh>时存在问题-一秒钟即可选择,而不是五个默认脚本。也许这些问题是由KSS专有模块的修改引起的,或者此问题是错误地“拧松了” ME。

在华硕H97-PLUS板上,固件具有以下功能-BootOrder随时间溢出。原因很可能是因为代码中的错误。尽管也许制造商希望将所有已连接的引导设备保留在板上,但并没有计算出一天内可能会有十几个引导设备。因此,当BootOrder溢出时,系统会在引导过程中挂起。要清洁它,您必须关闭所有引导设备并打开系统。固件会自行清除,系统会直接引导进入BIOS Setup Shell。性能将一直保持到下一次溢出为止。

总结与不同供应商的董事会合作的经验,您得出的结论是,即使已经采用了众所周知的模型,也几乎不可能找出您将在下一个董事会上处理的EFI级别上有什么意外之处。这是一种彩票,因为有时在收集有关系统的信息时可能会遇到困难。也许这对制造商有着不可磨灭的研究理想主义和信念,因为当在其上运行旧版本的FPT或MEInfo时,带有ME v11和v12的一些最新的主板又会如何挂起?

硬件协议的工作问题




当我们开始使用USB设备时,会弹出一些问题-驱动器和令牌。发生这种情况的原因通常是:与外设一起使用的BIOS代码是独立硬件供应商(IHV)针对特定外设的驱动程序和应用程序的危险混合物,芯片组制造商(在我们的情况下为Intel)的代码,BIOS制造商的代码和代码由主板制造商提供。

出现以下“有趣”情况:

令牌“未检测到”。同时,LED点亮。最有可能的是,主机控制器没有经过USB设备的初始重置过程,也就是没有供电,但是通过更改D +和D-线进行的重置无法正常工作,并且如果没有它,使用令牌进行任何进一步的操作都是没有意义的。

在装入外壳之前,计算机将冻结(再次,连接了令牌)。在这种情况下,如果没有令牌,PC将正常启动。 Live,看起来像这样:计算机似乎在启动后立即崩溃,而令牌仍在连接器中伸出。您将其取出-加载突然继续。连接-再次挂起。显而易见的问题是在UEFI中,人们只能推测其原因。

无法打开USB_IO接口的情况。也许它仅与用于智能卡的接口-USB CCID连接。某些AMI驱动程序已经使用EFI_OPEN_PROTOCOL_BY_DRIVER参数打开了USB_IO。驱动程序具有带有GUID的协议:

#define EFI_AMI_USB_CCID_PROTOCOL_GUID	 { 0x5FDEE00D, 0xDA40, 0x405A, { 0xB9, 0x2E, 0xCF, 0x4A, 0x80, 0xEA, 0x8F, 0x76} }
 // Workaround.      EFI_OPEN_PROTOCOL_BY_DRIVER,  ,     EFI_OPEN_PROTOCOL_GET_PROTOCOL.
 //
 // Open USB I/O Protocol
 //
 Status = gBS->OpenProtocol (
 ControllerHandle,
 &gEfiUsbIoProtocolGuid,
 (VOID **) &UsbIo,
 This->DriverBindingHandle,
 ControllerHandle,
 EFI_OPEN_PROTOCOL_BY_DRIVER
 );

 if (EFI_ACCESS_DENIED == Status)
 {		// AMI BIOS workaround (BindingStop will not be invoked)
	 Status = gBS->OpenProtocol(
		 ControllerHandle,
		 &gEfiUsbIoProtocolGuid,
		 (VOID **)&UsbIo,
		 This->DriverBindingHandle,
		 ControllerHandle,
		 EFI_OPEN_PROTOCOL_GET_PROTOCOL
	 );
 }

但是,不会调用BindingStop(),即设备提取事件不受监视,驱动程序将尝试使用无效的句柄。 HP Compaq Elite 8300 SFF PC和其他一些计算机已观察到这种情况。这或者是供应商对有害驱动程序的保护,还是一种常规的开发错误。也许AMI一直在朝着USB CCID的方向做一些事情,但是干扰驱动程序无法卸载,因为它与USB HID,USB MassStorage一起位于同一AMI UHCI模块中。与UninstallInterface()相似。

或另一个有趣的功能。在未检测到令牌的UEFI BIOS之一中,USB_IO允许读取设备描述符,但EFI_INVALID_PARAMETER返回到下一个UsbBulkTransfer()。而且,这仅在某些类型的令牌(具有绝对相同的参数)上发生,而其他令牌则运行完美。

通常,有趣的是,协议UsbBulkTransfer()是在EFI_USB_IO_PROTOCOL协议中实现的。它旨在保证无限制的时间或超时参数中指定的时间的包交付。但是对MassStorage设备进行了一项实验:将大文件复制到USB闪存驱动器时,该文件已被删除。PC挂紧。连接USB闪存驱动器时,PC下垂并继续写入文件,好像什么都没发生。令牌也有相同的情况,但有其自身的特点。这是一个体系结构问题,在EFI中,除了计时器外没有其他中断,并且设备根据轮询进行操作。也就是说,系统在USB轮询中的某处崩溃,但没有达到超时,当设备重新出现时,它只是继续并完成了操作。

虚拟化


我们还应该谈谈虚拟环境。当前市场上有两个支持EFI环境仿真的主要平台:VMware和VirtualBox。与“真实”系统进行交互时,两者都有其优点和缺点。 VMware环境可以充分使用NVRAM变量,但是在DXE模块初始化期间以可视方式显示消息时会迷迷糊糊:在最佳情况下,将优先考虑有关查找可引导媒体的本机消息,而忽略了我们所需的内容。相反,VirtualBox完美地呈现了所需的所有内容,但不想记住长变量。

VMware花园中的另一块小石头-内置的FAT32驱动程序仅支持8.3表示法的文件创建和编辑。目前尚不清楚为什么要这样做,但这显然需要引起注意。在真实平台上可能会观察到类似的驱动程序实现,但到目前为止,我们还没有遇到过。

另一方面,在虚拟机中,固件实用程序,编程器,跳线和不舒服的芯片之间并没有共舞。单独的ROM文件UEFITool和配置文件中的一行。几乎是田园诗。

到底



来自CHIPSEC的一部分请求。他们在哪里教这些圣礼?

如前所述,UEFI Shell中的开发和实现是一个引人入胜的创新过程。即使在著名的领域,您也总是可以遇到新的事物。一方面,令人鼓舞的是该标准正在制定中,另一方面,令人遗憾的是,生产者对其的具体实施过于“创造性”。

主要问题是而且仍然存在:

  1. 在开发固件时,供应商会脱离UEFI规范。
  2. 实施期间代码中的错误。
  3. NDV代码,在集成过程中弹出。

最后但并非最不重要的一点是,官方(阅读,开放)文档中没有很多内容,例如,对通过PCI设备(例如MEI,HECI)与ME通信的协议的说明。您可以找到寄存器的描述,但不能找到命令。找到一个GUID,但找不到其目的。这再次使工作返回到长时间的分析,在平台上收集数据和统计数据并使用反汇编程序。

应该指出的是,这种情况正在缓慢但肯定会得到纠正,我想相信,标准的制定将成为相当可预测且非常令人愉快的过程的时机已经不远了。 Gazinformservice LLC 的硬件和软件保护产品小组负责人

Vladimir Onipchuk


All Articles