Bố cục phân vùng

Trong Android 10, hệ thống tệp gốc không còn được bao gồm trong ramdisk.img và thay vào đó được hợp nhất vào system.img (nghĩa là system.img luôn được tạo như thể BOARD_BUILD_SYSTEM_ROOT_IMAGE đã được đặt). Các thiết bị khởi chạy với Android 10:

  • Sử dụng bố cục phân vùng gốc hệ thống (được bản dựng tự động thực thi mà không có tùy chọn nào để thay đổi hành vi).
  • Phải sử dụng đĩa RAM, điều này cần thiết cho dm-tuyến tính.
  • Phải đặt BOARD_BUILD_SYSTEM_ROOT_IMAGE thành false . Cài đặt này chỉ được sử dụng để phân biệt giữa các thiết bị sử dụng đĩa RAM và các thiết bị không sử dụng đĩa RAM (và thay vào đó hãy gắn trực tiếp system.img ).

Ý nghĩa của cấu hình hệ thống dưới dạng root khác nhau giữa Android 9 và Android 10. Trong cấu hình hệ thống dưới dạng root của Android 9, BOARD_BUILD_SYSTEM_ROOT_IMAGE được đặt thành true , điều này buộc bản dựng phải 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 tin 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 là tùy chọn đố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 phiên bản Android thấp hơn. Trong cấu hình hệ thống dưới dạng root của Android 10, bản dựng luôn hợp nhất $TARGET_SYSTEM_OUT$TARGET_ROOT_OUT vào system.img ; cấu hình này là hành vi mặc định cho tất cả các thiết bị chạy Android 10.

Android 10 thực hiện các thay đổi tiếp theo để 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ập nhật qua mạng (OTA) để tạo, thay đổi kích thước hoặc hủy phân vùng. Là một phần của thay đổi này, nhân Linux không còn có thể gắn phân vùng hệ thống logic trên các thiết bị chạy Android 10 nữa, do đó thao tác này được xử lý bởi init giai đoạn đầu tiên.

Các phần sau đây mô tả các yêu cầu về hệ thống với tư cách là root đối với các 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 với tư cách là root (bao gồm các thay đổi về bố cục phân vùng và các yêu cầu về hạt nhân dm-verity). Để biết chi tiết về những thay đổi đối với ramdisk, hãy xem Phân vùng Ramdisk .

Giới thiệu về các OTA chỉ dành cho hệ thống

Các 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.imgproduct.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 gốc hệ thống. Tất cả các thiết bị chạy Android 10 phải sử dụng bố cục phân vùng gốc hệ thống để kích hoạt các OTA chỉ dành cho hệ thống.

Để biết chi tiết về các thiết bị A/B và không phải A/B, hãy tham khảo 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

Lớp phủ nhà cung cấp cho phép bạn phủ các thay đổi đối với phân vùng vendor khi khởi động thiết bị. Lớp phủ nhà cung cấp là một tập hợp các mô-đun 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, quá 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 đó, nó tìm kiếm /product/vendor_overlay/<target_vendor_version> và gắn từng thư mục con vào thư mục phân vùng vendor tương ứng của nó, 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 vào ngữ cảnh tệp của /vendor/<overlay_dir> .

Triển khai lớp phủ 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 bất kỳ tệp mới nào. Lớp phủ nhà cung cấp không thể xóa 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ó ngữ cảnh tệp không khớp giữa tệp lớp phủ của nhà cung cấp và tệp mà họ thay thế, hãy chỉ định điều đó trong chính sách 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 đích và ngữ cảnh tệp chính xác không được chỉ định trong chính sách riêng biệ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 đích.

Để sử dụng lớp phủ của nhà cung cấp, kernel phải bật OverlayFS bằng cách đặt CONFIG_OVERLAY_FS=y . Ngoài ra, kernel phải được hợp nhất từ ​​kernel thông thường 4.4 trở lên hoặc được vá bằng "overlayfs: override_creds=off option bypass creator_cred" .

Ví dụ về triển khai lớp phủ nhà cung cấp

