標籤:

UEFI 固件更新

固件更新對於我們來說都不陌生。那麼什麼是UEFI Capsule Update呢?Capsule,顧名思義,是「膠囊」的意思,所以UEFI Capsule Update可以理解為膠囊式固件更新。我們今天來談談UEFI Capsule Update 的實現過程。

UEFI規範定義了Firmware Management協議(FMP)、capsule格式以及EFI System Resource Table (ESRT) 用於支持系統和設備固件更新。使用FMP協議可以獲取固件信息並且把ESRT報告給OS。

出於安全性考慮,Flash設備在系統啟動時是鎖住的,所以在操作系統中直接更新Flash是行不通的。

Direct Flash Update

如下圖所示,一個可行的辦法是操作系統把待更新的固件信息發送至系統固件,在下一次啟動過程中,系統在Flash設備上鎖前更新固件。這個待更新的固件就被稱作「capsule」。需要注意的是,capsule不僅僅用來做固件更新,還用於OS傳遞信息至固件。UEFI規範定義了一些capsule services,比如,操作系統調用UpdateCapsule()傳遞capsule image至固件,固件根據capsule flag決定立即處理capsule還是重啟後再處理。總結一下,膠囊式固件更新是在編譯階段把到更新的固件封裝成capsule,由OS傳遞capsule image至系統固件,然後由系統固件來處置待更新的capsule。

固件更新實現過程

0. 操作系統模塊調用Capsule Runtime服務EFI_RUNTIME_SERVICES.UpdateCapsule()傳遞帶有reset屬性的Capsule image至系統固件,這時系統更需要做一次重啟。需要注意的是,此時的重啟並非真正的重啟,而是走了S3的路徑,主要是為了利用S3狀態memory不丟失,這樣capsule image就可以一直保存在memory中。

1. 重啟時,平台PEI模塊調用PEI_CAPSULE_PPI.CheckCapsuleUpdate()判斷是否有Capsule固件待處理。CapsulePei模塊讀取「CapsuleUpdateDate」Variable檢測是否有capsule在memory中,如果條件滿足,PEI模塊將會把啟動模式設置為BOOT_ON_FLASH_UPDATE。

2. Memory初始化完成後,PEI module調用PEI_CAPSULE_PPI.Coalesce()判斷一系列Capsule片段的當前位置,把它們合併成一個連續的內存區域,把合併後的capsule拷貝至PEI memory中並且創建EFI_HOB_UEFI_CAPUSLE.

操作系統為capsule image分配的是連續的虛擬地址空間,而實際上則是一系列不連續的物理地址區域片段。OS會把虛擬地址以及物理地址一併傳遞到固件。這樣固件可以立即處理或者在重啟後處理capsule。如下圖所示,左邊是OS的角度看到的存放capsule的連續虛擬地址空間,中間的圖表示capsule在系統內存中實際分布。最右邊是傳遞至固件的Capsule block descriptor scatter gather list。Capsule Coalesce會遍歷這個list,把所有capsule片段組合在一起放在連續的系統內存中。

3. 進入BDS階段後,BDS判斷當前啟動模式如果為BOOT_ON_FLASH_UPDATE,則調用CapsuleLib:ProcessCapsules()處理Capsule image。第一次調用需在EFI_END_OF_DXE_EVENT之前,因為系統flash設備會在EFI_END_OF_DXE_EVENT之後鎖住。

4. ProcessCapsules() 通過CAPSULE_HOB獲取滿足條件的capsule images,如果capsule image是UEFI FMP格式的capsule,則調用ProcessFmpCapsuleImage()。

5. ProcessFmpCapsuleImage()調用FMP協議介面Fmp->GetImageInfo()獲取固件信息並且和FMP capsule對比。只有滿足了一系列驗證條件後,比如簽名驗證,ProcessFmpCapsuleImage()才會調用Fmp->SetImage()執行固件更新。更新成功後,需設置capsule status variable避免同一個capsule image下次仍然被執行。

認證檢測

固件在更新前必須按照NIST(National Institute of Standards and Technology)標準完成一些認證檢測,比如簽名認證。待更新capsule必須經過簽名,更新機制才可以判斷待更新內容是否可信。UEFI capsule 使用EFI_FIRMWARE_IMAGE_AUTHENTICATION認證,認證信息為PKCS7簽名。固件更新機制從系統固件中提取可信證書,用可信證書驗證PKCS7簽名。如果capsule沒有使用EFI_FIRMWARE_IMAGE_AUTHENTICATION認證或者認證失敗,此capsule不會被用來更新固件。具體請參考:

github.com/tianocore/ed

以上就是UEFI Capsule Update的簡單介紹。感興趣的同學請參考代碼繼續學習。

歡迎大家關注本專欄和用微信掃描下方二維碼加入微信公眾號"UEFIBlog",在那裡有最新的文章。同時歡迎大家給本專欄和公眾號投稿!

用微信掃描二維碼加入UEFIBlog公眾號


推薦閱讀:

一起學習電腦如何睡眠S3
CPU省電的秘密(二):CStates
如何在ubuntu下重建被grub覆蓋的win10引導區?
UEFI 引導與 BIOS 引導在原理上有什麼區別?
UEFI+GPT與BIOS+MBR各自有什麼優缺點?

TAG:UEFI | 固件 |