Triển khai phân vùng động

Phân vùng động được triển khai bằng cách sử dụng mô-đun ánh xạ thiết bị dm-tuyến tính trong nhân Linux. super phân vùng chứa siêu dữ liệu liệt kê tên và phạm vi khối của từng phân vùng động trong super . Trong giai đoạn đầu tiên init , siêu dữ liệu này được phân tích cú pháp và xác thực, đồng thời các thiết bị khối ảo được tạo để thể hiện từng phân vùng động.

Khi áp dụng OTA, các phân vùng động sẽ tự động được tạo, thay đổi kích thước hoặc xóa nếu cần. Đối với thiết bị A/B, có hai bản sao siêu dữ liệu và các thay đổi chỉ được áp dụng cho bản sao đại diện cho vùng mục tiêu.

Vì các phân vùng động được triển khai trong không gian người dùng nên các phân vùng mà bộ nạp khởi động cần không thể được tạo thành động. Ví dụ: boot , dtbovbmeta được bộ tải khởi động đọc và do đó phải duy trì dưới dạng phân vùng vật lý.

Mỗi phân vùng động có thể thuộc về một nhóm cập nhật . Các nhóm này giới hạn dung lượng tối đa mà các phân vùng trong nhóm đó có thể sử dụng. Ví dụ: systemvendor có thể thuộc về một nhóm giới hạn tổng kích thước của systemvendor .

Triển khai phân vùng động trên thiết bị mới

Phần này trình bày chi tiết cách triển khai phân vùng động trên các thiết bị mới chạy Android 10 trở lên. Để cập nhật các thiết bị hiện có, hãy xem Nâng cấp thiết bị Android .

Thay đổi phân vùng

Đối với các thiết bị chạy Android 10, hãy tạo một phân vùng có tên super . super phân vùng xử lý các khe A/B bên trong, vì vậy các thiết bị A/B không cần các phân vùng super_asuper_b riêng biệt. Tất cả các phân vùng AOSP chỉ đọc mà bộ tải khởi động không sử dụng phải là phân vùng động và phải được xóa khỏi Bảng phân vùng GUID (GPT). Các phân vùng dành riêng cho nhà cung cấp không cần phải động và có thể được đặt trong GPT.

Để ước tính kích thước của super , hãy thêm kích thước của các phân vùng bị xóa khỏi GPT. Đối với thiết bị A/B, điều này phải bao gồm kích thước của cả hai vị trí. Hình 1 hiển thị bảng phân vùng ví dụ trước và sau khi chuyển đổi sang phân vùng động.

Bố cục bảng phân vùng
Hình 1. Bố cục bảng phân vùng vật lý mới khi chuyển đổi sang phân vùng động

Các phân vùng động được hỗ trợ là:

  • Hệ thống
  • Người bán
  • Sản phẩm
  • Hệ thống mở rộng
  • ODM

Đối với các thiết bị chạy Android 10, tùy chọn dòng lệnh kernel androidboot.super_partition phải trống để lệnh sysprop ro.boot.super_partition trống.

Căn chỉnh phân vùng

Mô-đun ánh xạ thiết bị có thể hoạt động kém hiệu quả hơn nếu super phân vùng không được căn chỉnh chính xác. super phân vùng PHẢI được căn chỉnh theo kích thước yêu cầu I/O tối thiểu được xác định bởi lớp khối. Theo mặc định, hệ thống xây dựng (thông qua lpmake , tạo ra hình ảnh super phân vùng), giả định rằng căn chỉnh 1 MiB là đủ cho mọi phân vùng động. Tuy nhiên, nhà cung cấp phải đảm bảo rằng super phân vùng được căn chỉnh chính xác.

Bạn có thể xác định kích thước yêu cầu tối thiểu của thiết bị khối bằng cách kiểm tra sysfs . Ví dụ:

# ls -l /dev/block/by-name/super
lrwxrwxrwx 1 root root 16 1970-04-05 01:41 /dev/block/by-name/super -> /dev/block/sda17
# cat /sys/block/sda/queue/minimum_io_size
786432

Bạn có thể xác minh sự liên kết của super phân vùng theo cách tương tự:

# cat /sys/block/sda/sda17/alignment_offset

Độ lệch căn chỉnh PHẢI bằng 0.

Thay đổi cấu hình thiết bị

Để bật phân vùng động, hãy thêm cờ sau vào device.mk :

PRODUCT_USE_DYNAMIC_PARTITIONS := true

