在嵌入式系統(tǒng)(尤其是Rockchip平臺Android設(shè)備)中,A/B(Seamless Update)無縫更新是保障系統(tǒng)更新不丟數(shù)據(jù)、更新失敗可回滾的核心機(jī)制。而SPL(Secondary Program Loader,二級程序加載器)作為系統(tǒng)啟動的早期階段,負(fù)責(zé)初始化硬件、選擇啟動分區(qū),spl_ab.c正是SPL層處理A/B分區(qū)啟動的核心代碼。本文將從函數(shù)解析、核心流程、開發(fā)意義三個維度,徹底拆解這段代碼。
一、A/B分區(qū)與SPL的核心作用
A/B分區(qū)將系統(tǒng)分為兩個獨立的槽位(Slot A/Slot B),更新時先更新非當(dāng)前啟動的槽位,更新完成后切換槽位啟動;若啟動失敗,自動回退到原槽位。
SPL是BootLoader的早期階段,執(zhí)行優(yōu)先級最高,spl_ab.c的核心目標(biāo)是:讀取A/B元數(shù)據(jù)、判斷槽位可啟動性、選擇最優(yōu)啟動槽位、處理啟動失敗后的嘗試次數(shù)遞減與系統(tǒng)重置。
二、核心函數(shù)分類解析
代碼中的函數(shù)可分為7大類,覆蓋“基礎(chǔ)工具→元數(shù)據(jù)處理→槽位管理→啟動流程”全鏈路,以下是關(guān)鍵函數(shù)的作用拆解:
1.基礎(chǔ)工具函數(shù):解決通用問題
|
函數(shù)名
|
核心作用
|
|
safe_memcmp
|
安全的內(nèi)存比較,無數(shù)據(jù)依賴分支(避免側(cè)信道攻擊),返回兩內(nèi)存區(qū)域是否不相等(0=相等,非0=不等)
|
|
htobe32
|
主機(jī)字節(jié)序→大端字節(jié)序轉(zhuǎn)換(A/B元數(shù)據(jù)存儲為大端)
|
|
be32toh
|
大端字節(jié)序→主機(jī)字節(jié)序轉(zhuǎn)換(讀取元數(shù)據(jù)后適配本地CPU)
|
2. A/B元數(shù)據(jù)處理:校驗/更新/初始化
A/B元數(shù)據(jù)(AvbABData)存儲在misc分區(qū),包含槽位優(yōu)先級、剩余嘗試次數(shù)、啟動成功標(biāo)記等關(guān)鍵信息,這組函數(shù)是元數(shù)據(jù)操作的核心:
|
函數(shù)名
|
核心作用
|
|
spl_ab_data_verify_and_byteswap
|
校驗元數(shù)據(jù)合法性:
|
|
spl_ab_data_update_crc_and_byteswap
|
更新元數(shù)據(jù)的CRC32:先拷貝數(shù)據(jù),再計算CRC32并轉(zhuǎn)換為大端序(用于寫入存儲)
|
|
spl_ab_data_init
|
初始化默認(rèn)元數(shù)據(jù):
|
3.元數(shù)據(jù)讀寫:對接存儲層
|
函數(shù)名
|
核心作用
|
|
spl_read_ab_metadata
|
從misc分區(qū)指定偏移讀取元數(shù)據(jù)到內(nèi)存(單次讀512字節(jié),適配塊設(shè)備讀寫粒度)
|
|
spl_write_ab_metadata
|
將內(nèi)存中的元數(shù)據(jù)寫入misc分區(qū)指定偏移
|
|
spl_ab_data_read
|
封裝“讀取+校驗”:讀取失敗/校驗失敗時,初始化新元數(shù)據(jù)并寫入misc分區(qū)
|
|
spl_ab_data_write
|
封裝“更新CRC+寫入”:先更新CRC32,再寫入存儲
|
4.槽位選擇:核心決策邏輯
|
函數(shù)名
|
核心作用
|
|
spl_slot_is_bootable
|
判斷槽位是否可啟動:優(yōu)先級>0且(已成功啟動 或 剩余嘗試次數(shù)>0)
|
|
spl_get_lastboot
|
獲取上次啟動的槽位索引(0=A,1=B)
|
|
spl_get_current_slot
|
選擇當(dāng)前要啟動的槽位(核心函數(shù)):
|
5.分區(qū)名處理:適配槽位后綴
|
函數(shù)名
|
核心作用
|
|
spl_ab_append_part_slot
|
給分區(qū)名追加槽位后綴(如boot→boot_a);misc分區(qū)例外(無后綴);獲取槽位失敗時直接返回原分區(qū)名
|
6.槽位狀態(tài)管理:處理啟動失敗
|
函數(shù)名
|
核心作用
|
|
spl_slot_set_unbootable
|
標(biāo)記槽位為不可啟動:優(yōu)先級、剩余嘗試次數(shù)、啟動成功標(biāo)記全置0
|
|
spl_slot_normalize
|
規(guī)范化槽位狀態(tài)(處理非法場景):
|
|
spl_ab_decrease_tries
|
啟動失敗時減少當(dāng)前槽位嘗試次數(shù):
|
|
spl_ab_decrease_reset
|
啟動失敗后重置系統(tǒng):
|
7.啟動參數(shù)傳遞:對接內(nèi)核
|
函數(shù)名
|
核心作用
|
|
spl_ab_bootargs_append_slot
|
給設(shè)備樹(FDT)的啟動參數(shù)(bootargs)追加槽位后綴(如android.slot_suffix=_a),讓內(nèi)核感知當(dāng)前啟動槽位
|
三、SPL階段A/B啟動核心流程圖