Quy trình này minh họa việc triển khai lớp phủ nhà cung cấp phủ lên các thư mục /vendor/lib/* , /vendor/etc/*/vendor/app/* .

  1. Thêm các tệp nhà cung cấp dựng 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
    
  2. Cài đặt các tệp nhà cung cấp dựng sẵn vào product/vendor_overlay trong device/google/device/device.mk :

    PRODUCT_COPY_FILES += \
        $(call find-copy-subdir-files,*,device/google/device/vendor_overlay,$(TARGET_COPY_OUT_PRODUCT)/vendor_overlay)
    
  3. Xác định ngữ cảnh tệp nếu tệp phân vùng vendor mục tiêu có ngữ cảnh khác với vendor_file . Vì /vendor/lib/* sử dụng ngữ cảnh vendor_file nên ví dụ này không bao gồm thư mục đó.

    Thêm phần 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
    
  4. Cho phép quá trình init gắn kết lớp phủ của nhà cung cấp trên các ngữ cảnh tệp khác với vendor_file . Vì quy trình init đã có quyền gắn vào ngữ cảnh vendor_file , nên ví dụ này không xác định chính sách cho vendor_file .

    Thêm phần 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ủ 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 tệp vào /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 thử nghiệm cho Atest :

$ atest -v fs_mgr_vendor_overlay_test

Cập nhật lên hệ thống với quyền root

Để cập nhật các thiết bị không phải A/B để sử dụng hệ thống với quyền root, bạn phải cập nhật sơ đồ phân vùng cho boot.imgsystem.img , thiết lập dm-verity và xóa mọi phụ thuộc khởi động trên các 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 biệt 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ị xóa trên thiết bị không phải A/B và được thực hiện tương tự như sơ đồ A/B, chế độ khôi phục có thể bị hỏng trong quá trình cập nhật không thành công vào phân vùng /boot . Vì lý do này, phân vùng /recovery phải là 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, ngụ ý rằng hình ảnh khôi phục sẽ tiếp tục được cập nhật theo cách trì hoãn (nghĩa là giống như trong các thiết bị chạy Android 8.1.0 trở xuống).

Bảng sau liệt kê sự 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 Đĩa Ram (trước 9) Hệ thống là root (sau 9)
boot.img Chứa kernel và ramdisk.img :
ramdisk.img
  -/
    - init.rc
    - init
    - etc -> /system/etc
    - system/ (mount point)
    - vendor/ (mount point)
    - odm/ (mount point)
    ...
Chỉ chứa kernel khởi động bình thường.
recovery.img Chứa kernel khôi phục và ramdisk.img khôi phục.
system.img Chứa các mục sau:
system.img
  -/
    - bin/
    - etc
    - vendor -> /vendor
    - ...
Chứa nội dung đã hợp nhất của system.imgramdisk.img gốc:
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 sơ đồ 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 root, kernel phải gắn system.img dưới / (điểm gắn kết) với dm-verity . AOSP hỗ trợ triển khai dm-verity sau cho system.img .

vboot 1.0

Đối với vboot 1.0 , hạt nhân phải phân tích siêu dữ liệu dành riêng cho Android trên /system , sau đó chuyển đổi sang thông 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 hiển thị các cài đặt liên quan đến dm-verity cho system-as-root trong dòng lệnh kernel:

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 ), bộ nạp khởi động phải tích hợp external/avb/libavb , sau đó phân tích bộ mô tả hashtree cho /system , chuyển đổi nó thành dm-verity params và cuối cùng chuyển các thông số đó cho kernel thông qua dòng lệnh kernel. (Các bộ 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á kernel sau:

Ví dụ sau đây hiển thị các cài đặt liên quan đến dm-verity cho system-as-root trong dòng lệnh kernel:

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à root, sau khi hình ảnh hệ thống chung (GSI) được flash trên thiết bị (và trước khi chạy thử nghiệm Bộ kiểm tra nhà cung cấp ), mọi thư mục gốc dành riêng cho thiết bị được thêm 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ởi GSI gốc hệ thống. Việc xóa các thư mục này có thể khiến thiết bị không thể khởi động được nếu tồn tại sự phụ thuộc vào các thư mục gốc dành riêng cho thiết bị (ví dụ: chúng được sử dụng làm điểm gắn kết).

Để tránh sự cố này, khô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 kết dành riêng cho 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). Các điểm gắn kết dành riêng cho nhà cung cấp này có thể được chỉ định trực tiếp trong cả cây thiết bị fstab (đối với quá trình gắn kết ở giai đoạn đầu) và tệp /vendor/etc/fstab.{ro.hardware} mà không cần thiết lập bổ sung (vì fs_mgr tạo chúng trong /mnt/vendor/* tự động).