Trong Android 10, hệ thống tệp gốc không còn được đưa vào ramdisk.img
mà được hợp nhất vào system.img
(tức là system.img
luôn được tạo nếu bạn đã đặt BOARD_BUILD_SYSTEM_ROOT_IMAGE
). Các thiết bị chạy Android 10:
- Sử dụng bố cục phân vùng hệ thống dưới dạng gốc (tự động được bản dựng thực thi mà không có tuỳ chọn nào để thay đổi hành vi).
- Phải sử dụng ramdisk, đây là yêu cầu bắt buộc đối với dm-linear.
- Phải đặt
BOARD_BUILD_SYSTEM_ROOT_IMAGE
thànhfalse
. Chế độ cài đặt này chỉ dùng để phân biệt giữa các thiết bị sử dụng ramdisk và các thiết bị không sử dụng ramdisk (thay vào đó, hãy trực tiếp gắnsystem.img
).
Ý nghĩa của cấu hình hệ thống dưới dạng thư mục gốc khác nhau giữa Android 9 và Android 10. Trong cấu hình hệ thống dưới dạng thư mục gốc của Android 9, BOARD_BUILD_SYSTEM_ROOT_IMAGE
được đặt thành true
. Thao tác này buộc bản dựng hợp nhất hệ thống tệp gốc vào system.img
, sau đó gắn system.img
làm hệ thống tệp gốc (rootfs). Cấu hình này là bắt buộc đối với các thiết bị chạy Android 9, nhưng không bắt buộc đối với các thiết bị nâng cấp lên Android 9 và đối với các thiết bị chạy các phiên bản Android thấp hơn. Trong cấu hình hệ thống dưới dạng thư mục gốc của Android 10, bản dựng luôn hợp nhất $TARGET_SYSTEM_OUT
và $TARGET_ROOT_OUT
vào system.img
; cấu hình này là hành vi mặc định cho tất cả thiết bị chạy Android 10.
Android 10 thực hiện thêm các thay đổi để hỗ trợ phân vùng động, một hệ thống phân vùng không gian người dùng cho phép các bản cập nhật qua mạng (OTA) tạo, đổi kích thước hoặc huỷ phân vùng. Trong quá trình thay đổi này, nhân Linux không thể gắn phân vùng hệ thống logic trên các thiết bị chạy Android 10 nữa, vì vậy, thao tác này được xử lý bằng quá trình khởi động giai đoạn đầu tiên.
Các phần sau đây mô tả các yêu cầu về hệ thống làm thư mục gốc cho bản cập nhật OTA chỉ dành cho hệ thống, cung cấp hướng dẫn về cách cập nhật thiết bị để sử dụng hệ thống làm thư mục gốc (bao gồm cả các thay đổi về bố cục phân vùng và yêu cầu về hạt nhân dm-verity). Để biết thông tin chi tiết về các thay đổi đối với ramdisk, hãy xem phần Phân vùng ramdisk.
Giới thiệu về bản cập nhật OTA chỉ dành cho hệ thống
Các bản cập nhật OTA chỉ dành cho hệ thống cho phép các bản phát hành Android cập nhật system.img
và product.img
mà không thay đổi các phân vùng khác, yêu cầu bố cục phân vùng hệ thống dưới dạng gốc. Tất cả thiết bị chạy Android 10 phải sử dụng bố cục phân vùng hệ thống làm gốc để bật tính năng OTA chỉ dành cho hệ thống.
- Các thiết bị A/B, gắn phân vùng
system
dưới dạng rootfs, đã sử dụng hệ thống dưới dạng gốc và không yêu cầu thay đổi để hỗ trợ OTA hệ thống. - Bạn phải cập nhật các thiết bị không phải A/B (các thiết bị gắn phân vùng
system
tại/system
) để sử dụng bố cục phân vùng hệ thống làm gốc nhằm hỗ trợ bản cập nhật OTA cho hệ thống.
Để biết thông tin chi tiết về thiết bị A/B và không phải A/B, hãy tham khảo bài viết Bản cập nhật hệ thống A/B (Liền mạch).
Sử dụng lớp phủ của nhà cung cấp (<=AOSP 14)
Lớp phủ của nhà cung cấp cho phép bạn phủ các thay đổi lên phân vùng vendor
tại thời điểm khởi động thiết bị. Lớp phủ của nhà cung cấp là một tập hợp các mô-đun của nhà cung cấp trong phân vùng product
được phủ lên phân vùng vendor
khi thiết bị khởi động, thay thế và thêm vào các mô-đun hiện có.
Khi thiết bị khởi động, quy trình init
sẽ hoàn tất quá trình gắn kết giai đoạn đầu tiên và đọc các thuộc tính mặc định. Sau đó, trình tìm kiếm sẽ tìm kiếm /product/vendor_overlay/<target_vendor_version>
và gắn từng thư mục con trên thư mục phân vùng vendor
tương ứng, nếu đáp ứng các điều kiện sau:
/vendor/<overlay_dir>
tồn tại./product/vendor_overlay/<target_vendor_version>/<overlay_dir>
có cùng ngữ cảnh tệp với/vendor/<overlay_dir>
.init
được phép gắn trên ngữ cảnh tệp của/vendor/<overlay_dir>
.
Triển khai lớp phủ của nhà cung cấp
Cài đặt tệp lớp phủ của nhà cung cấp trong /product/vendor_overlay/<target_vendor_version>
. Các tệp đó phủ lên phân vùng vendor
khi thiết bị khởi động, thay thế các tệp cùng tên và thêm mọi tệp mới. Lớp phủ của nhà cung cấp không thể xoá các tệp khỏi phân vùng vendor
.
Các tệp lớp phủ của nhà cung cấp phải có cùng ngữ cảnh tệp với các tệp đích mà chúng thay thế trong phân vùng vendor
. Theo mặc định, các tệp trong thư mục /product/vendor_overlay/<target_vendor_version>
có ngữ cảnh vendor_file
. Nếu có sự không khớp về ngữ cảnh tệp giữa các tệp lớp phủ của nhà cung cấp và các tệp mà chúng thay thế, hãy chỉ định điều đó trong chính sách bảo mật dành riêng cho thiết bị. Ngữ cảnh tệp được đặt ở cấp thư mục. Nếu ngữ cảnh tệp của thư mục lớp phủ của nhà cung cấp không khớp với thư mục mục tiêu và ngữ cảnh tệp chính xác không được chỉ định trong chính sách bảo mật dành riêng cho thiết bị, thì thư mục lớp phủ của nhà cung cấp đó sẽ không được phủ lên thư mục mục tiêu.
Để sử dụng lớp phủ của nhà cung cấp, hạt nhân phải bật OverlayFS bằng cách đặt CONFIG_OVERLAY_FS=y
. Ngoài ra, hạt nhân phải được hợp nhất từ hạt nhân phổ biến 4.4 trở lên hoặc được vá bằng "overlayfs:
override_creds=off option bypass creator_cred"
.
Ví dụ về cách triển khai lớp phủ của nhà cung cấp
Quy trình này minh hoạ cách triển khai lớp phủ của nhà cung cấp phủ lên các thư mục /vendor/lib/*
, /vendor/etc/*
và /vendor/app/*
.
-
Thêm các tệp nhà cung cấp tạo sẵn trong
device/<vendor>/<target>/vendor_overlay/<target_vendor_version>/
:device/google/device/vendor_overlay/28/lib/libfoo.so device/google/device/vendor_overlay/28/lib/libbar.so device/google/device/vendor_overlay/28/etc/baz.xml device/google/device/vendor_overlay/28/app/qux.apk
-
Cài đặt các tệp nhà cung cấp tạo sẵn vào
product/vendor_overlay
trongdevice/google/device/device.mk
:PRODUCT_COPY_FILES += \ $(call find-copy-subdir-files,*,device/google/device/vendor_overlay,$(TARGET_COPY_OUT_PRODUCT)/vendor_overlay)
-
Xác định ngữ cảnh tệp nếu các tệp phân vùng
vendor
mục tiêu có ngữ cảnh khác vớivendor_file
. Vì/vendor/lib/*
sử dụng ngữ cảnhvendor_file
, nên ví dụ này không bao gồm thư mục đó.Thêm nội dung sau vào
device/google/device-sepolicy/private/file_contexts
:/(product|system/product)/vendor_overlay/[0-9]+/etc(/.*)? u:object_r:vendor_configs_file:s0 /(product|system/product)/vendor_overlay/[0-9]+/app(/.*)? u:object_r:vendor_app_file:s0
-
Cho phép quy trình
init
gắn lớp phủ của nhà cung cấp trên các ngữ cảnh tệp khác vớivendor_file
. Vì quy trìnhinit
đã có quyền gắn trên ngữ cảnhvendor_file
, nên ví dụ này không xác định chính sách chovendor_file
.Thêm nội dung sau vào
device/google/device-sepolicy/public/init.te
:allow init vendor_configs_file:dir mounton; allow init vendor_app_file:dir mounton;
Xác thực lớp phủ của nhà cung cấp
Để xác thực cấu hình lớp phủ của nhà cung cấp, hãy thêm các tệp trong /product/vendor_overlay/<target_vendor_version>/<overlay_dir>
và kiểm tra xem các tệp đó có được phủ lên các tệp trong /vendor/<overlay_dir>
hay không.
Đối với các bản dựng userdebug
, có một mô-đun kiểm thử cho Atest:
$ atest -v fs_mgr_vendor_overlay_test
Cập nhật lên hệ thống-là-gốc
Để cập nhật các thiết bị không phải A/B để sử dụng hệ thống làm thư mục gốc, bạn phải cập nhật giao thức phân vùng cho boot.img
và system.img
, thiết lập dm-verity và xoá mọi phần phụ thuộc khởi động trên thư mục gốc dành riêng cho thiết bị.
Cập nhật phân vùng
Không giống như các thiết bị A/B sử dụng lại /boot
làm phân vùng khôi phục, các thiết bị không phải A/B phải tách riêng phân vùng /recovery
vì chúng không có phân vùng khe dự phòng (ví dụ: từ boot_a
đến boot_b
). Nếu /recovery
bị xoá trên thiết bị không phải A/B và được tạo tương tự như lược đồ A/B, thì chế độ khôi phục có thể bị hỏng trong quá trình cập nhật không thành công cho phân vùng /boot
. Vì lý do này, phân vùng /recovery
phải là một phân vùng riêng biệt với /boot
đối với các thiết bị không phải A/B, điều này có nghĩa là hình ảnh khôi phục sẽ tiếp tục được cập nhật theo cách trì hoãn (tức là giống như trong các thiết bị chạy Android 8.1.0 trở xuống).
Bảng sau đây liệt kê các điểm khác biệt về phân vùng hình ảnh cho các thiết bị không phải A/B trước và sau Android 9.
Hình ảnh | Ramdisk (trước phiên bản 9) | Hệ thống làm thư mục gốc (sau phiên bản 9) |
---|---|---|
boot.img |
Chứa một hạt nhân và ramdisk.img :
ramdisk.img -/ - init.rc - init - etc -> /system/etc - system/ (mount point) - vendor/ (mount point) - odm/ (mount point) ... |
Chỉ chứa một hạt nhân khởi động thông thường. |
recovery.img |
Chứa hạt nhân khôi phục và ramdisk.img khôi phục. |
|
system.img |
Chứa những nội dung sau:
system.img -/ - bin/ - etc - vendor -> /vendor - ... |
Chứa nội dung hợp nhất của system.img và ramdisk.img ban đầu:
system.img -/ - init.rc - init - etc -> /system/etc - system/ - bin/ - etc/ - vendor -> /vendor - ... - vendor/ (mount point) - odm/ (mount point) ... |
Bản thân các phân vùng không thay đổi; cả ramdisk và system-as-root đều sử dụng lược đồ phân vùng sau:
/boot
/system
/system
/recovery
/vendor
, v.v.
Thiết lập dm-verity
Trong hệ thống dưới dạng thư mục gốc, nhân phải gắn system.img
trong /
(điểm gắn) bằng dm-verity. AOSP hỗ trợ các phương thức triển khai dm-verity sau đây cho system.img
.
vboot 1.0
Đối với vboot 1.0, hạt nhân phải phân tích cú pháp siêu dữ liệu dành riêng cho Android trên /system
, sau đó chuyển đổi thành tham số dm-verity để thiết lập dm-verity (yêu cầu các bản vá hạt nhân này).
Ví dụ sau đây cho thấy các chế độ cài đặt liên quan đến dm-verity cho hệ thống dưới dạng thư mục gốc trong dòng lệnh hạt nhân:
ro root=/dev/dm-0 rootwait skip_initramfs init=/init dm="system none ro,0 1 android-verity /dev/sda34" veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f
vboot 2.0
Đối với vboot 2.0 (AVB), trình tải khởi động phải tích hợp external/avb/libavb, sau đó phân tích cú pháp hashtree descriptor cho /system
, chuyển đổi thành dm-verity params và cuối cùng truyền các tham số này đến hạt nhân thông qua dòng lệnh hạt nhân. (Trình mô tả Hashtree của /system
có thể nằm trên /vbmeta
hoặc trên chính /system
.)
vboot 2.0 yêu cầu các bản vá nhân sau:
- https://android-review.googlesource.com/#/c/kernel/common/+/158491/
- các bản vá kernel 4.4, các bản vá kernel 4.9, v.v.
Ví dụ sau đây cho thấy các chế độ cài đặt liên quan đến dm-verity cho hệ thống dưới dạng thư mục gốc trong dòng lệnh hạt nhân:
ro root=/dev/dm-0 rootwait skip_initramfs init=/init dm="1 vroot none ro 1,0 5159992 verity 1 PARTUUID=00000016-0000-0000-0000-000000000000 PARTUUID=00000016-0000-0000-0000-000000000000 4096 4096 644999 644999 sha1 d80b4a8be3b58a8ab86fad1b498640892d4843a2 8d08feed2f55c418fb63447fec0d32b1b107e42c 10 restart_on_corruption ignore_zero_blocks use_fec_from_device PARTUUID=00000016-0000-0000-0000-000000000000 fec_roots 2 fec_blocks 650080 fec_start 650080"
Sử dụng thư mục gốc dành riêng cho thiết bị
Với hệ thống làm thư mục gốc, sau khi hình ảnh hệ thống chung (GSI) được cài đặt ROM trên thiết bị (và trước khi chạy các chương trình kiểm thử Bộ kiểm thử của nhà cung cấp), mọi thư mục gốc dành riêng cho thiết bị được thêm bằng BOARD_ROOT_EXTRA_FOLDERS
sẽ biến mất vì toàn bộ nội dung thư mục gốc đã được thay thế bằng GSI hệ thống làm thư mục gốc. Việc xoá các thư mục này có thể khiến thiết bị không khởi động được nếu có phần phụ thuộc trên các thư mục gốc dành riêng cho thiết bị (ví dụ: các thư mục này được dùng làm điểm gắn).
Để tránh vấn đề này, đừng sử dụng BOARD_ROOT_EXTRA_FOLDERS
để thêm thư mục gốc dành riêng cho thiết bị. Nếu bạn cần chỉ định các điểm gắn theo thiết bị, hãy sử dụng /mnt/vendor/<mount point>
(được thêm vào các danh sách thay đổi này). Bạn có thể chỉ định trực tiếp các điểm gắn này theo nhà cung cấp trong cả cây thiết bị fstab
(để gắn ở giai đoạn đầu) và tệp /vendor/etc/fstab.{ro.hardware}
mà không cần thiết lập thêm (vì fs_mgr
sẽ tự động tạo các điểm gắn này trong /mnt/vendor/*
).