Chuyển tính năng khởi động nhanh sang không gian người dùng

Fastboot là tên của một mô-đun và chế độ trình tải khởi động. Android 10 trở lên hỗ trợ các phân vùng có thể đổi kích thước bằng cách di chuyển quá trình triển khai fastboot từ trình tải khởi động sang không gian người dùng. Việc di chuyển này cho phép chuyển mã nhấp nháy vào một vị trí chung có thể duy trì và kiểm thử, chỉ với các phần dành riêng cho nhà cung cấp của fastboot được triển khai bằng lớp trừu tượng phần cứng (HAL). Ngoài ra, Android 12 trở lên hỗ trợ nhấp nháy ramdisk thông qua một lệnh fastboot được thêm vào.

Thống nhất fastboot và khôi phục

Vì fastboot và khôi phục không gian người dùng tương tự nhau, nên bạn có thể hợp nhất chúng vào một phân vùng hoặc tệp nhị phân. Điều này mang lại các lợi ích như sử dụng ít dung lượng hơn, có ít phân vùng hơn và có fastboot và khôi phục chia sẻ nhân và thư viện.

Fastbootd là tên của một trình nền và chế độ không gian người dùng. Để hỗ trợ fastbootd, trình tải khởi động phải triển khai một lệnh khối điều khiển khởi động (BCB) mới là boot-fastboot. Để chuyển sang chế độ fastbootd, trình tải khởi động sẽ ghi boot-fastboot vào trường lệnh của thông báo BCB và giữ nguyên trường recovery của BCB (để cho phép khởi động lại mọi tác vụ khôi phục bị gián đoạn). Các trường status, stagereserved cũng không thay đổi. Trình tải khởi động tải và khởi động vào hình ảnh khôi phục khi thấy boot-fastboot trong trường lệnh BCB. Sau đó, quá trình khôi phục sẽ phân tích cú pháp thông báo BCB và chuyển sang chế độ fastbootd.

Lệnh ADB

Phần này mô tả lệnh adb để tích hợp fastbootd. Lệnh này có các kết quả khác nhau, tuỳ thuộc vào việc lệnh này được thực thi theo hệ thống hay theo quá trình khôi phục.

Lệnh Mô tả
reboot fastboot
  • Khởi động lại vào fastbootd (hệ thống).
  • Trực tiếp chuyển sang fastbootd mà không cần khởi động lại (quá trình khôi phục).

Lệnh Fastboot

Phần này mô tả các lệnh fastboot để tích hợp fastbootd, bao gồm các lệnh mới để nhấp nháy và quản lý các phân vùng logic. Một số lệnh có các kết quả khác nhau, tuỳ thuộc vào việc lệnh đó được thực thi theo trình tải khởi động hay theo fastbootd.

Lệnh Mô tả
reboot recovery
  • Khởi động lại vào quá trình khôi phục (trình tải khởi động).
  • Trực tiếp chuyển sang quá trình khôi phục mà không cần khởi động lại (fastbootd).
reboot fastboot Khởi động lại vào fastbootd.
getvar is-userspace
  • Trả về yes (fastbootd).
  • Trả về no (trình tải khởi động).
getvar is-logical:<partition> Trả về yes nếu phân vùng đã cho là phân vùng logic, no nếu không. Các phân vùng logic hỗ trợ tất cả các lệnh được liệt kê bên dưới.
getvar super-partition-name Trả về tên của phân vùng siêu dữ liệu. Tên này bao gồm hậu tố vị trí hiện tại nếu phân vùng siêu dữ liệu là phân vùng A/B (thường thì không).
create-logical-partition <partition> <size> Tạo một phân vùng logic có tên và kích thước đã cho. Tên này không được tồn tại dưới dạng phân vùng logic.
delete-logical-partition <partition> Xoá phân vùng logic đã cho (xóa phân vùng một cách hiệu quả).
resize-logical-partition <partition> <size> Đổi kích thước phân vùng logic thành kích thước mới mà không thay đổi nội dung của phân vùng đó. Không thành công nếu không có đủ dung lượng để thực hiện việc đổi kích thước.
flash <partition><filename> ] Ghi một tệp vào phân vùng flash. Thiết bị phải ở trạng thái đã mở khoá.
erase <partition> Xoá một phân vùng (không bắt buộc phải xoá an toàn). Thiết bị phải ở trạng thái đã mở khoá.
getvar <variable> | all Hiển thị một biến trình tải khởi động hoặc tất cả các biến. Nếu biến không tồn tại, hãy trả về lỗi.
set_active <slot>

