將 Fastboot 移至使用者空間

Fastboot 是系統啟動載入程式模組和模式的名稱。Android 10 以上版本會將 Fastboot 實作項目從引導程式重新安置至使用者空間,以支援可調整大小的分區。這個 重設 - 將刷新程式碼移到可維護且可測試的範圍內 是由 硬體抽象層 (HAL)此外,Android 12 以上版本支援透過新增的 fastboot 指令刷新 RAMDISK。

統一 Fastboot 和復原功能

由於使用者空間快速啟動和復原功能相似,因此您可以將這兩項功能合併為一個分割區或二進位檔。這樣一來,您就能享有以下優點:使用較少空間、整體分區較少,以及讓 fastboot 和 recovery 共用其核心和程式庫。

Fastbootd 是使用者空間守護程序和模式的名稱。如要支援 fastbootd,系統啟動載入程式必須實作新的啟動控制項區塊 (BCB) 指令boot-fastboot。如要進入fastbootd模式,請啟動系統啟動載入程式 將 boot-fastboot 寫入 BCB 訊息的指令欄位,然後 BCB 的 recovery 欄位不變 (以便重新啟動任何中斷的復原程序) 工作)。statusstagereserved 欄位也維持不變。 系統出現啟動載入程式時,即會載入並啟動還原映像檔, boot-fastboot。復原程序接著會剖析 BCB 訊息,並切換至 fastbootd 模式。

ADB 指令

本節說明用於整合 fastbootdadb 指令。這項指令的結果會因執行方式而異,如果是由系統執行,結果就會不同。

指令 說明
reboot fastboot
  • 重新啟動至 fastbootd (系統)。
  • 在不重新啟動 (還原) 的情況下直接輸入 fastbootd

Fastboot 指令

本節說明用於整合 fastbootd 的 fastboot 指令,包括用於閃記及管理邏輯磁碟區的新指令。只有部分通知 指令會產生不同的結果,具體取決於您是否執行 系統啟動載入程式,或使用 fastbootd 提交。

指令 說明
reboot recovery
  • 重新啟動並進入復原程序 (系統啟動載入程式)。
  • 不需重新啟動即可直接進入復原模式 (fastbootd)。
reboot fastboot 重新啟動後進入 fastbootd
getvar is-userspace
  • 傳回 yes (fastbootd)。
  • 傳回 no (啟動載入程式)。
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> ] 將檔案寫入 Flash 分區。裝置必須處於解鎖狀態。
erase <partition> 清除分區 (不必使用安全清除功能)。裝置必須位於 解鎖狀態。
getvar <variable> | all 顯示系統啟動載入程式變數或所有變數。如果變數不存在,則會傳回錯誤。
set_active <slot>

將指定的 A/B 啟動運算單元設為 active。在下次嘗試啟動時,系統會從指定的插槽啟動。

對於 A/B 支援,運算單元是重複的分區集合,可從中獨立啟動。版位名稱為 ab 等,並在分區名稱中加上後置字串 _a_b 等來區分。

reboot 正常重新啟動裝置。
reboot-bootloader (或reboot bootloader) 重新啟動裝置,並進入系統啟動載入程式。
fastboot fetch vendor_boot <out.img>

Android 12 以上版本中使用,以支援刷新供應商 RAMDISK

取得整個分區大小和區塊大小。取得每個區塊的資料,然後將資料拼接成 <out.img>

詳情請參閱 fastboot fetch vendor_boot <out.img>

fastboot flash vendor_boot:default <vendor-ramdisk.img>

Android 12 以上版本中使用,以支援供應商快閃記憶體磁碟。

這是 Flash 指令的特殊變化版本。它會執行 fetch vendor_boot 圖片函式,就像呼叫 fastboot fetch 一樣。它閃爍的新 vendor_boot 圖片會視啟動標頭版本為第 3 版或第 4 版而定。

詳情請參閱 fastboot flash vendor_boot:default <vendor-ramdisk.img>

fastboot flash vendor_boot:<foo> <vendor-ramdisk.img> Android 12 以上版本中使用,以支援供應商快閃記憶體磁碟。

擷取 vendor_boot 圖片。如果供應商啟動標頭為第 3 版,則會傳回錯誤。如果是第 4 版,會找到 供應商 ramdisk 片段 (如有)。並將其替換為指定的圖片,重新計算大小和偏移量,然後閃爍新 vendor_boot image

詳情請參閱 fastboot flash vendor_boot:<foo> <vendor-ramdisk.img>

Fastboot 和系統啟動載入程式

系統啟動載入程式會閃過 bootloaderradioboot/recovery 分區,接著裝置會啟動至 fastboot (使用者空間),並閃過所有其他分區。引導程式應支援下列指令。