Thay đổi cấu hình bảng

Bạn được yêu cầu đặt kích thước của super phân vùng:

BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

Trên thiết bị A/B, hệ thống xây dựng sẽ báo lỗi nếu tổng kích thước của hình ảnh phân vùng động lớn hơn một nửa kích thước super phân vùng.

Bạn có thể cấu hình danh sách các phân vùng động như sau. Đối với các thiết bị sử dụng nhóm cập nhật, hãy liệt kê các nhóm trong biến BOARD_SUPER_PARTITION_GROUPS . Sau đó, mỗi tên nhóm có một biến BOARD_ group _SIZEBOARD_ group _PARTITION_LIST . Đối với thiết bị A/B, kích thước tối đa của một nhóm chỉ được bao gồm một vị trí vì tên nhóm được gắn hậu tố vị trí bên trong.

Đây là một thiết bị mẫu đặt tất cả các phân vùng vào một nhóm có tên example_dynamic_partitions :

BOARD_SUPER_PARTITION_GROUPS := example_dynamic_partitions
BOARD_EXAMPLE_DYNAMIC_PARTITIONS_SIZE := 6442450944
BOARD_EXAMPLE_DYNAMIC_PARTITIONS_PARTITION_LIST := system vendor product

Dưới đây là một thiết bị mẫu đặt các dịch vụ hệ thống và sản phẩm vào group_foovendor , productodm vào group_bar :

BOARD_SUPER_PARTITION_GROUPS := group_foo group_bar
BOARD_GROUP_FOO_SIZE := 4831838208
BOARD_GROUP_FOO_PARTITION_LIST := system product_services
BOARD_GROUP_BAR_SIZE := 1610612736
BOARD_GROUP_BAR_PARTITION_LIST := vendor product odm
  • Đối với thiết bị khởi chạy A/B ảo, tổng kích thước tối đa của tất cả các nhóm tối đa là:
    BOARD_SUPER_PARTITION_SIZE - chi phí chung
    Xem Triển khai A/B ảo .
  • Đối với thiết bị khởi chạy A/B, tổng kích thước tối đa của tất cả các nhóm phải là:
    BOARD_SUPER_PARTITION_SIZE / 2 - chi phí
  • Đối với các thiết bị không phải A/B và thiết bị A/B được trang bị thêm, tổng kích thước tối đa của tất cả các nhóm phải là:
    BOARD_SUPER_PARTITION_SIZE - chi phí chung
  • Tại thời điểm xây dựng, tổng kích thước hình ảnh của từng phân vùng trong nhóm cập nhật không được vượt quá kích thước tối đa của nhóm.
  • Cần có chi phí chung trong quá trình tính toán để tính đến siêu dữ liệu, sắp xếp, v.v. Chi phí chung hợp lý là 4 MiB, nhưng bạn có thể chọn chi phí lớn hơn khi thiết bị cần.

Kích thước phân vùng động

Trước khi có phân vùng động, kích thước phân vùng được phân bổ quá mức để đảm bảo rằng chúng có đủ chỗ cho các bản cập nhật trong tương lai. Kích thước thực tế được lấy theo nguyên trạng và hầu hết các phân vùng chỉ đọc đều có một lượng dung lượng trống trong hệ thống tệp của chúng. Trong các phân vùng động, không gian trống đó không thể sử dụng được và có thể được sử dụng để phát triển các phân vùng trong OTA. Điều quan trọng là đảm bảo rằng các phân vùng không lãng phí dung lượng và được phân bổ ở kích thước tối thiểu có thể.

Đối với hình ảnh ext4 chỉ đọc, hệ thống xây dựng sẽ tự động phân bổ kích thước tối thiểu nếu không chỉ định kích thước phân vùng mã hóa cứng. Hệ thống xây dựng phù hợp với hình ảnh để hệ thống tệp có ít không gian chưa sử dụng nhất có thể. Điều này đảm bảo rằng thiết bị không lãng phí dung lượng có thể được sử dụng cho các OTA.

Ngoài ra, hình ảnh ext4 có thể được nén thêm bằng cách cho phép chống trùng lặp ở cấp độ khối. Để kích hoạt tính năng này, hãy sử dụng cấu hình sau:

BOARD_EXT4_SHARE_DUP_BLOCKS := true

