前言
fastboot是一種用於Android設備上的刷機協議,便於系統開發者快速燒錄系統。隨着AOSP的發展,谷歌在Android Q版本引入了super動態分區功能,實現system、vendor和product等分區大小的靈活配置,避免了系統升級帶來頻繁修改分區表的問題。同時引入了手機端側fastboot模式實現super分區的擦寫,之前版本的fastboot刷寫功能通常實現在bootloader模式(一般由SOC廠家提供原始實現),新引入的fastboot模式實現在recovery系統中集成了fastbootd二進制程序,在recovery系統中可復用系統的usb、網絡等驅動,降低了開發難度,具有更好的可移植性(目前各個廠家的bootloader方案各有不同),一定程度降低了廠家的工作量。
一、源碼&編譯
源碼路徑
手機端fastbootd源碼路徑:system/core/fastboot/device
Host端fastboot源碼路徑:system/core/fastboot
在system/core/fastboot目錄下mm即可編譯生成fastbootd和Host端使用的fastboot工具。
二、fastboot模式啟動過程
啟動流程圖
adb/bootloader模式下reboot-fastboot。
相關代碼
- 執行adbreboot-fastboot
adb新增對命令reboot-fastboot的支持。
system/core/adb/daemon/services.cpp
- 設置屬性sys.powerctl=fastboot
調用reboot命令設置屬性sys.powerctl=fastboot,觸發init進程執行action::powerctl。
system/core/reboot/reboot.c
init.rc1
- 寫入bootloader_message后重啟
init進程將reboot-reason寫入bootloader_message后重啟系統。
system/core/init/reboot.cpp
- 重啟后進入recovery系統
重啟進入recovery系統后,recovery程序讀取bootloader_message,屬性sys.usb.config先后設置為none和fastboot。
recovery_main.cpp
- 啟動fastbootd進程
init進程在屬性sys.usb.config=none時清除usb的ffs配置,sys.usb.config=fastboot時配置usb的ffs為fastboot模式,生成fastboot對應的讀寫endpoint設備,用於和PC端的fastboot協議數據讀寫。
init.rc
-
fastboot模式下fastbootreboot recovery可切換到recovery模式(啟動adb,關閉fastbootd)而不需要重啟。
-
PC端fastboot從r28.0.1之后開始支持reboot-fastboot命令,adb從r28.0.2之后開始支持reboot-fastboot命令。
-
fastbootd與recovery進程的關系和update_binary與recovery進程的關系類似,前者負責flash擦寫邏輯的實現,后者負責UI的實現。
三、fastboot通信過程
fastboot協議
cmd:arg1......
例如reboot、flash:boot、erase:boot、oem:unlock、getvar:product、download:size等。
如上圖所示,fastboot協議不僅可以通過usb實現,也可以通過網絡的方式實現。
flash命令執行過程
動態分區
在super分區頭部存在metadata數據結構記錄system、vendor、product等分區的位置和大小,結構如下圖所示。
通常將boot、userdata、cache等稱為物理分區,super分區中的system、vendor、product等稱為邏輯分區。
fastbootd中支持create-logical-partition/delete-logical-partition/resize-logical-partition三個命令主動創建super分區上的邏輯分區。
fastboot delete-logical-partitionsystemfastboot create-logical-partitionsystem 1073741824
fastboot resize-logical-partition system 4294967296
fastboot flash system system.img
按照上述方式刷機成功后,重啟進入Android系統,在init的first_stage階段生成對應的dm設備並掛載:
main()->FirstStageMain() -->DoFirstStageMount()-->InitDevices()-->MountPartitions()-->CreateLogicalPartitions()-->CreateDevice()
init在first_stage階段讀取fstab配置
依據fstab配置創建super的邏輯分區
主要通過控制/dev/device-mapper,創建dm設備,加載super分區的metadata的table數據(分區的名字、偏移和大小等)傳遞給DeviceMapper驅動生產對應的/dev/dmX設備。具體的LinuxDeviceMapper實現機制,這里不詳細介紹,請參見《DeviceMapper架構及在android上的應用》。
四、小結
目前用戶空間的fastbootd作為fastboot協議中的服務端覆蓋了所有fastboot原生命令,fastboot和recovery共享內核和庫,基於usbgadget、block等linux驅動實現了協議通信和flash設備的讀寫等功能。對於OEM命令,Google也設計了對應OEMHAL(android.hardware.fastboot@1.0-service)兼容各自的私有命令,同時方便開發者在各個版本之間快速移植。基於用戶空間下fastbootd的高可移植性、linux運行環境等特點,用戶空間下的fastbootd可能會逐漸替代引導程序實現fastboot的方式,而引導程序只保留各自SOC的線刷功能。