Android 11 đã giới thiệu khái niệm Hình ảnh hạt nhân chung (GKI). Để có thể dễ dàng khởi động một thiết bị tùy ý bằng GKI, các thiết bị Android 11 có thể sử dụng tiêu đề hình ảnh khởi động phiên bản 3. Trong phiên bản 3, tất cả thông tin dành riêng cho nhà cung cấp sẽ được đưa ra khỏi phân vùng boot
và được chuyển sang phân vùng vendor_boot
mới. Thiết bị ARM64 chạy Android 11 trên nhân Linux 5.4 phải hỗ trợ phân vùng vendor_boot
và định dạng phân vùng boot
được cập nhật để vượt qua thử nghiệm với GKI.
Các thiết bị Android 12 có thể sử dụng tiêu đề hình ảnh khởi động phiên bản 4, hỗ trợ đưa nhiều đĩa ram của nhà cung cấp vào phân vùng vendor_boot
. Nhiều mảnh đĩa ram của nhà cung cấp được nối lần lượt trong phần đĩa ram của nhà cung cấp. Bảng ramdisk của nhà cung cấp được sử dụng để mô tả bố cục của phần ramdisk của nhà cung cấp và siêu dữ liệu của từng đoạn ramdisk của nhà cung cấp.
Cấu trúc phân vùng
Phân vùng khởi động của nhà cung cấp là A/B với A/B ảo và được bảo vệ bởi tính năng Khởi động được xác minh của Android.
Phiên bản 3
Phân vùng bao gồm một tiêu đề, đĩa RAM của nhà cung cấp và blob cây thiết bị (DTB).
Phần | Số trang |
---|---|
Tiêu đề khởi động của nhà cung cấp (n trang) | n = (2112 + page_size - 1) / page_size |
Đĩa RAM của nhà cung cấp (o trang) | o = (vendor_ramdisk_size + page_size - 1) / page_size |
DTB (p trang) | p = (dtb_size + page_size - 1) / page_size |
Phiên bản 4
Phân vùng bao gồm một tiêu đề, phần đĩa ram của nhà cung cấp (bao gồm tất cả các mảnh đĩa ram của nhà cung cấp, được nối), blob cây thiết bị (DTB) và bảng ramdisk của nhà cung cấp.
Phần | Số trang |
---|---|
Tiêu đề khởi động của nhà cung cấp (n trang) | n = (2128 + page_size - 1) / page_size |
Các mảnh ramdisk của nhà cung cấp (o trang) | o = (vendor_ramdisk_size + page_size - 1) / page_size |
DTB (p trang) | p = (dtb_size + page_size - 1) / page_size |
Bảng ramdisk của nhà cung cấp (q trang) | q = (vendor_ramdisk_table_size + page_size - 1) / page_size |
Bootconfig (trang r) | r = (bootconfig_size + page_size - 1) / page_size |
Tiêu đề khởi động của nhà cung cấp
Nội dung của tiêu đề phân vùng khởi động của nhà cung cấp chủ yếu bao gồm dữ liệu được chuyển đến đó từ tiêu đề hình ảnh khởi động . Nó cũng chứa thông tin về ramdisk của nhà cung cấp.
Phiên bản 3
struct vendor_boot_img_hdr_v3
{
#define VENDOR_BOOT_MAGIC_SIZE 8
uint8_t magic[VENDOR_BOOT_MAGIC_SIZE];
uint32_t header_version;
uint32_t page_size; /* flash page size we assume */
uint32_t kernel_addr; /* physical load addr */
uint32_t ramdisk_addr; /* physical load addr */
uint32_t vendor_ramdisk_size; /* size in bytes */
#define VENDOR_BOOT_ARGS_SIZE 2048
uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE];
uint32_t tags_addr; /* physical addr for kernel tags */
#define VENDOR_BOOT_NAME_SIZE 16
uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */
uint32_t header_size; /* size of vendor boot image header in
* bytes */
uint32_t dtb_size; /* size of dtb image */
uint64_t dtb_addr; /* physical load address */
};
Phiên bản 4
struct vendor_boot_img_hdr_v4
{
#define VENDOR_BOOT_MAGIC_SIZE 8
uint8_t magic[VENDOR_BOOT_MAGIC_SIZE];
uint32_t header_version;
uint32_t page_size; /* flash page size we assume */
uint32_t kernel_addr; /* physical load addr */
uint32_t ramdisk_addr; /* physical load addr */
uint32_t vendor_ramdisk_size; /* size in bytes */
#define VENDOR_BOOT_ARGS_SIZE 2048
uint8_t cmdline[VENDOR_BOOT_ARGS_SIZE];
uint32_t tags_addr; /* physical addr for kernel tags */
#define VENDOR_BOOT_NAME_SIZE 16
uint8_t name[VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */
uint32_t header_size; /* size of vendor boot image header in
* bytes */
uint32_t dtb_size; /* size of dtb image */
uint64_t dtb_addr; /* physical load address */
uint32_t vendor_ramdisk_table_size; /* size in bytes for the vendor ramdisk table */
uint32_t vendor_ramdisk_table_entry_num; /* number of entries in the vendor ramdisk table */
uint32_t vendor_ramdisk_table_entry_size; /* size in bytes for a vendor ramdisk table entry */
uint32_t bootconfig_size; /* size in bytes for the bootconfig section */
};
#define VENDOR_RAMDISK_TYPE_NONE 0
#define VENDOR_RAMDISK_TYPE_PLATFORM 1
#define VENDOR_RAMDISK_TYPE_RECOVERY 2
#define VENDOR_RAMDISK_TYPE_DLKM 3
struct vendor_ramdisk_table_entry_v4
{
uint32_t ramdisk_size; /* size in bytes for the ramdisk image */
uint32_t ramdisk_offset; /* offset to the ramdisk image in vendor ramdisk section */
uint32_t ramdisk_type; /* type of the ramdisk */
#define VENDOR_RAMDISK_NAME_SIZE 32
uint8_t ramdisk_name[VENDOR_RAMDISK_NAME_SIZE]; /* asciiz ramdisk name */
#define VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE 16
// Hardware identifiers describing the board, soc or platform which this
// ramdisk is intended to be loaded on.
uint32_t board_id[VENDOR_RAMDISK_TABLE_ENTRY_BOARD_ID_SIZE];
};
-
vendor_ramdisk_size
là tổng kích thước của tất cả các mảnh ramdisk của nhà cung cấp. -
ramdisk_type
biểu thị loại ramdisk, các giá trị có thể là:-
VENDOR_RAMDISK_TYPE_NONE
cho biết giá trị không được chỉ định. - Đĩa RAM
VENDOR_RAMDISK_TYPE_PLATFORM
chứa các bit dành riêng cho nền tảng. Bộ nạp khởi động phải luôn tải chúng vào bộ nhớ. - Đĩa
VENDOR_RAMDISK_TYPE_RECOVERY
chứa tài nguyên khôi phục. Bộ nạp khởi động phải tải chúng vào bộ nhớ khi khởi động vào recovery. - Đĩa ram
VENDOR_RAMDISK_TYPE_DLKM
chứa các mô-đun hạt nhân có thể tải động.
-
-
ramdisk_name
là tên duy nhất của ramdisk. -
board_id
là một vectơ định danh phần cứng do nhà cung cấp xác định.
Hỗ trợ bộ nạp khởi động
Vì phân vùng khởi động của nhà cung cấp chứa thông tin (chẳng hạn như kích thước trang flash, kernel, địa chỉ tải ramdisk, chính DTB) đã tồn tại trước đó trong phân vùng khởi động, nên bộ nạp khởi động phải truy cập vào cả phân vùng khởi động và phân vùng khởi động của nhà cung cấp để có đủ dữ liệu hoàn tất quá trình khởi động .
Bộ tải khởi động phải tải ramdisk chung vào bộ nhớ ngay sau ramdisk của nhà cung cấp (các định dạng CPIO, Gzip và lz4 hỗ trợ kiểu nối này). Không căn chỉnh trang hình ảnh ramdisk chung hoặc thêm bất kỳ khoảng trống nào khác giữa nó và phần cuối của ramdisk của nhà cung cấp trong bộ nhớ. Sau khi kernel giải nén, nó trích xuất tệp được nối thành initramfs
, dẫn đến cấu trúc tệp là một đĩa ram chung được phủ lên cấu trúc tệp ramdisk của nhà cung cấp.
Bởi vì đĩa ram chung và đĩa ram của nhà cung cấp được nối với nhau nên chúng phải có cùng định dạng. Hình ảnh khởi động GKI sử dụng đĩa ram chung được nén bằng lz4, do đó, thiết bị tuân thủ GKI phải sử dụng đĩa ram chung được nén bằng lz4 của nhà cung cấp. Cấu hình cho điều này được hiển thị dưới đây.
Các yêu cầu về bộ nạp khởi động để hỗ trợ bootconfig được giải thích trên trang Triển khai Bootconfig .
Nhiều đĩa RAM của nhà cung cấp (phiên bản 4)
Với tiêu đề ảnh khởi động phiên bản 4, bộ nạp khởi động có thể chọn một tập hợp con hoặc tất cả các đĩa ram của nhà cung cấp để tải dưới dạng initramfs
trong thời gian khởi động. Bảng ramdisk của nhà cung cấp chứa siêu dữ liệu của từng ramdisk và có thể hỗ trợ bộ nạp khởi động trong việc quyết định nên tải ramdisk nào. Bộ nạp khởi động có thể quyết định thứ tự tải các đĩa ram của nhà cung cấp đã chọn, miễn là đĩa ram chung được nạp sau cùng.
Ví dụ: bộ tải khởi động có thể bỏ qua việc tải các đĩa ram của nhà cung cấp thuộc loại VENDOR_RAMDISK_TYPE_RECOVERY
trong quá trình khởi động bình thường để bảo tồn tài nguyên, do đó, chỉ các đĩa ram của nhà cung cấp thuộc loại VENDOR_RAMDISK_TYPE_PLATFORM
và VENDOR_RAMDISK_TYPE_DLKM
mới được tải vào bộ nhớ. Mặt khác, các đĩa ram của nhà cung cấp loại VENDOR_RAMDISK_TYPE_PLATFORM
, VENDOR_RAMDISK_TYPE_RECOVERY
và VENDOR_RAMDISK_TYPE_DLKM
được tải vào bộ nhớ khi khởi động vào chế độ khôi phục.
Ngoài ra, bộ nạp khởi động có thể bỏ qua bảng ramdisk của nhà cung cấp và tải toàn bộ phần ramdisk của nhà cung cấp. Điều này có tác dụng tương tự như việc tải tất cả các mảnh đĩa ram của nhà cung cấp trong phân vùng vendor_boot
.
Xây dựng hỗ trợ
Để triển khai hỗ trợ khởi động của nhà cung cấp cho một thiết bị:
Đặt
BOARD_BOOT_HEADER_VERSION
thành3
hoặc cao hơn.Đặt
BOARD_RAMDISK_USE_LZ4
thànhtrue
nếu thiết bị của bạn tuân thủ GKI hoặc nếu thiết bị sử dụng đĩa ram chung được nén lz4.Đặt
BOARD_VENDOR_BOOTIMAGE_PARTITION_SIZE
thành kích thước phù hợp cho thiết bị của bạn, có tính đến các mô-đun hạt nhân phải có trên đĩa ram của nhà cung cấp.Cập nhật
AB_OTA_PARTITIONS
để bao gồmvendor_boot
và mọi danh sách phân vùng OTA dành riêng cho nhà cung cấp trên thiết bị.Sao chép
fstab
thiết bị của bạn vào/first_stage_ramdisk
trong phân vùngvendor_boot
, không phải phân vùngboot
. Ví dụ:$(LOCAL_PATH)/fstab.hardware:$(TARGET_COPY_OUT_VENDOR_RAMDISK)/first_stage_ramdisk/fstab.$(PRODUCT_PLATFORM)
.
Để bao gồm nhiều ramdisks của nhà cung cấp trong vendor_boot
:
- Đặt
BOARD_BOOT_HEADER_VERSION
thành4
. Đặt
BOARD_VENDOR_RAMDISK_FRAGMENTS
thành danh sách tên phân đoạn ramdisk của nhà cung cấp hợp lý sẽ được đưa vàovendor_boot
.Để thêm ramdisk của nhà cung cấp dựng sẵn, hãy đặt
BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).PREBUILT
vào đường dẫn tệp dựng sẵn.Để thêm ramdisk của nhà cung cấp DLKM, hãy đặt
BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).KERNEL_MODULE_DIRS
vào danh sách các thư mục mô-đun hạt nhân cần đưa vào.Đặt
BOARD_VENDOR_RAMDISK_FRAGMENT.$(vendor_ramdisk).MKBOOTIMG_ARGS
thành đối sốmkbootimg
. Đây là các đối số--board_id[0-15]
và--ramdisk_type
cho đoạn ramdisk của nhà cung cấp. Đối với ramdisk của nhà cung cấp DLKM,--ramdisk_type
mặc định sẽ làDLKM
nếu nó không được chỉ định khác.
Để xây dựng tài nguyên khôi phục dưới dạng ramdisk recovery
độc lập trong vendor_boot
:
- Đặt
BOARD_BOOT_HEADER_VERSION
thành4
. - Đặt
BOARD_MOVE_RECOVERY_RESOURCES_TO_VENDOR_BOOT
thànhtrue
. - Đặt
BOARD_INCLUDE_RECOVERY_RAMDISK_IN_VENDOR_BOOT
thànhtrue
. - Điều này thêm một đoạn ramdisk của nhà cung cấp có
ramdisk_name
làrecovery
vàramdisk_type
làVENDOR_RAMDISK_TYPE_RECOVERY
. Sau đó, đĩa RAM chứa tất cả các tệp khôi phục, là các tệp được cài đặt trong$(TARGET_RECOVERY_ROOT_OUT)
.
đối số mkbootimg
Lý lẽ | Sự miêu tả |
---|---|
--ramdisk_type | Loại đĩa RAM có thể là NONE , PLATFORM , RECOVERY hoặc DLKM . |
--board_id[0-15] | Chỉ định vector board_id , mặc định là 0 . |
Sau đây là một cấu hình ví dụ:
BOARD_KERNEL_MODULE_DIRS := foo bar baz
BOARD_BOOT_HEADER_VERSION := 4
BOARD_VENDOR_RAMDISK_FRAGMENTS := dlkm_foobar
BOARD_VENDOR_RAMDISK_FRAGMENT.dlkm_foobar.KERNEL_MODULE_DIRS := foo bar
BOARD_VENDOR_RAMDISK_FRAGMENT.dlkm_foobar.MKBOOTIMG_ARGS := --board_id0 0xF00BA5 --board_id1 0xC0FFEE
Kết quả của vendor_boot
sẽ chứa hai đoạn ramdisk của nhà cung cấp. Cái đầu tiên là ramdisk "mặc định", chứa thư mục DLKM baz
và phần còn lại của các tệp trong $(TARGET_VENDOR_RAMDISK_OUT)
. Cái thứ hai là dlkm_foobar
ramdisk, chứa các thư mục DLKM foo
và bar
và --ramdisk_type
mặc định là DLKM
.