Đặt vị trí khởi động A/B đã cho thành active. Trong lần khởi động tiếp theo, hệ thống sẽ khởi động từ vị trí được chỉ định.

Đối với tính năng hỗ trợ A/B, các vị trí là các tập hợp phân vùng trùng lặp có thể khởi động độc lập. Các vị trí được đặt tên là a, b, v.v., và được phân biệt bằng cách thêm các hậu tố _a, _b, v.v. vào tên phân vùng.

reboot Khởi động lại thiết bị bình thường.
reboot-bootloader (hoặc reboot bootloader) Khởi động lại thiết bị vào trình tải khởi động.
fastboot fetch vendor_boot <out.img>

Sử dụng trong Android 12 trở lên để hỗ trợ nhấp nháy ramdisk của nhà cung cấp.

Lấy toàn bộ kích thước phân vùng và kích thước khối. Lấy dữ liệu cho từng khối, sau đó ghép dữ liệu lại với nhau thành <out.img>

Để biết thông tin chi tiết, hãy xem fastboot fetch vendor_boot <out.img>.

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

Sử dụng trong Android 12 trở lên để hỗ trợ nhấp nháy ramdisk của nhà cung cấp.

Đây là một biến thể đặc biệt của lệnh nhấp nháy. Lệnh này thực hiện một hàm hình ảnh fetch vendor_boot, như thể fastboot fetch được gọi. Hình ảnh vendor_boot mới mà lệnh này nhấp nháy phụ thuộc vào việc phiên bản tiêu đề khởi động là phiên bản 3 hay phiên bản 4.

Để biết thông tin chi tiết, hãy xem fastboot flash vendor_boot:default <vendor-ramdisk.img>.

fastboot flash vendor_boot:<foo> <vendor-ramdisk.img> Sử dụng trong Android 12 trở lên để hỗ trợ nhấp nháy ramdisk của nhà cung cấp.

Tìm nạp hình ảnh vendor_boot. Trả về lỗi nếu tiêu đề khởi động của nhà cung cấp là phiên bản 3. Nếu là phiên bản 4, thì lệnh này sẽ tìm thấy phân mảnh ramdisk chính xác của nhà cung cấp (nếu có). Lệnh này sẽ thay thế phân mảnh đó bằng hình ảnh đã cho, tính toán lại kích thước và độ lệch, đồng thời nhấp nháy vendor_boot image mới.

Để biết thông tin chi tiết, hãy xem fastboot flash vendor_boot:<foo> <vendor-ramdisk.img>

Fastboot và trình tải khởi động

Trình tải khởi động sẽ nhấp nháy các phân vùng bootloader, radioboot/recovery, sau đó thiết bị sẽ khởi động vào fastboot (không gian người dùng) và nhấp nháy tất cả các phân vùng khác. Trình tải khởi động phải hỗ trợ các lệnh sau.

Lệnh Mô tả
download Tải hình ảnh xuống để cài đặt ROM.
flash recovery <image>/ flash boot <image>/ flash bootloader <image>/ Nhấp nháy phân vùng recovery/boot và trình tải khởi động.
reboot Khởi động lại thiết bị.
reboot fastboot Khởi động lại bằng fastboot.
reboot recovery Khởi động lại để khôi phục.
getvar Lấy một biến trình tải khởi động bắt buộc để nhấp nháy hình ảnh khôi phục/khởi động (ví dụ: current-slotmax-download-size).
oem <command> Lệnh do OEM xác định.

Phân vùng động

Trình tải khởi động không được cho phép nhấp nháy hoặc xoá các phân vùng động và phải trả về lỗi nếu các thao tác này được thực hiện. Đối với các thiết bị phân vùng động được trang bị thêm, công cụ khởi động nhanh (và trình tải khởi động) hỗ trợ chế độ bắt buộc để trực tiếp cài đặt ROM một phân vùng động khi ở chế độ trình tải khởi động. Ví dụ: nếu system là một phân vùng động trên thiết bị được trang bị thêm, thì việc sử dụng lệnh fastboot --force flash system sẽ cho phép trình tải khởi động (thay vì fastbootd) cài đặt ROM phân vùng.