Nếu việc tự động phân bổ kích thước tối thiểu của phân vùng là điều không mong muốn thì có hai cách để kiểm soát kích thước phân vùng. Bạn có thể chỉ định lượng không gian trống tối thiểu với BOARD_ partition IMAGE_PARTITION_RESERVED_SIZE hoặc bạn có thể chỉ định BOARD_ partition IMAGE_PARTITION_SIZE để buộc các phân vùng động theo một kích thước cụ thể. Cả hai điều này đều không được khuyến khích trừ khi cần thiết.

Ví dụ:

BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800

Điều này buộc hệ thống tệp trong product.img phải có 50 MiB dung lượng chưa sử dụng.

Thay đổi hệ thống dưới dạng root

Các thiết bị chạy Android 10 không được sử dụng quyền root.

Các thiết bị có phân vùng động (dù khởi chạy cùng hoặc trang bị thêm phân vùng động) không được sử dụng hệ thống làm root. Nhân Linux không thể diễn giải super phân vùng và do đó không thể gắn kết system . system hiện được gắn kết bởi init giai đoạn đầu tiên, nằm trong đĩa RAM.

Không đặt BOARD_BUILD_SYSTEM_ROOT_IMAGE . Trong Android 10, cờ BOARD_BUILD_SYSTEM_ROOT_IMAGE chỉ được sử dụng để phân biệt xem hệ thống được gắn bởi kernel hay bằng init giai đoạn đầu trong ramdisk.

Đặt BOARD_BUILD_SYSTEM_ROOT_IMAGE thành true sẽ gây ra lỗi xây dựng khi PRODUCT_USE_DYNAMIC_PARTITIONS cũng true .

Khi BOARD_USES_RECOVERY_AS_BOOT được đặt thành true, hình ảnh khôi phục được tạo dưới dạng boot.img, chứa ramdisk của khôi phục. Trước đây, bootloader đã sử dụng tham số dòng lệnh kernel skip_initramfs để quyết định nên khởi động vào chế độ nào. Đối với các thiết bị Android 10, bộ nạp khởi động KHÔNG PHẢI chuyển skip_initramfs vào dòng lệnh kernel. Thay vào đó, bộ nạp khởi động phải vượt qua androidboot.force_normal_boot=1 để bỏ qua quá trình khôi phục và khởi động Android bình thường. Các thiết bị chạy Android 12 trở lên phải sử dụng bootconfig để vượt qua androidboot.force_normal_boot=1 .

Thay đổi cấu hình AVB

Khi sử dụng Boot 2.0 được xác minh của Android , nếu thiết bị không sử dụng bộ mô tả phân vùng theo chuỗi thì không cần thay đổi. Tuy nhiên, nếu sử dụng phân vùng theo chuỗi và một trong các phân vùng đã được xác minh là phân vùng động thì cần phải thay đổi.

Đây là cấu hình ví dụ cho một thiết bị xâu chuỗi vbmeta cho các phân vùng systemvendor .

BOARD_AVB_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048
BOARD_AVB_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION := 1

BOARD_AVB_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
BOARD_AVB_VENDOR_ALGORITHM := SHA256_RSA2048
BOARD_AVB_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
BOARD_AVB_VENDOR_ROLLBACK_INDEX_LOCATION := 1

Với cấu hình này, bộ nạp khởi động mong muốn tìm thấy chân trang vbmeta ở cuối phân vùng systemvendor . Vì các phân vùng này không còn hiển thị với bộ nạp khởi động (chúng nằm trong super ), nên cần có hai thay đổi.

  • Thêm phân vùng vbmeta_systemvbmeta_vendor vào bảng phân vùng của thiết bị. Đối với thiết bị A/B, hãy thêm vbmeta_system_a , vbmeta_system_b , vbmeta_vendor_avbmeta_vendor_b . Nếu thêm một hoặc nhiều phân vùng này, chúng phải có cùng kích thước với phân vùng vbmeta .
  • Đổi tên các cờ cấu hình bằng cách thêm VBMETA_ và chỉ định phân vùng nào mà chuỗi mở rộng tới:
    BOARD_AVB_VBMETA_SYSTEM := system
    BOARD_AVB_VBMETA_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
    BOARD_AVB_VBMETA_SYSTEM_ALGORITHM := SHA256_RSA2048
    BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
    BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 1
    
    BOARD_AVB_VBMETA_VENDOR := vendor
    BOARD_AVB_VBMETA_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem
    BOARD_AVB_VBMETA_VENDOR_ALGORITHM := SHA256_RSA2048
    BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP)
    BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION := 1
    