四、開發(fā)者關(guān)注這段代碼的核心意義
對于嵌入式開發(fā)者(尤其是Rockchip/Android BootLoader開發(fā)者),理解spl_ab.c是保障A/B啟動穩(wěn)定的關(guān)鍵,核心價值體現(xiàn)在5個方面:
1.快速定位啟動故障
當(dāng)設(shè)備出現(xiàn)“A/B啟動失敗、卡在SPL階段、槽位切換異常”時,可通過代碼日志(如“CRC32 does not match”“No bootable slots found”)定位根因:
?元數(shù)據(jù)CRC不匹配:misc分區(qū)損壞,spl_ab_data_read會自動初始化元數(shù)據(jù);
?無可用槽位:兩槽位嘗試次數(shù)耗盡,需手動重置元數(shù)據(jù);
?槽位被標(biāo)記為不可啟動:檢查spl_slot_normalize是否觸發(fā)了非法狀態(tài)處理。
2.定制A/B更新策略
默認(rèn)邏輯可根據(jù)產(chǎn)品需求調(diào)整:
?調(diào)整默認(rèn)優(yōu)先級/嘗試次數(shù):修改spl_ab_data_init中的AVB_AB_MAX_PRIORITY/AVB_AB_MAX_TRIES_REMAINING;
?自定義槽位選擇規(guī)則:修改spl_get_current_slot(如優(yōu)先級相同時選上次啟動的槽位,而非默認(rèn)的Slot A);
?調(diào)整啟動失敗后的行為:修改spl_ab_decrease_reset(如增加重試次數(shù)閾值,或取消自動重置)。
3.適配不同硬件平臺
不同存儲設(shè)備(eMMC/NAND/SD卡)的塊設(shè)備讀寫(blk_dread/blk_dwrite)邏輯有差異,需確保spl_read/write_ab_metadata適配硬件;不同CPU架構(gòu)的字節(jié)序可能不同,需驗證htobe32/be32toh的正確性。
4.提升系統(tǒng)穩(wěn)定性
?safe_memcmp避免側(cè)信道攻擊,提升元數(shù)據(jù)比較的安全性;
?spl_save_metadata_if_changed僅在元數(shù)據(jù)變化時寫入存儲,減少misc分區(qū)的寫操作,延長存儲壽命;
?spl_slot_normalize處理非法狀態(tài),避免因元數(shù)據(jù)異常導(dǎo)致的啟動邏輯崩潰。
5.適配Android無縫更新標(biāo)準(zhǔn)
Android A/B無縫更新的核心是槽位管理,這段代碼是SPL層對接Android A/B規(guī)范的關(guān)鍵,確保更新后能正確切換槽位啟動,失敗時自動回滾,符合Google的A/B更新標(biāo)準(zhǔn)。
五、總結(jié)
spl_ab.c是SPL階段A/B分區(qū)啟動的“大腦”,從元數(shù)據(jù)讀寫、槽位決策到啟動失敗處理,覆蓋了A/B啟動的全核心流程。對于嵌入式開發(fā)者而言,理解這段代碼不僅能快速定位啟動故障,還能根據(jù)產(chǎn)品需求定制更新策略,保障設(shè)備在無縫更新場景下的穩(wěn)定性與兼容性。
無論是調(diào)試A/B啟動問題,還是適配新硬件平臺,spl_ab.c都是必須深入掌握的核心模塊——它是連接硬件初始化與系統(tǒng)啟動的關(guān)鍵橋梁,也是保障Android無縫更新落地的基礎(chǔ)。
-
Android
+關(guān)注
關(guān)注
12文章
4024瀏覽量
133973 -
嵌入式系統(tǒng)
+關(guān)注
關(guān)注
41文章
3747瀏覽量
133622 -
代碼
+關(guān)注
關(guān)注
30文章
4967瀏覽量
73958 -
spl
+關(guān)注
關(guān)注
0文章
22瀏覽量
16754 -
Rockchip
+關(guān)注
關(guān)注
0文章
92瀏覽量
19577
發(fā)布評論請先 登錄
Microchip 93XX56A/B/C系列2K Microwire兼容串行EEPROM深度解析
實戰(zhàn)排障|RK平臺啟動卡死、SPL崩潰,兩行日志直接定位DDR硬件死穴!
Microchip 93XX66A/B/C系列4Kbit低電壓串行EEPROM深度解析
U-Boot SPL核心文件spl.c深度解析:從啟動流程到調(diào)試優(yōu)化
深入解析U-Boot TPL代碼:嵌入式啟動的“第一棒”背后的秘密
深入解析rk平臺Android Bootloader核心代碼:從啟動流程到AVB驗證
德州儀器LM5100A/B/C和LM5101A/B/C系列高壓柵極驅(qū)動器的深度解析
Texas Instruments LM5100A/B/C和LM5101A/B/C高壓柵極驅(qū)動器深度解析
d1哪吒開發(fā)板的啟動流程分析
國產(chǎn)!全志T113-i 雙核Cortex-A7@1.2GHz 工業(yè)開發(fā)板—eMMC配置核心板使用說明(二)
深度解析SPL階段A/B分區(qū)啟動:spl_ab.c代碼全拆解
評論