Sạc khi tắt nguồn

Nếu một thiết bị hỗ trợ sạc khi tắt nguồn hoặc tự động khởi động vào một chế độ đặc biệt khi được cấp nguồn, thì việc triển khai lệnh fastboot oem off-mode-charge 0 phải bỏ qua các chế độ đặc biệt này để thiết bị khởi động như thể người dùng đã nhấn nút nguồn.

HAL OEM Fastboot

Để thay thế hoàn toàn fastboot của trình tải khởi động, fastboot phải xử lý tất cả các lệnh fastboot hiện có. Nhiều lệnh trong số này là của OEM và được ghi lại nhưng yêu cầu triển khai tuỳ chỉnh. Nhiều lệnh dành riêng cho OEM không được ghi lại. Để xử lý các lệnh như vậy, HAL fastboot sẽ chỉ định các lệnh OEM bắt buộc. OEM cũng có thể triển khai các lệnh riêng.

Định nghĩa của HAL fastboot như sau:

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);

};

Bật fastbootd

Cách bật fastbootd trên thiết bị:

  1. Thêm fastbootd vào PRODUCT_PACKAGES trong device.mk: PRODUCT_PACKAGES += fastbootd.

  2. Đảm bảo rằng HAL fastboot, HAL điều khiển khởi động và HAL sức khoẻ được đóng gói như một phần của hình ảnh khôi phục.

  3. Thêm mọi quyền SEPolicy dành riêng cho thiết bị mà fastbootd yêu cầu. Ví dụ: fastbootd yêu cầu quyền ghi vào một phân vùng dành riêng cho thiết bị để cài đặt ROM phân vùng đó. Ngoài ra, việc triển khai HAL fastboot cũng có thể yêu cầu các quyền dành riêng cho thiết bị.

Để xác thực fastboot không gian người dùng, hãy chạy Bộ kiểm thử nhà cung cấp (VTS).

Cài đặt ROM ramdisk của nhà cung cấp

Android 12 trở lên hỗ trợ nhấp nháy ramdisk bằng một lệnh fastboot được thêm vào, lệnh này sẽ kéo toàn bộ hình ảnh vendor_boot từ một thiết bị. Lệnh này sẽ nhắc công cụ fastboot phía máy chủ đọc tiêu đề khởi động của nhà cung cấp, tạo lại hình ảnh và nhấp nháy hình ảnh mới.

Để kéo toàn bộ hình ảnh vendor_boot, lệnh fetch:vendor_boot đã được thêm vào cả giao thức fastboot và quá trình triển khai giao thức fastbootd trong Android 12. Xin lưu ý rằng fastbootd triển khai lệnh này, nhưng bản thân trình tải khởi động có thể không triển khai. OEM có thể thêm lệnh fetch:vendor_boot vào quá trình triển khai giao thức của trình tải khởi động. Tuy nhiên, nếu lệnh này không được nhận dạng ở chế độ trình tải khởi động, thì việc nhấp nháy từng ramdisk của nhà cung cấp ở chế độ trình tải khởi động không phải là một lựa chọn được nhà cung cấp hỗ trợ.

Thay đổi trình tải khởi động

Các lệnh getvar:max-fetch-sizefetch:name được triển khai trong fastbootd. Để hỗ trợ nhấp nháy ramdisk của nhà cung cấp trong trình tải khởi động, bạn phải triển khai 2 lệnh này.

Thay đổi fastbootd

getvar:max-fetch-size tương tự như max-download-size. Lệnh này chỉ định kích thước tối đa mà thiết bị có thể gửi trong một phản hồi DATA. Trình điều khiển không được tìm nạp kích thước lớn hơn giá trị này.

fetch:name[:offset[:size]] thực hiện một loạt các bước kiểm tra trên thiết bị. Nếu tất cả các điều kiện sau đây đều đúng, thì lệnh fetch:name[:offset[:size]] sẽ trả về dữ liệu:

  • Thiết bị đang chạy một bản dựng có thể gỡ lỗi.
  • Thiết bị đã mở khoá (trạng thái khởi động màu cam).
  • Tên phân vùng được tìm nạp là vendor_boot.
  • Giá trị size nằm trong khoảng 0 < size <= max-fetch-size.