指令 說明
download 將映像檔下載為 Flash。
flash recovery <image>/ flash boot <image>/ flash bootloader <image>/ 刷新 recovery/boot 分區和系統啟動載入程式。
reboot 重新啟動裝置。
reboot fastboot 重新啟動為 Fastboot。
reboot recovery 重新啟動以進行復原。
getvar 取得刷新復原/啟動程序所需的系統啟動載入程式變數 圖片 (例如 current-slotmax-download-size)。
oem <command> 由原始設備製造商 (OEM) 定義的指令。

動態分割區

系統啟動載入程式不得允許刷新或清除動態分區 如果嘗試執行這些作業,則必須傳回錯誤。對於改裝的動態分區裝置,fastboot 工具 (和引導程序) 支援強制模式,可在引導程序模式下直接刷新動態分區。舉例來說,如果 system 是改裝裝置上的動態分區,使用 fastboot --force flash system 指令可啟用 Bootloader (而非 fastbootd) 來刷新分區。

關閉模式充電

如果裝置支援關機充電,或在接上電源時自動啟動特殊模式,則 fastboot oem off-mode-charge 0 指令的實作方式必須略過這些特殊模式,讓裝置啟動時就像使用者按下電源鍵一樣。

Fastboot OEM HAL

如要完全取代系統啟動載入程式 Fastboot,必須處理所有現有的 Quickboot Quickboot 指令。這些指令大多來自原始設備製造商 (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

  1. device.mk 中將 fastbootd 新增至 PRODUCT_PACKAGESPRODUCT_PACKAGES += fastbootd

  2. 確保 Fastboot HAL、啟動控制 HAL 和健康狀態 HAL 包裝完成 做為復原映像檔的一部分

  3. 新增 fastbootd 要求的任何裝置專屬 SEPolicy 權限。適用對象 舉例來說,fastbootd 需要具備裝置專屬分區的寫入權限,才能 新的 Docker 映像檔此外,fastboot HAL 實作也可能需要裝置專屬權限。

如要驗證使用者空間快速啟動功能,請執行供應商測試套件 (VTS)

Flash 供應商 RAMDISK

Android 12 以上版本支援 使用新增的 Fastboot 指令刷新 ramdisks 裝置中的 vendor_boot 張圖片。這個指令會提示主機端 Fastboot 工具讀取廠商開機標頭、重新映射並刷新新映像檔。

為提取完整的 vendor_boot 映像檔,指令 fetch:vendor_boot 已加入至 fastboot 通訊協定和 Android 12 中 fastbootd 實作通訊協定。請注意,Fastbootd 但系統啟動載入程式本身不一定能實作這個內容。原始設備製造商 (OEM) 可將 fetch:vendor_boot 指令新增至其協定啟動載入程式實作項目。不過,如果系統啟動載入程式模式無法辨識該指令,則 在系統啟動載入程式模式下刷新個別廠商 ramdisk 不受供應商支援 如果有需要 SQL 指令的分析工作負載 則 BigQuery 可能是最佳選擇

系統啟動載入程式變更

指令 getvar:max-fetch-sizefetch:name 已在 fastbootd 中實作。如要在系統啟動載入程式中支援刷新廠商 ramdisks,您必須 實作這兩個指令

快速系統啟動變更

getvar:max-fetch-sizemax-download-size 相似。它會指定裝置可在單一 DATA 回應中傳送的最大大小。駕駛不得 擷取的大小。

fetch:name[:offset[:size]] 會對裝置執行一系列檢查。如果所有 以下為 true,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)

如果未指定 offsetpartition_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 一樣。

    • 如果廠商啟動程序是標頭 3、 它會執行以下作業:
      • 將供應商 ramdisk 更換為指定的映像檔。
      • 刷新新的 vendor_boot 圖片。
    • 如果供應商啟動標頭為 第 4 版,則會執行以下操作:
      • 將整個供應商 ramdisk 取代為指定映像檔,讓指定映像檔成為 vendor_boot 映像檔中唯一的供應商 ramdisk 片段。
      • 重新計算供應商 RAMDISK 資料表中的大小和偏移量。
      • 閃爍新 vendor_boot 圖片。
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

    擷取 vendor_boot image,就像呼叫 fastboot fetch 一樣。

    • 如果廠商開機標頭是第 3 版,就會傳回錯誤。
    • 如果供應商啟動標頭為第 4 版,則會執行以下操作:

      • 尋找具有名稱的廠商 ramdisk 片段 ramdisk_<var>&lt;foo></var>。如果找不到或有多個相符項目,則會傳回錯誤。
      • 使用指定的映像檔取代供應商的 RAMDISK 片段。
      • 重新計算供應商 RAMDISK 表格中的每個大小和偏移量。
      • 刷新新的 vendor_boot 圖片。
    • 如未指定 <foo>,系統會嘗試尋找 ramdisk_

mkbootimg

名稱 default 是預留給 Android 12 以上版本中供應商 RAM 磁碟片段的名稱。雖然 fastboot flash vendor_boot:default 語意保持不變,但您不得將 RAM 磁碟片段命名為 default

SELinux 異動

變更日期: fastbootd.te 以便支援刷新廠商 ramdisks。