將 Fastboot 移至用戶空間

Android 10 及更高版本通過將 fastboot 實現從引導加載程序重新定位到用戶空間來支持可調整大小的分區。這種重新定位可以將閃存代碼移動到一個可維護和可測試的公共位置,而只有供應商特定的 fastboot 部分由硬件抽象層 (HAL) 實現。此外,Android 12 及更高版本支持通過添加的 fastboot 命令刷寫 ramdisk。

統一快速啟動和恢復

因為用戶空間的 fastboot 和 recovery 是相似的,你可以將它們合併到一個分區或二進製文件中。這提供了一些優勢,例如使用更少的空間、總體上具有更少的分區以及快速啟動和恢復共享其內核和庫。

為了支持fastbootd ,引導程序必須實現一個新的引導控制塊(BCB)命令boot-fastboot 。進入fastbootd模式,引導程序寫入boot-fastboot到BCB消息的命令字段和離開recovery BCB不變(使重新啟動任何中斷恢復任務)的領域。的statusstage ,並reserved領域保持不變為好。見狀引導程序加載和啟動到恢復映像boot-fastboot在BCB命令字段。恢復然後解析BCB消息並切換到fastbootd模式。

亞行命令

本節介紹了adb的整合指揮fastbootd 。該命令有不同的結果,這取決於它是由系統執行還是由恢復執行。

命令描述
reboot fastboot
  • 重新引導到fastbootd (系統)。
  • 進入fastbootd的情況下直接重新啟動(恢復)。

快速啟動命令

本節介紹了整合FASTBOOT命令fastbootd ,包括閃光和管理邏輯分區的新命令。有些命令有不同的結果,這取決於他們是否已經通過引導程序或執行fastbootd

命令描述
reboot recovery
  • 重新啟動進入恢復(引導加載程序)。
  • 進入恢復的情況下直接重新啟動( fastbootd )。
reboot fastboot重新啟動進入fastbootd
getvar is-userspace
  • 返回yesfastbootd )。
  • 返回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> ]將文件寫入閃存分區。設備必須處於解鎖狀態。
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>

使用Android12和更高的支持閃爍廠商的ramdisk。

獲取整個分區大小和塊大小。獲取數據對於每個大塊,然後將數據縫合在一起以<out.img>

有關詳細信息,請參閱fastboot fetch vendor_boot <out.img>

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

使用Android12和更高的支持閃爍廠商的ramdisk。

這是 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>使用Android12和更高的支持閃爍廠商的ramdisk。

獲取的vendor_boot圖像。如果供應商引導頭是版本 3,則返回錯誤。如果是版本 4,它會找到正確的供應商 ramdisk 片段(如果可用)。它取代了與給定圖像,重新計算大小和偏移量,並閃爍新vendor_boot image

有關詳細信息,請參閱fastboot flash vendor_boot: <foo> <vendor-ramdisk.img>

快速啟動和引導加載程序

引導加載程序閃爍bootloaderradio ,和boot/recovery分區,然後將設備引導到FASTBOOT(用戶空間)和閃爍所有其他分區。引導加載程序應支持以下命令。

命令描述
download將圖像下載到閃存。
flash recovery <image> / flash boot <image> / flash bootloader <image> /閃爍recovery/boot分區和引導程序。
reboot重新啟動設備。
reboot fastboot重新啟動到快速啟動。
reboot recovery重新啟動以恢復。
getvar獲取所需的恢復/引導映像的閃爍(例如,引導加載程序可變current-slotmax-download-size )。
oem <command>由 OEM 定義的命令。

動態分區

引導加載程序一定不能讓閃爍或動態分區的刪除,如果這些操作必須嘗試返回一個錯誤。對於改裝的動態分區設備,fastboot 工具(和引導加載程序)支持強制模式,以在引導加載程序模式下直接刷新動態分區。例如,如果system是一個動態分區改型設備上,使用fastboot --force flash system命令使引導程序(而不是fastbootd )閃爍的分區。

關閉模式充電

如果當施加電源時,一個實施方案的裝置的支撐關閉模式充電或以其它方式autoboots到特殊模式fastboot oem off-mode-charge 0命令必須旁路這些特殊模式,因此,設備啟動,就像用戶已經按下電源按鈕。

快速啟動 OEM HAL

要完全替代引導加載程序 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在設備上:

  1. 添加fastbootdPRODUCT_PACKAGESdevice.mkPRODUCT_PACKAGES += fastbootd

  2. 確保將 fastboot HAL、引導控制 HAL 和運行狀況 HAL 打包為恢復映像的一部分。

  3. 通過添加所需的任何特定於設備的SEPolicy權限fastbootd 。例如, fastbootd要求的裝置,特定分區寫訪問閃爍該分區。此外,fastboot HAL 實現可能還需要特定於設備的權限。

為了驗證用戶空間FASTBOOT,運行商測試套件(VTS) 。

閃爍供應商 ramdisk

機器人12和更高的提供用於與該拉滿添加的FASTBOOT命令閃爍的ramdisk支撐vendor_boot從設備的圖像。該命令會提示主機端 fastboot 工具讀取供應商引導標頭、重新映像並刷新新映像。

拉滿vendor_boot圖像,命令fetch:vendor_boot加入既快速啟動協議,並fastbootd實現在Android中12注協議fastbootd確實實現這一點,但引導程序本身可能不是。 OEM廠商可以添加fetch:vendor_boot命令他們的引導程序執行協議。但是,如果在引導加載程序模式下無法識別該命令,則在引導加載程序模式下刷新單個供應商 ramdisk 不是供應商支持的選項。

引導加載程序更改

該命令getvar:max-fetch-sizefetch:name在實現fastbootd 。要在引導加載程序中支持刷寫供應商 ramdisk,您必須實現這兩個命令。

Fastbootd 更改

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)

offsetpartition_size (或兩者)是未指定的,則使用默認值,這對於offset是0,並且對於size為計算值partition_size - offset

  • 偏移指定,未指定大小: size = partition_size - offset
  • 既不指定:用於兩個,默認值size = partition_size - 0。

例如, fetch:foo取整個foo在偏移0的分區。

驅動程序更改

將命令添加到 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 ,它執行以下操作:
      • 替換與給定圖像整體的供應商虛擬盤,使得所述給定圖像成為在的唯一供應商虛擬盤片段vendor_boot圖像。
      • 重新計算供應商 ramdisk 表中的大小和偏移量。
      • 閃爍新vendor_boot圖像。
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

    獲取vendor_boot image ,彷彿fastboot fetch被調用。

    • 如果供應商引導標頭是版本 3,則會返回錯誤。
    • 如果供應商引導頭是版本 4,它會執行以下操作:

      • 查找與名賣方RAMDISK片段foo 。如果未找到,或者有多個匹配項,則返回錯誤。
      • 用給定的圖像替換供應商 ramdisk 片段。
      • 重新計算供應商 ramdisk 表中的每個大小和偏移量。
      • 閃爍新vendor_boot圖像。

mkbootimg

名稱default保留給Android中12和更高的命名供應商虛擬盤片段。雖然FASTBOOT flash vendor_boot:default語義保持不變,你不能命名你的ramdisk的片段作為default

SELinux 的變化

改變是在做fastbootd.te支持閃爍廠商的ramdisk。