Một thiết bị có thể đang sử dụng một, cả hai hoặc không sử dụng phân vùng nào trong số này. Chỉ cần thay đổi khi xâu chuỗi vào một phân vùng hợp lý.

Thay đổi bộ tải khởi động AVB

Nếu bộ tải khởi động đã nhúng libavb , hãy bao gồm các bản vá sau:

Nếu sử dụng phân vùng theo chuỗi, hãy thêm một bản vá bổ sung:

  • 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: Hỗ trợ các đốm màu vbmeta khi bắt đầu phân vùng."

Thay đổi dòng lệnh hạt nhân

Một tham số mới, androidboot.boot_devices , phải được thêm vào dòng lệnh kernel. Điều này được init sử dụng để kích hoạt các liên kết tượng /dev/block/by-name . Nó phải là thành phần đường dẫn thiết bị tới liên kết tượng trưng theo tên cơ bản được tạo bởi ueventd , nghĩa là /dev/block/platform/ device-path /by-name/ partition-name . Các thiết bị chạy Android 12 trở lên phải sử dụng bootconfig để chuyển androidboot.boot_devices tới init .

Ví dụ: nếu liên kết tượng trưng theo tên siêu phân vùng là /dev/block/platform/ soc/100000.ufshc /by-name/super , bạn có thể thêm tham số dòng lệnh trong tệp BoardConfig.mk như sau:

BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
Bạn có thể thêm tham số bootconfig trong tệp BoardConfig.mk như sau:
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc

thay đổi fstab

Cây thiết bị và lớp phủ cây thiết bị không được chứa các mục nhập fstab. Sử dụng tệp fstab sẽ là một phần của ramdisk.

Các thay đổi phải được thực hiện đối với tệp fstab đối với các phân vùng logic:

  • Trường cờ fs_mgr phải bao gồm cờ logical và cờ first_stage_mount , được giới thiệu trong Android 10, cho biết rằng một phân vùng sẽ được gắn kết trong giai đoạn đầu tiên.
  • Một phân vùng có thể chỉ định avb= vbmeta partition name làm cờ fs_mgr và sau đó phân vùng vbmeta được chỉ định sẽ được khởi tạo bởi init giai đoạn đầu tiên trước khi thử gắn bất kỳ thiết bị nào.
  • Trường dev phải là tên phân vùng.

Các mục nhập fstab sau đây đặt hệ thống, nhà cung cấp và sản phẩm làm phân vùng hợp lý theo các quy tắc trên.

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

Sao chép tệp fstab vào ramdisk giai đoạn đầu tiên.

Những thay đổi của SELinux

Thiết bị khối siêu phân vùng phải được đánh dấu bằng nhãn super_block_device . Ví dụ: nếu liên kết tượng trưng theo tên siêu phân vùng là /dev/block/platform/ soc/100000.ufshc /by-name/super , hãy thêm dòng sau vào file_contexts :

/dev/block/platform/soc/10000\.ufshc/by-name/super   u:object_r:super_block_device:s0

khởi động nhanh

Bộ tải khởi động (hoặc bất kỳ công cụ flash không phải vùng người dùng nào) không hiểu các phân vùng động nên không thể flash chúng. Để giải quyết vấn đề này, các thiết bị phải sử dụng triển khai giao thức fastboot trong không gian người dùng, được gọi là fastbootd.

Để biết thêm thông tin về cách triển khai fastbootd, hãy xem Di chuyển Fastboot sang không gian người dùng .

adb kể lại

Đối với các nhà phát triển sử dụng bản dựng eng hoặc userdebug, adb remount cực kỳ hữu ích để lặp lại nhanh. Phân vùng động gây ra sự cố cho adb remount vì không còn dung lượng trống trong mỗi hệ thống tệp. Để giải quyết vấn đề này, các thiết bị có thể kích hoạt lớp phủ. Miễn là có không gian trống trong siêu phân vùng, adb remount sẽ tự động tạo một phân vùng động tạm thời và sử dụng lớp phủ để ghi. Phân vùng tạm thời được đặt tên là scratch , vì vậy đừng sử dụng tên này cho các phân vùng khác.

Để biết thêm thông tin về cách bật lớp phủ, hãy xem lớp phủ README trong AOSP.

Nâng cấp thiết bị Android

Nếu bạn nâng cấp thiết bị lên Android 10 và muốn hỗ trợ phân vùng động trong OTA, bạn không cần thay đổi bảng phân vùng tích hợp sẵn. Một số cấu hình bổ sung là cần thiết.

Thay đổi cấu hình thiết bị

