Gắn các phân vùng sớm

Các thiết bị hỗ trợ Treble phải kích hoạt tính năng gắn kết giai đoạn đầu tiên để đảm bảo init có thể tải các đoạn chính sách Linux được tăng cường bảo mật (SELinux) trải rộng trên các phân vùng systemvendor . Quyền truy cập này cũng cho phép tải các mô-đun hạt nhân càng sớm càng tốt sau khi hạt nhân khởi động.

Để thực hiện việc gắn sớm, Android phải có quyền truy cập vào hệ thống tệp chứa mô-đun. Android 8.0 trở lên hỗ trợ gắn /system , /vendor hoặc /odm ngay từ giai đoạn đầu tiên của init (nghĩa là trước khi SElinux được khởi tạo).

Mục Fstab

Trong Android 9 trở xuống, thiết bị có thể chỉ định mục nhập fstab cho các phân vùng được gắn sớm bằng cách sử dụng lớp phủ cây thiết bị (DTO) . Trong Android 10 trở lên, thiết bị phải chỉ định các mục nhập fstab cho các phân vùng được gắn sớm bằng tệp fstab trong ramdisk giai đoạn đầu tiên. Android 10 giới thiệu các cờ fs_mgr sau để sử dụng trong tệp fstab :

  • first_stage_mount chỉ ra rằng một phân vùng sẽ được gắn kết bởi init giai đoạn đầu tiên.
  • logical chỉ ra rằng đây là một phân vùng động .
  • avb= vbmeta-partition-name chỉ định phân vùng vbmeta . Giai đoạn đầu tiên init khởi tạo phân vùng này trước khi gắn các phân vùng khác. Đối số cho cờ này có thể được bỏ qua nếu phân vùng vbmeta cho mục nhập đã được chỉ định bởi mục nhập fstab khác ở dòng trước đó.

Ví dụ sau đây hiển thị các mục fstab để đặt các phân vùng system , vendorproduct làm phân vùng logic (động).

#<dev>  <mnt_point> <type>  <mnt_flags options> <fs_mgr_flags>
system   /system     ext4    ro,barrier=1     wait,slotselect,avb=vbmeta_system,logical,first_stage_mount
vendor   /vendor     ext4    ro,barrier=1     wait,slotselect,avb=vbmeta,logical,first_stage_mount
product  /product    ext4    ro,barrier=1     wait,slotselect,avb,logical,first_stage_mount

Trong ví dụ này, nhà cung cấp chỉ định phân vùng vbmeta bằng cờ fs_mgr avb=vbmeta , nhưng product bỏ qua đối vbmeta vì nhà cung cấp đã thêm vbmeta vào danh sách phân vùng.

Các thiết bị chạy Android 10 trở lên phải đặt tệp fstab vào ramdisk và phân vùng vendor .

Đĩa RAM

Vị trí tệp fstab trong ramdisk phụ thuộc vào cách thiết bị sử dụng ramdisk.

Các thiết bị có đĩa ram khởi động phải đặt tệp fstab vào thư mục gốc của đĩa ram khởi động. Nếu thiết bị có cả đĩa ram khởi động và đĩa ram khôi phục thì không cần thay đổi nào đối với đĩa ram khôi phục. Ví dụ:

PRODUCT_COPY_FILES +=  device/google/<product-name>/fstab.hardware:$(TARGET_COPY_OUT_RAMDISK)/fstab.$(PRODUCT_PLATFORM)

