Android 10 及更高版本通過將 fastboot 實現從引導加載程序重新定位到用戶空間來支持可調整大小的分區。這種重新定位允許將閃存代碼移動到可維護和可測試的公共位置,只有硬件抽象層 (HAL) 實現的 fastboot 的供應商特定部分。此外,Android 12 及更高版本支持通過添加的 fastboot 命令刷新 ramdisk。
統一快速啟動和恢復
因為用戶空間的快速啟動和恢復是相似的,你可以將它們合併到一個分區或二進製文件中。這提供了一些優勢,例如使用更少的空間、總體上具有更少的分區以及讓 fastboot 和 recovery 共享它們的內核和庫。
為了支持fastbootd
,引導加載程序必須實現一個新的引導控制塊 (BCB) 命令boot-fastboot
。為了進入fastbootd
模式,bootloader 將boot-fastboot
寫入 BCB 消息的命令字段,並保持 BCB 的recovery
字段不變(以啟用重新啟動任何中斷的恢復任務)。 status
、 stage
和reserved
字段也保持不變。在 BCB 命令字段中看到boot-fastboot
後,引導加載程序加載並引導到恢復映像。然後,Recovery 會解析 BCB 消息並切換到fastbootd
模式。
亞行命令
本節介紹用於集成fastbootd
的adb
命令。該命令具有不同的結果,具體取決於它是由系統執行還是由恢復執行。
命令 | 描述 |
---|---|
reboot fastboot |
|
快速啟動命令
本節介紹用於集成fastbootd
的 fastboot 命令,包括用於刷新和管理邏輯分區的新命令。某些命令有不同的結果,具體取決於它們是由 bootloader 還是由fastbootd
執行的。
命令 | 描述 |
---|---|
reboot recovery |
|
reboot fastboot | 重新啟動到fastbootd 。 |
getvar is-userspace |
|
getvar is-logical: <partition> | 如果給定分區是邏輯分區,則返回yes ,否則返回no 。邏輯分區支持下面列出的所有命令。 |
getvar super-partition-name | 返回超級分區的名稱。如果超級分區是 A/B 分區(通常不是),則名稱包括當前插槽後綴。 |
create-logical-partition <partition> <size> | 創建具有給定名稱和大小的邏輯分區。該名稱不能作為邏輯分區存在。 |
delete-logical-partition <partition> | 刪除給定的邏輯分區(有效擦除分區)。 |
resize-logical-partition <partition> <size> | 將邏輯分區的大小調整為新大小,而不更改其內容。如果沒有足夠的可用空間來執行調整大小,則會失敗。 |
update-super <partition> | 合併對超級分區元數據的更改。如果無法進行合併(例如,設備上的格式是不受支持的版本),則此命令將失敗。可選的wipe 參數覆蓋設備的元數據,而不是執行合併。 |
flash <partition> [ <filename> ] | 將文件寫入閃存分區。設備必須處於解鎖狀態。 |
erase <partition> | 擦除分區(不需要安全擦除)。設備必須處於解鎖狀態。 |
getvar <variable> | all | 顯示引導加載程序變量或所有變量。如果變量不存在,則返回錯誤。 |
set_active <slot> | 將給定的 A/B 引導槽設置為 對於 A/B 支持,插槽是可以獨立引導的重複分區集。插槽被命名為 |
reboot | 正常重啟設備。 |
reboot-bootloader (或reboot bootloader ) | 將設備重新啟動到引導加載程序。 |
fastboot fetch vendor_boot <out.img> | 在Android 12 及更高版本中使用以支持刷新供應商 ramdisk。 獲取整個分區大小和塊大小。獲取每個塊的數據,然後將數據拼接到 有關詳細信息,請參閱 |
fastboot flash vendor_boot:default <vendor-ramdisk.img> | 在Android 12及更高版本中使用以支持刷新供應商 ramdisk。 這是 flash 命令的特殊變體。它執行 有關詳細信息,請參閱 |
fastboot flash vendor_boot: <foo> <vendor-ramdisk.img> | 在Android 12及更高版本中使用以支持刷新供應商 ramdisk。 獲取 有關詳細信息,請參閱 |
快速啟動和引導加載程序
bootloader 會bootloader
、 radio
和boot/recovery
分區,之後設備啟動到 fastboot(用戶空間)並刷新所有其他分區。引導加載程序應支持以下命令。
命令 | 描述 |
---|---|
download | 將圖像下載到閃存。 |
flash recovery <image> / flash boot <image> / flash bootloader <image> / | 刷新recovery/boot 分區和引導加載程序。 |
reboot | 重新啟動設備。 |
reboot fastboot | 重新啟動到快速啟動。 |
reboot recovery | 重新啟動以恢復。 |
getvar | 獲取刷新恢復/引導映像所需的引導加載程序變量(例如current-slot 和max-download-size )。 |
oem <command> | OEM 定義的命令。 |
動態分區
引導加載程序不得允許對動態分區進行刷新或擦除,並且在嘗試執行這些操作時必須返回錯誤。對於改裝的動態分區設備,fastboot 工具(和引導加載程序)支持強制模式,以便在引導加載程序模式下直接刷新動態分區。例如,如果system
是改裝設備上的動態分區,則使用fastboot --force flash system
命令啟用引導加載程序(而不是fastbootd
)來刷新分區。
關機模式充電
如果設備支持關閉模式充電或在通電時自動啟動到特殊模式,則fastboot oem off-mode-charge 0
命令的實現必須繞過這些特殊模式,以便設備像用戶按下一樣啟動電源按鈕。
快速啟動 OEM HAL
要完全替換 bootloader fastboot,fastboot 必須處理所有現有的 fastboot 命令。其中許多命令來自 OEM 並已記錄在案,但需要自定義實現。許多 OEM 特定的命令未記錄在案。為了處理此類命令,fastboot HAL 指定了所需的 OEM 命令。 OEM 還可以實現自己的命令。
fastboot HAL的定義如下:
import IFastbootLogger;
/**
* IFastboot interface implements vendor specific fastboot commands.
*/
interface IFastboot {
/**
* Returns a bool indicating whether the bootloader is enforcing verified
* boot.
*
* @return verifiedBootState True if the bootloader is enforcing verified
* boot and False otherwise.
*/
isVerifiedBootEnabled() generates (bool verifiedBootState);
/**
* Returns a bool indicating the off-mode-charge setting. If off-mode
* charging is enabled, the device autoboots into a special mode when
* power is applied.
*
* @return offModeChargeState True if the setting is enabled and False if
* not.
*/
isOffModeChargeEnabled() generates (bool offModeChargeState);
/**
* Returns the minimum battery voltage required for flashing in mV.
*
* @return batteryVoltage Minimum battery voltage (in mV) required for
* flashing to be successful.
*/
getBatteryVoltageFlashingThreshold() generates (int32_t batteryVoltage);
/**
* Returns the file system type of the partition. This is only required for
* physical partitions that need to be wiped and reformatted.
*
* @return type Can be ext4, f2fs or raw.
* @return result SUCCESS if the operation is successful,
* FAILURE_UNKNOWN if the partition is invalid or does not require
* reformatting.
*/
getPartitionType(string partitionName) generates (FileSystemType type, Result result);
/**
* Executes a fastboot OEM command.
*
* @param oemCmd The oem command that is passed to the fastboot HAL.
* @response result Returns the status SUCCESS if the operation is
* successful,
* INVALID_ARGUMENT for bad arguments,
* FAILURE_UNKNOWN for an invalid/unsupported command.
*/
doOemCommand(string oemCmd) generates (Result result);
};
啟用快速啟動
要在設備上啟用fastbootd
:
將
fastbootd
添加到device.mk
中的PRODUCT_PACKAGES
中:PRODUCT_PACKAGES += fastbootd
。確保將 fastboot HAL、啟動控制 HAL 和運行狀況 HAL 打包為恢復映像的一部分。
添加
fastbootd
所需的任何特定於設備的 SEPolicy 權限。例如,fastbootd
需要對特定於設備的分區進行寫訪問才能刷新該分區。此外,fastboot HAL 實施可能還需要特定於設備的權限。
要驗證用戶空間快速啟動,請運行供應商測試套件 (VTS) 。
刷新供應商 ramdisk
Android 12 及更高版本通過添加的 fastboot 命令提供對閃存 ramdisk 的支持,該命令可從設備中提取完整的vendor_boot
映像。該命令提示主機端快速啟動工具讀取供應商啟動標頭、重新映像並刷新新映像。
為了提取完整的vendor_boot
映像,命令fetch:vendor_boot
被添加到 fastboot 協議和 Android 12 中該協議的 fastbootd 實現中。請注意,fastbootd確實實現了這一點,但引導加載程序本身可能沒有。 OEM 可以將fetch:vendor_boot
命令添加到協議的引導加載程序實現中。但是,如果在引導加載程序模式下無法識別該命令,則在引導加載程序模式下刷新各個供應商 ramdisk 不是供應商支持的選項。
引導加載程序更改
命令getvar:max-fetch-size
和fetch:name
在fastbootd
中實現。要在引導加載程序中支持刷新供應商 ramdisk,您必須實現這兩個命令。
快速啟動更改
getvar:max-fetch-size
類似於max-download-size
。它指定設備可以在一個 DATA 響應中發送的最大大小。驅動程序不得獲取大於此值的大小。
fetch:name[:offset[:size]]
在設備上執行一系列檢查。如果滿足以下所有條件,則fetch:name[:offset[:size]]
命令返回數據:
- 該設備正在運行可調試的構建。
- 設備已解鎖(啟動狀態為橙色)。
- 獲取的分區名稱是
vendor_boot
。 -
size
值在 0 <size
<=max-fetch-size
範圍內。
驗證這些後, fetch:name[:offset[:size]]
返回分區大小和偏移量。請注意以下事項:
-
fetch:name
相當於fetch:name:0
,相當於fetch:name:0:partition_size
。 -
fetch:name:offset
等價於fetch:name:offset:(partition_size - offset)
因此fetch:name[:offset[:size]]
= fetch:name:offset:(partition_size - offset)
當未指定offset
或partition_size
(或兩者)時,使用默認值,對於offset
是 0,對於size
是partition_size - offset
的計算值。
- 指定偏移量,未指定大小:
size = partition_size - offset
- 均未指定:兩者都使用默認值,
size = partition_size
- 0。
例如, fetch:foo
在偏移量 0 處獲取整個foo
分區。
驅動程序更改
命令被添加到 fastboot 工具以實現驅動程序更改。每個都鏈接到其在Fastboot 命令表中的完整定義。
fastboot fetch vendor_boot out.img
- 調用
getvar max-fetch-size
來確定塊大小。 - 調用
getvar partition-size:vendor_boot[_a]
來確定整個分區的大小。 - 為每個塊調用
fastboot fetch vendor_boot[_a]:offset:size
。 (塊大小大於vendor_boot
大小,所以通常只有一個塊。) - 將數據拼接到
out.img
中。
- 調用
fastboot flash vendor_boot:default vendor-ramdisk.img
這是 flash 命令的特殊變體。它獲取
vendor_boot
映像,就像調用了fastboot fetch
一樣。fastboot flash vendor_boot:foo vendor-ramdisk.img
獲取
vendor_boot image
,就像調用了fastboot fetch
一樣。- 如果供應商引導標頭是版本 3,它會返回錯誤。
如果供應商引導標頭是版本 4,它會執行以下操作:
- 查找名稱為
foo
的供應商 ramdisk 片段。如果未找到,或者有多個匹配項,則返回錯誤。 - 用給定的圖像替換供應商 ramdisk 片段。
- 重新計算供應商 ramdisk 表中的每個大小和偏移量。
- 刷新新的
vendor_boot
映像。
- 查找名稱為
mkbootimg
名稱default
保留用於在 Android 12 及更高版本中命名供應商 ramdisk 片段。雖然 fastboot flash vendor_boot:default
語義保持不變,但您不能將您的 ramdisk 片段命名為default
。
SELinux 變化
在fastbootd.te
中進行了更改以支持刷新供應商 ramdisk。