Khi các điều kiện này được xác minh, fetch:name[:offset[:size]] sẽ trả về kích thước và độ lệch của phân vùng. Xin lưu ý những điều sau:

  • fetch:name tương đương với fetch:name:0, tương đương với fetch:name:0:partition_size.
  • fetch:name:offset tương đương với fetch:name:offset:(partition_size - offset)

Do đó, fetch:name[:offset[:size]] = fetch:name:offset:(partition_size - offset).

Khi offset hoặc partition_size (hoặc cả hai) không được chỉ định, các giá trị mặc định sẽ được sử dụng, trong đó offset là 0 và size là giá trị được tính của partition_size - offset.

  • Độ lệch được chỉ định, kích thước không được chỉ định: size = partition_size - offset
  • Không có giá trị nào được chỉ định: các giá trị mặc định được sử dụng cho cả hai, size = partition_size - 0.

Ví dụ: fetch:foo sẽ tìm nạp toàn bộ phân vùng foo ở độ lệch 0.

Thay đổi trình điều khiển

Các lệnh đã được thêm vào công cụ fastboot để triển khai các thay đổi trình điều khiển. Mỗi lệnh được liên kết với định nghĩa đầy đủ trong bảng Lệnh Fastboot lệnh.

  • fastboot fetch vendor_boot out.img

    • Gọi getvar max-fetch-size để xác định kích thước khối.
    • Gọi getvar partition-size:vendor_boot[_a] để xác định kích thước của toàn bộ phân vùng.
    • Gọi fastboot fetch vendor_boot[_a]:offset:size cho từng khối. (Kích thước khối lớn hơn kích thước vendor_boot, vì vậy thường chỉ có một khối.)
    • Ghép dữ liệu lại với nhau thành out.img.
  • fastboot flash vendor_boot:default vendor-ramdisk.img

    Đây là một biến thể đặc biệt của lệnh nhấp nháy. Lệnh này sẽ tìm nạp hình ảnh vendor_boot, như thể fastboot fetch được gọi.

    • Nếu tiêu đề khởi động của nhà cung cấp là phiên bản 3 , thì lệnh này sẽ thực hiện như sau:
      • Thay thế ramdisk của nhà cung cấp bằng hình ảnh đã cho.
      • Nhấp nháy hình ảnh vendor_boot mới.
    • Nếu tiêu đề khởi động của nhà cung cấp là phiên bản 4, thì lệnh này sẽ thực hiện như sau:
      • Thay thế toàn bộ ramdisk của nhà cung cấp bằng hình ảnh đã cho để hình ảnh đã cho trở thành phân mảnh ramdisk duy nhất của nhà cung cấp trong hình ảnh vendor_boot.
      • Tính toán lại kích thước và độ lệch trong bảng ramdisk của nhà cung cấp.
      • Nhấp nháy hình ảnh vendor_boot mới.
  • fastboot flash vendor_boot:foo vendor-ramdisk.img

    Tìm nạp vendor_boot image, như thể fastboot fetch được gọi.

    • Nếu tiêu đề khởi động của nhà cung cấp là phiên bản 3, thì lệnh này sẽ trả về lỗi.
    • Nếu tiêu đề khởi động của nhà cung cấp là phiên bản 4, thì lệnh này sẽ thực hiện như sau:

      • Tìm phân mảnh ramdisk của nhà cung cấp có tên ramdisk_<var>&lt;foo></var>. Nếu không tìm thấy hoặc nếu có nhiều kết quả trùng khớp, hãy trả về lỗi.
      • Thay thế phân mảnh ramdisk của nhà cung cấp bằng hình ảnh đã cho.
      • Tính toán lại từng kích thước và độ lệch trong bảng ramdisk của nhà cung cấp.
      • Nhấp nháy hình ảnh vendor_boot mới.
    • Nếu bạn không chỉ định <foo>, thì lệnh này sẽ cố gắng tìm ramdisk_.

mkbootimg

Tên default được dành riêng để đặt tên cho các phân mảnh ramdisk của nhà cung cấp trong Android 12 trở lên. Mặc dù ngữ nghĩa fastboot flash vendor_boot:default vẫn giữ nguyên, nhưng bạn không được đặt tên cho các phân mảnh ramdisk là default.

Thay đổi SELinux

Một thay đổi đã được thực hiện trong fastbootd.te để hỗ trợ nhấp nháy ramdisk của nhà cung cấp.