Các thiết bị sử dụng recovery làm ramdisk phải sử dụng tham số dòng lệnh kernel androidboot.force_normal_boot=1 để quyết định nên khởi động vào Android hay tiếp tục khởi động vào recovery. Các thiết bị khởi chạy Android 12 trở lên với phiên bản kernel 5.10 trở lên phải sử dụng bootconfig để truyền tham số androidboot.force_normal_boot=1 . Trong các thiết bị này, init giai đoạn đầu tiên thực hiện thao tác chuyển gốc sang /first_stage_ramdisk trước khi gắn các phân vùng gắn kết sớm, vì vậy các thiết bị phải đặt tệp fstab vào $(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk . Ví dụ:

PRODUCT_COPY_FILES +=  device/google/<product-name>/fstab.hardware:$(TARGET_COPY_OUT_RECOVERY)/root/first_stage_ramdisk/fstab.$(PRODUCT_PLATFORM)

Người bán

Tất cả các thiết bị phải đặt một bản sao của tệp fstab vào /vendor/etc . Điều này là do giai đoạn đầu tiên init giải phóng đĩa RAM sau khi nó hoàn thành quá trình gắn phân vùng sớm và thực hiện thao tác chuyển đổi gốc để di chuyển mount tại /system sang / . Do đó, mọi hoạt động tiếp theo cần truy cập vào tệp fstab đều phải sử dụng bản sao trong /vendor/etc . Ví dụ:

PRODUCT_COPY_FILES +=  device/google/<product-name>/fstab.hardware:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.$(PRODUCT_PLATFORM)

Mount phân vùng sớm, VBoot 1.0

Yêu cầu để mount sớm phân vùng bằng VBoot 1.0 bao gồm:

  1. Đường dẫn nút thiết bị phải sử dụng các liên kết tượng trưng by-name của chúng trong các mục nhập fstab và devicetree. Ví dụ: thay vì chỉ định phân vùng bằng cách sử dụng /dev/block/mmcblk0pX , hãy đảm bảo rằng các phân vùng được đặt tên và nút thiết bị là /dev/block/…./by-name/{system,vendor,odm} .
  2. Các đường dẫn được cung cấp cho PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITIONCUSTOM_IMAGE_VERITY_BLOCK_DEVICE trong cấu hình thiết bị cho sản phẩm (nghĩa là trong device/ oem / project /device.mk ) phải khớp với các nút thiết bị khối tương ứng được chỉ định by-name trong fstab /devicetree mục. Ví dụ:
    PRODUCT_SYSTEM_VERITY_PARTITION := /dev/block/…./by-name/system
    PRODUCT_VENDOR_VERITY_PARTITION := /dev/block/…./by-name/vendor
    CUSTOM_IMAGE_VERITY_BLOCK_DEVICE := /dev/block/…./by-name/odm
    
  3. Các mục nhập được cung cấp thông qua lớp phủ cây thiết bị không được lặp lại trong các đoạn tệp fstab . Ví dụ: khi chỉ định một mục để gắn /vendor trong cây thiết bị, tệp fstab không được lặp lại mục đó.
  4. Các phân vùng yêu cầu verifyatboot không được gắn sớm (làm như vậy không được hỗ trợ).
  5. Chế độ/trạng thái xác thực cho các phân vùng đã xác minh phải được chỉ định trong kernel_cmdline bằng tùy chọn androidboot.veritymode (yêu cầu hiện có).

Gắn devicetree sớm, VBoot 1.0

Trong Android 8.x trở lên, init phân tích cây thiết bị và tạo các mục nhập fstab để sớm gắn kết phân vùng trong giai đoạn đầu tiên. Một mục fstab có dạng:

src mnt_point type mnt_flags fs_mgr_flags

Các thuộc tính của cây thiết bị được xác định để bắt chước định dạng đó:

  • Các mục fstab phải ở dưới /firmware/android/fstab trong cây thiết bị và phải có chuỗi tương thích được đặt thành android,fstab .
  • Mỗi nút trong /firmware/android/fstab được coi là một mục nhập fstab gắn kết sớm duy nhất. Một nút phải có các thuộc tính sau được xác định:
    • dev phải trỏ đến nút thiết bị đại diện cho phân vùng by-name
    • type phải là loại hệ thống tệp (như trong tệp fstab )
    • mnt_flags phải là danh sách các cờ gắn kết được phân tách bằng dấu phẩy (như trong tệp fstab )
    • fsmgr_flags phải là danh sách fs_mgr flags của Android (như trong tệp fstab )
  • Các phân vùng A/B phải có tùy chọn slotselect fs_mgr .
  • Các phân vùng kích hoạt dm-verity phải có tùy chọn verify fs_mgr .

Ví dụ: /system và /vendor trên N6P

Ví dụ sau đây cho thấy quá trình gắn kết sớm của devicetree cho các phân vùng systemvendor trên Nexus 6P:

/ {
  firmware {
    android {
      compatible = "android,firmware";
      fstab {
        compatible = "android,fstab";
        system {
          compatible = "android,system";
          dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/system";
          type = "ext4";
          mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
          fsmgr_flags = "wait,verify";
        };
        vendor {
          compatible = "android,vendor";
          dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor";
          type = "ext4";
          mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
          fsmgr_flags = "wait";
        };
      };
    };
  };
};

Ví dụ: /nhà cung cấp trên Pixel

Ví dụ sau cho thấy sự gắn kết sớm của cây thiết bị cho /vendor trên Pixel (hãy nhớ thêm slotselect cho các phân vùng tuân theo A/B):

/ {
  firmware {
    android {
      compatible = "android,firmware";
      fstab {
        compatible = "android,fstab";
        vendor {
          compatible = "android,vendor";
          dev = "/dev/block/platform/soc/624000.ufshc/by-name/vendor";
          type = "ext4";
          mnt_flags = "ro,barrier=1,discard";
          fsmgr_flags = "wait,slotselect,verify";
        };
      };
    };
  };
};

Mount phân vùng sớm, VBoot 2.0

VBoot 2.0 là Khởi động được xác minh của Android (AVB) . Các yêu cầu để gắn kết sớm các phân vùng với VBoot 2.0 là:

  1. Các đường dẫn nút thiết bị phải sử dụng các liên kết tượng trưng by-name của chúng trong các mục nhập fstab và devicetree. Ví dụ: thay vì chỉ định phân vùng bằng cách sử dụng /dev/block/mmcblk0pX , hãy đảm bảo rằng các phân vùng được đặt tên và nút thiết bị là /dev/block/…./by-name/{system,vendor,odm} .
  2. Xây dựng các biến hệ thống (chẳng hạn như PRODUCT_{SYSTEM,VENDOR}_VERITY_PARTITIONCUSTOM_IMAGE_VERITY_BLOCK_DEVICE ) được sử dụng cho VBoot 1.0 KHÔNG bắt buộc đối với VBoot 2.0. Thay vào đó, nên xác định các biến xây dựng được giới thiệu trong VBoot 2.0 (bao gồm BOARD_AVB_ENABLE := true ); để biết cấu hình đầy đủ, hãy tham khảo Xây dựng tích hợp hệ thống cho AVB .
  3. Các mục nhập được cung cấp thông qua lớp phủ cây thiết bị không được lặp lại trong các đoạn tệp fstab . Ví dụ: nếu bạn chỉ định một mục để gắn /vendor trong cây thiết bị, tệp fstab không được lặp lại mục đó.
  4. VBoot 2.0 không hỗ trợ verifyatboot , cho dù việc gắn kết sớm có được bật hay không.
  5. Chế độ/trạng thái xác thực cho các phân vùng đã xác minh phải được chỉ định trong kernel_cmdline bằng tùy chọn androidboot.veritymode (yêu cầu hiện có). Đảm bảo bao gồm các bản sửa lỗi sau cho AVB:

Gắn devicetree sớm, VBoot 2.0

Cấu hình trong devicetree cho VBoot 2.0 giống như trong VBoot 1.0 , ngoại trừ các ngoại lệ sau:

  • fsmgr_flag được chuyển từ verify sang avb .
  • Tất cả các phân vùng có siêu dữ liệu AVB phải nằm trong mục VBMeta trong cây thiết bị, ngay cả khi phân vùng không được cài đặt sớm (ví dụ: /boot ).

Ví dụ: /system và /vendor trên N5X

Ví dụ sau đây cho thấy quá trình gắn kết ban đầu của cây thiết bị cho các phân vùng systemvendor trên Nexus 5X. Lưu ý rằng:

  • /system được gắn kết với AVB và /vendor được gắn kết mà không cần xác minh tính toàn vẹn.
  • Vì Nexus 5X không có phân vùng /vbmeta nên vbmeta cấp cao nhất nằm ở cuối phân vùng /boot (để biết chi tiết, hãy tham khảo danh sách thay đổi AOSP ).
    / {
      firmware {
        android {
          compatible = "android,firmware";
          vbmeta {
            compatible = "android,vbmeta";
            parts = "boot,system,vendor";
          };
          fstab {
            compatible = "android,fstab";
            system {
              compatible = "android,system";
              dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/system";
              type = "ext4";
              mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
              fsmgr_flags = "wait,avb";
            };
            vendor {
              compatible = "android,vendor";
              dev = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor";
              type = "ext4";
              mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
              fsmgr_flags = "wait";
            };
          };
        };
      };
    };
    

Ví dụ: /nhà cung cấp trên Pixel

Ví dụ sau đây cho thấy việc sớm gắn /vendor trên Pixel. Lưu ý rằng:

  • Nhiều phân vùng hơn được chỉ định trong mục vbmeta vì những phân vùng đó được bảo vệ bởi AVB .
  • Tất cả các phân vùng AVB phải được đưa vào, ngay cả khi chỉ /vendor được gắn sớm.
  • Hãy nhớ thêm slotselect cho các phân vùng thuộc A/B.
    / {
      vbmeta {
        compatible = "android,vbmeta";
        parts = "vbmeta,boot,system,vendor,dtbo";
      };
      firmware {
        android {
          compatible = "android,firmware";
          fstab {
            compatible = "android,fstab";
            vendor {
              compatible = "android,vendor";
              dev = "/dev/block/platform/soc/624000.ufshc/by-name/vendor";
              type = "ext4";
              mnt_flags = "ro,barrier=1,discard";
              fsmgr_flags = "wait,slotselect,avb";
            };
          };
        };
      };
    };