【欄目介紹:“玩轉OurBMC”是OurBMC社區開創的知識分享類欄目,主要聚焦於社區和BMC全棧技術相關基礎知識的分享,全方位涵蓋了從理論原理到實踐操作的知識傳遞。OurBMC社區將通過“玩轉OurBMC”欄目,幫助開發者們深入瞭解到社區文化、理念及特色,增進開發者對BMC全棧技術的理解。
歡迎各位關注“玩轉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社區官方網站:
https://www.ourbmc.cn/