<p>【栏目介绍:“玩转OurBMC”是OurBMC社区开创的知识分享类栏目,主要聚焦于社区和BMC全栈技术相关基础知识的分享,全方位涵盖了从理论原理到实践操作的知识传递。OurBMC社区将通过“玩转OurBMC”栏目,帮助开发者们深入了解到社区文化、理念及特色,增进开发者对BMC全栈技术的理解。</p>
欢迎各位关注“玩转OurBMC”栏目,共同探索OurBMC社区的精彩世界。同时,我们诚挚地邀请各位开发者向“玩转OurBMC”栏目投稿,共同学习进步,将栏目打造成为汇聚智慧、激发创意的知识园地。】
在服务器产品交付阶段, BMC、BIOS及CPLD等核心固件的初始烧录通常采用离线编程方式,通过专用烧录器将固件镜像写入存储介质。随着服务器进入运维阶段,为应对安全漏洞修复、功能增强或硬件兼容性更新等需求,管理人员需借助远程管理接口实现固件升级。OpenBMC作为开源基板管理控制器固件框架,其设计的远程更新机制兼顾了灵活性与可靠性。本文将深入剖析OpenBMC在固件远程更新场景下的核心实现机制,重点解析其BMC固件单分区与A/B分区的更新流程、底层脚本的协作关系,以及通过总线接管更新BIOS/CPLD的硬件交互原理。
01 BMC固件更新
作为服务器管理核心组件,BMC固件本质上是针对特定硬件平台定制的嵌入式Linux系统,其软件栈由三个部分组成:负责硬件初始化和系统启动引导的 Bootloader (如U-Boot)、Linux内核以及包含OpenBMC服务与应用的根文件系统。在金融、电信等对可用性要求极高的行业中,为防止因BMC固件损坏导致服务器失去远程管理能力,会采用双物理Flash芯片的设计。这两个Flash通过CPLD或硬件多路复用器控制,可实现故障时自动切换。而在主流的OpenBMC平台方案中,为控制成本,通常只使用一颗Flash芯片,采用单分区方案,或A/B分区方案来保障固件可靠性。下图为OpenBMC平台上BMC固件的更新流程:

单分区方案:
在单分区方案中, BMC固件的所有组件只有单一副本,典型分区布局如下表所示:

在这种方案下更新 BMC固件时,管理员需要将完整的BMC系统镜像image-bmc上传到/run/initramfs/目录。执行reboot命令后,系统直接调用/run/initramfs/shutdown脚本,该脚本首先确保/proc等内核接口可用,以完成运行环境准备,接着彻底卸载所有与旧根目录关联的文件系统,确保Flash存储设备完全处于未被占用状态。随后检测更新镜像是否存在,一旦确认存在便启动看门狗机制防止意外重启,最后调用update脚本执行固件烧录,并通过reboot -f完成硬件重启。
update脚本作为更新操作的核心执行者,其功能主要包括安全校验、数据备份和烧录执行。在安全校验方面,它通过findmtd()确保目标分区正确,使用toobig()防止镜像溢出,并通过mtdismounted()确保分区未被挂载。在数据备份方面,脚本提供–save-files和–restore-files功能,读取/run/initramfs/whitelist文件,将rwfs中的重要用户数据备份到内存安全区域,更新完成后自动恢复。最终通过flashcp -v “$f” “/dev/$m”命令完成固件烧录,并将烧录状态写入特定区域以便系统启动时感知,在一切完成后清理暂存文件和临时备份。
A/B分区方案:
单分区方案的本质是对 Flash进行全量重写。而A/B分区方案是一种更加灵活、可回退的”热更新”,这种方案为内核与根文件系统这两大核心组件分别建立了A/B两套分区,从而实现冗余。其分区布局示例如下:

02 BIOS固件更新
除了更新BMC自身,BMC还负责更新服务器主板上的其他固件。在服务器正常运行时,SPI总线由服务器CPU控制,用于访问BIOS。当需要更新时,BMC 会通过 GPIO 信号切换总线控制权,暂时成为 SPI 总线的主设备。随后,BMC通过其内部的SPI控制器,驱动这条共享的SPI总线,将固件镜像直接写入作为从设备的BIOS Flash。例如,在飞腾腾珑E2000S平台上,可通过底层命令手动完成此过程:
# 解除服务器对SPI控制器的绑定
echo 2803a000.spi > /sys/bus/platform/drivers/phytium_spi/unbind
# 通过GPIO切换总线控制权至BMC
gpioutil set CPU1_SPI_SELECT 1
# 重新绑定控制器,此时BMC成为主设备
echo 2803a000.spi > /sys/bus/platform/drivers/phytium_spi/bind
# 将BIOS镜像文件写入对应的Flash分区
flashcp -v bios.bin /dev/mtd6
# 将总线控制权归还给服务器
gpioutil set CPU1_SPI_SELECT 0
03 CPLD固件更新
CPLD固件体积虽小,却控制着服务器关键硬件逻辑(如电源时序、信号复用)。BMC通过接管JTAG总线完成其更新。正常情况下,JTAG总线由服务器CPU使用。当通过BMC发起CPLD更新时,管理员上传用于写入CPLD固件的专用编程文件(如SVF文件),BMC通过GPIO或外部多路复用器切换,临时占用JTAG总线。随后,BMC内部的JTAG控制器驱动JTAG信号,按JTAG协议将新镜像写入CPLD的非易失存储器。以飞腾平台更新国产安路科技的服务器CPLD为例,手动更新命令如下:
# 切换JTAG总线控制权至BMC
gpioutil set CPU_JTAG_SELECT 1
# 通过JTAG接口烧录SVF格式的固件文件
loadsvf -d /dev/jtag0 -v -s /tmp/jtag.svf
CPLD更新完成后,通常需要对整机或对应模块进行断电上电,新的逻辑才会被加载生效。
本期内容聚焦OpenBMC在固件更新中的底层机制:BMC自身更新可通过单分区方案实现完整系统重装,或通过A/B分区方案实现热更新;而BIOS和CPLD的更新则依靠BMC临时接管硬件总线来实现。这些底层机制虽然直接有效,但通常涉及复杂的手动操作。下期内容,我们将深入分析OpenBMC如何通过上层服务(如Redfish API和phosphor-software-manager)将这些底层操作封装起来,在Web界面上实现一键式、可审计、安全可靠的统一固件更新。
欢迎大家关注OurBMC社区,了解更多BMC技术干货。
OurBMC社区官方网站:
</div>