Để trang bị thêm phân vùng động, hãy thêm các cờ sau vào device.mk :

PRODUCT_USE_DYNAMIC_PARTITIONS := true
PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true

Thay đổi cấu hình bảng

Bạn được yêu cầu đặt các biến bảng sau:

  • Đặt BOARD_SUPER_PARTITION_BLOCK_DEVICES vào danh sách các thiết bị khối được sử dụng để lưu trữ phạm vi phân vùng động. Đây là danh sách tên các phân vùng vật lý hiện có trên thiết bị.
  • Đặt BOARD_SUPER_PARTITION_ partition _DEVICE_SIZE theo kích thước của từng thiết bị khối trong BOARD_SUPER_PARTITION_BLOCK_DEVICES tương ứng. Đây là danh sách kích thước của các phân vùng vật lý hiện có trên thiết bị. Đây thường là BOARD_ partition IMAGE_PARTITION_SIZE trong cấu hình bảng hiện có.
  • Bỏ đặt BOARD_ partition IMAGE_PARTITION_SIZE cho tất cả các phân vùng trong BOARD_SUPER_PARTITION_BLOCK_DEVICES .
  • Đặt BOARD_SUPER_PARTITION_SIZE thành tổng BOARD_SUPER_PARTITION_ partition _DEVICE_SIZE .
  • Đặt BOARD_SUPER_PARTITION_METADATA_DEVICE cho thiết bị khối nơi lưu trữ siêu dữ liệu phân vùng động. Nó phải là một trong BOARD_SUPER_PARTITION_BLOCK_DEVICES . Thông thường, điều này được đặt thành system .
  • Đặt lần lượt BOARD_SUPER_PARTITION_GROUPS , BOARD_ group _SIZEBOARD_ group _PARTITION_LIST . Xem các thay đổi về cấu hình Board trên thiết bị mới để biết chi tiết.

Ví dụ: nếu thiết bị đã có phân vùng hệ thống và nhà cung cấp và bạn muốn chuyển đổi chúng thành phân vùng động và thêm phân vùng sản phẩm mới trong quá trình cập nhật, hãy đặt cấu hình bảng này:

BOARD_SUPER_PARTITION_BLOCK_DEVICES := system vendor
BOARD_SUPER_PARTITION_METADATA_DEVICE := system

# Rename BOARD_SYSTEMIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE.
BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE := <size-in-bytes>

# Rename BOARD_VENDORIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE
BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE := <size-in-bytes>

# This is BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE + BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>

# Configuration for dynamic partitions. For example:
BOARD_SUPER_PARTITION_GROUPS := group_foo
BOARD_GROUP_FOO_SIZE := <size-in-bytes>
BOARD_GROUP_FOO_PARTITION_LIST := system vendor product

Những thay đổi của SELinux

Các thiết bị khối siêu phân vùng phải được đánh dấu bằng thuộc tính super_block_device_type . Ví dụ: nếu thiết bị đã có phân vùng systemvendor , bạn muốn sử dụng chúng làm thiết bị khối để lưu trữ phạm vi phân vùng động và các liên kết tượng trưng theo tên của chúng được đánh dấu là system_block_device :

/dev/block/platform/soc/10000\.ufshc/by-name/system   u:object_r:system_block_device:s0
/dev/block/platform/soc/10000\.ufshc/by-name/vendor   u:object_r:system_block_device:s0

Sau đó, thêm dòng sau vào device.te :

typeattribute system_block_device super_block_device_type;

Đối với các cấu hình khác, hãy xem Triển khai phân vùng động trên thiết bị mới .

Để biết thêm thông tin về các bản cập nhật trang bị thêm, hãy xem OTA dành cho Thiết bị A/B không có phân vùng động .

Hình ảnh nhà máy

Để khởi chạy thiết bị có hỗ trợ phân vùng động, hãy tránh sử dụng fastboot vùng người dùng để flash hình ảnh gốc, vì việc khởi động vào không gian người dùng chậm hơn các phương pháp flash khác.

Để giải quyết vấn đề này, make dist hiện xây dựng một hình ảnh super.img bổ sung có thể được flash trực tiếp vào siêu phân vùng. Nó tự động đóng gói nội dung của các phân vùng logic, nghĩa là nó chứa system.img , vendor.img , v.v., ngoài siêu dữ liệu phân vùng super . Hình ảnh này có thể được flash trực tiếp vào super phân vùng mà không cần bất kỳ công cụ bổ sung nào hoặc sử dụng fastbootd. Sau khi xây dựng, super.img được đặt trong ${ANDROID_PRODUCT_OUT} .

