玩转OurBMC第二十五期:OpenBMC固件远程更新原理与实践(上)

栏目介绍:“玩转OurBMC” 是OurBMC社区开创的知识分享类栏目,主要聚焦于社区和BMC全栈技术相关基础知识的分享,全方位涵盖了从理论原理到实践操作的知识传递。OurBMC社区将通过 “玩转OurBMC” 栏目,帮助开发者们深入了解到社区文化、理念及特色,增进开发者对BMC全栈技术的理解。

欢迎各位关注 “玩转OurBMC” 栏目,共同探索OurBMC社区的精彩世界。同时,我们诚挚地邀请各位开发者向 “玩转OurBMC” 栏目投稿,共同学习进步,将栏目打造成为汇聚智慧、激发创意的知识园地。

在服务器产品交付阶段,BMC、BIOS及CPLD等核心固件的初始烧录通常采用离线编程方式,通过专用烧录器将固件镜像写入存储介质。随着服务器进入运维阶段,为应对安全漏洞修复、功能增强或硬件兼容性更新等需求,管理人员需借助远程管理接口实现固件升级。OpenBMC作为开源基板管理控制器固件框架,其设计的远程更新机制兼顾了灵活性与可靠性。本文将深入剖析OpenBMC在固件远程更新场景下的核心实现机制,重点解析其BMC固件单分区与A/B分区的更新流程、底层脚本的协作关系,以及通过总线接管更新BIOS/CPLD的硬件交互原理。

01 BMC固件更新

单分区方案:

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

分区名

设备节点

用途说明

bmc

/dev/mtd0

用于更新完整的BMC固件镜像

u-boot

/dev/mtd1

U-Boot 主体

u-boot-env

/dev/mtd2

U-Boot 环境变量

kernel

/dev/mtd3

Linux Kernel

rofs

/dev/mtd4

只读的根文件系统

rwfs

/dev/mtd5

可写覆盖层,存放用户配置和运行时数据

在这种方案下更新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两套分区,从而实现冗余。其分区布局示例如下:

分区名

设备节点

用途说明

u-boot

/dev/mtd1

U-Boot 主体

u-boot-env

/dev/mtd2

U-Boot 环境变量

kernel_a

/dev/mtd3

Linux Kernel A

kernel_b

/dev/mtd4

Linux Kernel B

rofs_a

/dev/mtd5

只读的根文件系统A

rofs_b

/dev/mtd6

只读的根文件系统B

rwfs

/dev/mtd7

可写覆盖层,在A/B系统间共享,存放用户配置和运行时数据

当需要更新时,BMC可以在后台将新的内核或文件系统写入当前未运行的分区(例如B分区),整个过程系统服务不中断。写入完成后,只需修改U-Boot的启动标志,下次重启时便会引导至新的B分区,完成镜像切换。如果新系统启动失败,还可以切回已知正常的A分区,实现回退。这种方案的最大优势在于支持组件增量更新,无需上传完整的系统镜像。

单分区方案通过全量重写Flash实现系统更新,操作直接但风险较高;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社区官方网站:

https://www.ourbmc.cn/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值