嵌入式Linux的OTA更新,基本原理和實現
時間:2020-05-07 來源:原創
需要更新
一旦嵌入式Linux產品離開實驗室并進入現實世界,如何更新設備的問題就變得至關重要。
更新并非總是必要的,但是很難想到沒有某個漏洞的軟件。即使您的軟件是完美的,但是如果設備通過任何開放源代碼庫在網絡或Internet上進行通信,則可能需要進行安全更新。
以CVE-2104-01650(嚴重)為例。此漏洞影響了OpenSSL加密庫,并擴展了網絡上三分之二的網站。即使到了三年后的今天,仍然有許多嵌入式Linux設備運行的是OpenSSL的非防御版本,可以廣泛攻擊。
阻止文件更新
在談論更新Linux時,您可能會看到提到了“阻止”和“文件”更新系統。這是指通過直接寫入塊設備或更新單個文件以執行更新來一次更新整個分區。您可能熟悉Desktop或Server Linux的文件更新系統(例如“ sudo apt-get upgrade”)。在嵌入式Linux中,基于模塊的升級由于其原子性以及整個文件系統通常是嵌入式Linux構建系統的輸出這一事實而成為必經之路。我們期望特定產品在每個嵌入式設備上的存儲空間是恒定的,因此我們每次都創建相同大小的分區。此類更新與具有某種后備或恢復映像配合使用。
發生故障時恢復
我們絕不希望設備處于無法使用的狀態(例如,如果發生斷電)。我們可以通過確保在更新過程中出現任何錯誤時始終可以“退回到”另一個分區來解決此問題。

圖1.發生故障時的恢復-后備選項
在上方,您可以看到電源中斷時后備模式的兩種可能實現。引導程序在左側引導應急分區,然后將其引導到主分區。在右側,Bootloader會基于開關引導兩個分區之一。
引導加載程序應實現某種確定啟動是否成功的方法,如果尚未成功,則應返回到救援分區(左圖)或先前的工作分區(右圖)。
救援方法(左手)允許為主分區提供更多空間,而雙rootfs方法(右手)要求在兩個分區之間或多或少均勻地分配空間。如果空間不成問題,則建議使用dual-rootfs方法,因為這將減少停機時間。通過救援方法進行更新需要兩次重新引導,一次重新進入救援分區,然后另一次重新進入主分區。dual-rootfs方法僅需要一次重新引導,因為可以隨時執行更新。
在這些系統中無法安全更新的是引導加載程序(或實際上是救援分區)。如果您也想更新引導加載程序,則需要兩個單獨的引導加載程序分區,以及某種Board-Management-Controller來實現兩者之間切換的邏輯。

圖2.發生故障時的恢復– Board Management Controller
當然,這是一個復雜的解決方案,需要一個額外的微控制器,一套新的固件以及更復雜的硬件設計(例如,在某些設備中使用,例如那些包含單獨的智能平臺管理接口(IPMI)控制器的設備) 。因此,您應該著眼于構建功能齊全,范圍較小且不需要更新的引導加載程序。
U-Boot環境變量
U-boot實現了一個非易失性“環境”,可以在其中存儲變量。甚至可以從Linux(可以通過多種方式來訪問它們,具體取決于環境的存儲方式,如elinux.org上所述)。
這是實現上述“開關”的最明顯方法。它也可以用于存儲有關先前啟動成功或失敗的信息,以便在啟動失敗的情況下可以反轉交換機并恢復工作分區。

圖3. U-boot環境變量
設置看門狗
處理器的硬件監視程序應該由U-Boot(CONFIG_WATCHDOG)設置,然后在啟動完成后由Linux維護。如果整個系統掛起,這將導致重置。
檢查啟動失敗
關鍵任務應用程序運行后,應在u-boot環境中設置一個變量,指示啟動完成。然后,U-boot將能夠檢查是否在下一次啟動時設置了該設置,如果啟動失敗(有時僅在連續幾次失敗之后),則可以采取措施。
具體的架構將取決于您的應用程序和產品。您將需要對此進行一些自定義,以適應您的需求。您將要確定所有可能的故障模式,并對所有故障模式實施恢復。
實施更新
正如我們之前所說,更新應以單個加密簽名文件的形式出現。私鑰簽名可確保其源自制造商您。現在,系統只需解壓縮它并運行其中的腳本即可自行執行更新。它將覆蓋要更新的分區;輕拂所需的任何開關,然后重新啟動。這應該盡快發生,以最大程度地減少停機時間。
保護更新
我們要確保提供給設備的更新文件來自制造商而不是其他人。為此,請使用制造商持有的私鑰對更新文件進行簽名。相應的公鑰保留在設備上,它將驗證要求使用其進行更新的任何更新文件。如果提供的文件被認為無效,則更新將失敗。
獲取更新
更新如何到達是另一回事。這里有四種可能性:
最明顯和最簡單的方法是,該更新是由具有root登錄到設備的工程師應用的。他運行更新腳本并更新了設備。這充滿了安全隱患,并且可能僅適用于開發中的系統或工程或工業環境中使用的系統。
物理介質已插入包含所需更新的設備(USB記憶棒)中。板上的軟件將通過輪詢守護程序或udev規則自動檢測并安裝。
通過某種方法(例如,Web應用程序)將更新文件上傳到單個計算機。
空中更新,如下一節所述。
空中更新
空中(OTA)更新通常是指通過安全通道從中央服務器更新的設備。它通常指的是物聯網設備,移動電話,汽車ECU等。在本文中,我將描述一種更新類型,該更新可以在連接到互聯網的任何設備上運行,并且可以通過Wi-Fi(空中),以太網(銅纜)或其他某種協議。
檢查更新
首先要做的是檢查更新。設備上運行的守護進程可以將請求發送到預定服務器,提供其當前版本和硬件版本。然后,服務器可以根據該信息,在必要時將簽名的更新文件發送到設備進行安裝,或者報告沒有可用的更新或不需要更新。
可以通過多種方式添加復雜性,從僅基于各種標準向設備子集提供更新,到對更新文件進行完全加密,再到將更新狀態或其他信息報告回中央服務器。
現成與內部解決方案
有許多現成的更新機制可以與嵌入式Linux系統集成,而不必如上所述重新發明輪子。可以在yocto項目中找到其中一些的比較。
這些可能需要一些時間和精力才能與您當前的嵌入式Linux構建系統集成,但是它可能比內部開發自定義方法要少一些,并且由于其中一些項目已經花費了數百小時而變得更加強大。進入他們。
為什么您不想要現成的解決方案的原因:
您希望在每個級別上為董事會自定義內容
在使用大型代碼庫時,您可能會遇到安全問題,而該代碼庫仍相對較新,并且使用或識別的程度不高
在ByteSnap Design,我們為許多不同的客戶提供了完整的硬件和軟件解決方案,我們創建了內部自定義更新系統,同時在各種不同的芯片組(例如MTS)上集成了Mender等現成的更新系統。