Đối với các thiết bị A/B khởi chạy với phân vùng động, super.img chứa hình ảnh trong khe A. Sau khi flash trực tiếp siêu ảnh, hãy đánh dấu khe A là có khả năng khởi động trước khi khởi động lại thiết bị.

Đối với các thiết bị trang bị thêm, make dist xây dựng một tập hợp các hình ảnh super_*.img có thể được flash trực tiếp vào các phân vùng vật lý tương ứng. Ví dụ: make dist super_system.imgsuper_vendor.img khi BOARD_SUPER_PARTITION_BLOCK_DEVICES là nhà cung cấp hệ thống. Những hình ảnh này được đặt trong thư mục OTA ở target_files.zip .

Điều chỉnh thiết bị lưu trữ ánh xạ thiết bị

Phân vùng động chứa một số đối tượng ánh xạ thiết bị không xác định. Tất cả những thứ này có thể không khởi tạo như mong đợi, vì vậy bạn phải theo dõi tất cả các lần gắn kết và cập nhật thuộc tính Android của tất cả các phân vùng được liên kết với các thiết bị lưu trữ cơ bản của chúng.

Một cơ chế bên trong init theo dõi các lần gắn kết và cập nhật không đồng bộ các thuộc tính Android. Khoảng thời gian này không được đảm bảo nằm trong một khoảng thời gian cụ thể, vì vậy bạn phải cung cấp đủ thời gian để tất cả các trình kích hoạt thuộc on property phản ứng. Các thuộc tính là dev.mnt.blk. <partition> trong đó <partition>root , system , data hoặc vendor chẳng hạn. Mỗi thuộc tính được liên kết với tên thiết bị lưu trữ cơ sở, như trong các ví dụ sau:

taimen:/ % getprop | grep dev.mnt.blk
[dev.mnt.blk.data]: [sda]
[dev.mnt.blk.firmware]: [sde]
[dev.mnt.blk.metadata]: [sde]
[dev.mnt.blk.persist]: [sda]
[dev.mnt.blk.root]: [dm-0]
[dev.mnt.blk.vendor]: [dm-1]

blueline:/ $ getprop | grep dev.mnt.blk
[dev.mnt.blk.data]: [dm-4]
[dev.mnt.blk.metadata]: [sda]
[dev.mnt.blk.mnt.scratch]: [sda]
[dev.mnt.blk.mnt.vendor.persist]: [sdf]
[dev.mnt.blk.product]: [dm-2]
[dev.mnt.blk.root]: [dm-0]
[dev.mnt.blk.system_ext]: [dm-3]
[dev.mnt.blk.vendor]: [dm-1]
[dev.mnt.blk.vendor.firmware_mnt]: [sda]

Ngôn ngữ init.rc cho phép mở rộng các thuộc tính Android như một phần của quy tắc và nền tảng có thể điều chỉnh các thiết bị lưu trữ khi cần bằng các lệnh như sau:

write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb 128
write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb 128

Khi quá trình xử lý lệnh bắt đầu ở giai đoạn thứ hai init , epoll loop sẽ hoạt động và các giá trị bắt đầu cập nhật. Tuy nhiên, vì trình kích hoạt thuộc tính không hoạt động cho đến khi init muộn nên chúng không thể được sử dụng trong giai đoạn khởi động ban đầu để xử lý root , system hoặc vendor . Bạn có thể mong đợi read_ahead_kb mặc định của kernel là đủ cho đến khi các tập lệnh init.rc có thể ghi đè vào early-fs (khi các daemon và tiện ích khác nhau bắt đầu). Do đó, Google khuyên bạn nên sử dụng tính năng on property , kết hợp với thuộc tính được kiểm soát init.rc như sys.read_ahead_kb , để xử lý việc tính thời gian cho các hoạt động và ngăn chặn các điều kiện tương tranh, như trong các ví dụ sau:

on property:dev.mnt.blk.root=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.system=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.system}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.vendor=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.vendor}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.product=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.system_ext}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.oem=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.oem}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on property:dev.mnt.blk.data=* && property:sys.read_ahead_kb=*
    write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048}

on early-fs:
    setprop sys.read_ahead_kb ${ro.read_ahead_kb.boot:-2048}

on property:sys.boot_completed=1
   setprop sys.read_ahead_kb ${ro.read_ahead_kb.bootcomplete:-128}