การแบ่งพาร์ติชันแบบไดนามิกจะใช้โมดูล dm-linear device-mapper
ในเคอร์เนล Linux พาร์ติชัน super มี
ข้อมูลเมตาที่แสดงชื่อและช่วงบล็อกของแต่ละพาร์ติชันแบบไดนามิก
ภายใน super ในระหว่างinitระยะแรก
ระบบจะแยกวิเคราะห์และตรวจสอบข้อมูลเมตานี้ และสร้างอุปกรณ์บล็อกเสมือนเพื่อ
แสดงถึงแต่ละพาร์ติชันแบบไดนามิก
เมื่อใช้ OTA ระบบจะสร้าง ปรับขนาด หรือลบพาร์ติชันแบบไดนามิกโดยอัตโนมัติตามความจำเป็น สำหรับอุปกรณ์ A/B จะมีข้อมูลเมตา 2 ชุด และการเปลี่ยนแปลงจะมีผลเฉพาะกับชุดที่แสดงถึง สล็อตเป้าหมาย
เนื่องจากมีการติดตั้งใช้งานพาร์ติชันแบบไดนามิกในพื้นที่ผู้ใช้ จึงไม่สามารถสร้างพาร์ติชันที่จำเป็น
สำหรับโปรแกรมโหลดระบบให้เป็นแบบไดนามิกได้ เช่น boot,
dtbo และ vbmeta จะอ่านโดย Bootloader และ
จึงต้องคงไว้เป็นพาร์ติชันจริง
พาร์ติชันแบบไดนามิกแต่ละรายการจะอยู่ในกลุ่มการอัปเดตได้ กลุ่มเหล่านี้
จะจำกัดพื้นที่สูงสุดที่พาร์ติชันในกลุ่มนั้นใช้ได้
เช่น system และ vendor อาจอยู่ในกลุ่มที่จำกัดขนาดรวมของ system และ vendor
ใช้พาร์ติชันแบบไดนามิกในอุปกรณ์ใหม่
ส่วนนี้จะอธิบายรายละเอียดวิธีใช้พาร์ติชันแบบไดนามิกในอุปกรณ์ใหม่ ที่เปิดตัวพร้อม Android 10 ขึ้นไป หากต้องการอัปเดต อุปกรณ์ที่มีอยู่ โปรดดูการอัปเกรดอุปกรณ์ Android
การเปลี่ยนแปลงพาร์ติชัน
สำหรับอุปกรณ์ที่เปิดตัวด้วย Android 10 ให้สร้าง
พาร์ติชันชื่อ super พาร์ติชัน super
จะจัดการสล็อต A/B ภายใน ดังนั้นอุปกรณ์ A/B จึงไม่จำเป็นต้องมีพาร์ติชัน super_a และ super_b แยกกัน
พาร์ติชัน AOSP แบบอ่านอย่างเดียวทั้งหมดที่ไม่ได้ใช้โดย Bootloader ต้อง
เป็นแบบไดนามิกและต้องนำออกจากตารางพาร์ติชัน GUID (GPT)
พาร์ติชันเฉพาะผู้ให้บริการไม่จำเป็นต้องเป็นแบบไดนามิกและอาจอยู่ใน GPT
หากต้องการประมาณขนาดของ super ให้เพิ่มขนาดของ
พาร์ติชันที่จะลบออกจาก GPT สำหรับอุปกรณ์ A/B
ควรระบุขนาดของทั้ง 2 สล็อต รูปที่ 1 แสดง
ตัวอย่างตารางพาร์ติชันก่อนและหลังการแปลงเป็นพาร์ติชันแบบไดนามิก
พาร์ติชันแบบไดนามิกที่รองรับมีดังนี้
- ระบบ
- ตัวแทนจำหน่ายรายย่อย
- ผลิตภัณฑ์
- System Ext
- ODM
สำหรับอุปกรณ์ที่เปิดตัวด้วย Android 10 ตัวเลือกบรรทัดคำสั่งของเคอร์เนล
androidboot.super_partition
ต้องว่างเปล่าเพื่อให้ sysprop คำสั่ง
ro.boot.super_partition ว่างเปล่า
การจัดแนวพาร์ติชัน
โมดูล Device-Mapper อาจทำงานได้ไม่เต็มประสิทธิภาพหากsuperพาร์ติชันไม่ได้รับการจัดแนวอย่างถูกต้อง super พาร์ติชันต้องสอดคล้องกับขนาดคำขอ I/O ขั้นต่ำตามที่กำหนดโดยเลเยอร์บล็อก โดยค่าเริ่มต้น ระบบบิลด์ (ผ่าน lpmake ซึ่งสร้างอิมเมจพาร์ติชัน super) จะถือว่าการจัดแนว 1 MiB เพียงพอสำหรับพาร์ติชันแบบไดนามิกทุกพาร์ติชัน อย่างไรก็ตาม ผู้ให้บริการควร
ตรวจสอบว่าsuperพาร์ติชันได้รับการจัดแนวอย่างถูกต้อง
คุณกำหนดขนาดคำขอขั้นต่ำของอุปกรณ์บล็อกได้โดย
ตรวจสอบ sysfs เช่น
# 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
คุณสามารถตรวจสอบการจัดแนวของsuperพาร์ติชันในลักษณะที่คล้ายกันได้โดยทำดังนี้
# cat /sys/block/sda/sda17/alignment_offsetออฟเซ็ตการจัดแนวต้องเป็น 0
การเปลี่ยนแปลงการกำหนดค่าอุปกรณ์
หากต้องการเปิดใช้การแบ่งพาร์ติชันแบบไดนามิก ให้เพิ่ม Flag ต่อไปนี้ใน
device.mk
PRODUCT_USE_DYNAMIC_PARTITIONS := true
การเปลี่ยนแปลงการกำหนดค่ากระดาน
คุณต้องตั้งค่าขนาดของพาร์ติชัน super ดังนี้
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>
ในอุปกรณ์ A/B ระบบบิลด์จะแสดงข้อผิดพลาดหากขนาดรวม
ของอิมเมจพาร์ติชันแบบไดนามิกมีขนาดมากกว่าครึ่งหนึ่งของsuper
ขนาดพาร์ติชัน
คุณกำหนดค่ารายการพาร์ติชันแบบไดนามิกได้ดังนี้ สำหรับ
อุปกรณ์ที่ใช้กลุ่มอัปเดต ให้แสดงรายการกลุ่มในตัวแปร BOARD_SUPER_PARTITION_GROUPS ชื่อกลุ่มแต่ละชื่อ
จะมีตัวแปร BOARD_group_SIZE
และ BOARD_group_PARTITION_LIST
สำหรับอุปกรณ์ A/B ขนาดสูงสุดของกลุ่มควรครอบคลุมเพียงช่องเดียว เนื่องจากชื่อกลุ่มจะต่อท้ายด้วยช่องภายใน
ต่อไปนี้คือตัวอย่างอุปกรณ์ที่จัดพาร์ติชันทั้งหมดไว้ในกลุ่ม
ชื่อ 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
ตัวอย่างอุปกรณ์ที่จัดวางบริการของระบบและผลิตภัณฑ์ไว้ใน
group_foo และ vendor, product
และ odm ไว้ใน 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
-
สำหรับอุปกรณ์ที่เปิดตัวด้วยการทดสอบ A/B เสมือน ผลรวมของขนาดสูงสุดของทุกกลุ่มต้องไม่เกิน
BOARD_SUPER_PARTITION_SIZE- ค่าใช้จ่าย
ดูการติดตั้งใช้งานการทดสอบ A/B เสมือน
-
สำหรับอุปกรณ์ที่เปิดตัวด้วยการทดสอบ A/B ผลรวมของขนาดสูงสุดของทุกกลุ่มต้องเป็น
BOARD_SUPER_PARTITION_SIZE/ 2 - ค่าใช้จ่ายเพิ่มเติม -
สำหรับอุปกรณ์ที่ไม่ใช่ A/B และอุปกรณ์ A/B ที่ดัดแปลงใหม่ ผลรวมของขนาดสูงสุด
ของทุกกลุ่มต้องเป็น
BOARD_SUPER_PARTITION_SIZE- ค่าใช้จ่าย - ในเวลาสร้าง ผลรวมของขนาดรูปภาพของแต่ละพาร์ติชัน ในกลุ่มการอัปเดตต้องไม่เกินขนาดสูงสุดของกลุ่ม
- ค่าใช้จ่ายจำเป็นต้องใช้ในการคำนวณเพื่อพิจารณาข้อมูลเมตา การจัดแนว และอื่นๆ ค่าใช้จ่ายที่เหมาะสมคือ 4 MiB แต่คุณ สามารถเลือกค่าใช้จ่ายที่สูงกว่านี้ได้ตามที่อุปกรณ์ต้องการ
ปรับขนาดพาร์ติชันแบบไดนามิก
ก่อนที่จะมีพาร์ติชันแบบไดนามิก ระบบจะจัดสรรขนาดพาร์ติชันมากเกินไปเพื่อ ให้มั่นใจว่ามีพื้นที่เพียงพอสำหรับการอัปเดตในอนาคต ระบบจะใช้ขนาดจริง และพาร์ติชันแบบอ่านอย่างเดียวส่วนใหญ่มีพื้นที่ว่าง ในระบบไฟล์ ในพาร์ติชันแบบไดนามิก พื้นที่ว่างดังกล่าวจะ ใช้ไม่ได้และอาจใช้เพื่อขยายพาร์ติชันในระหว่าง OTA คุณต้องตรวจสอบว่าพาร์ติชันไม่ได้ใช้พื้นที่อย่างสิ้นเปลืองและ ได้รับการจัดสรรให้มีขนาดเล็กที่สุดเท่าที่จะเป็นไปได้
สำหรับอิมเมจ ext4 แบบอ่านอย่างเดียว ระบบบิลด์จะจัดสรร ขนาดขั้นต่ำโดยอัตโนมัติหากไม่ได้ระบุขนาดพาร์ติชันที่ฮาร์ดโค้ดไว้ ระบบบิลด์จะปรับรูปภาพเพื่อให้ระบบไฟล์มีพื้นที่ ที่ไม่ได้ใช้ให้น้อยที่สุด ซึ่งจะช่วยให้มั่นใจได้ว่าอุปกรณ์จะไม่ใช้พื้นที่ ที่ใช้สำหรับ OTA ได้
นอกจากนี้ คุณยังบีบอัดรูปภาพ ext4 เพิ่มเติมได้โดยการเปิดใช้การขจัดข้อมูลที่ซ้ำกันระดับบล็อก- หากต้องการเปิดใช้ ให้ใช้การกำหนดค่าต่อไปนี้
BOARD_EXT4_SHARE_DUP_BLOCKS := true
หากไม่ต้องการให้ระบบจัดสรรขนาดขั้นต่ำของการแบ่งพาร์ติชันโดยอัตโนมัติ
คุณควบคุมขนาดพาร์ติชันได้ 2 วิธี คุณระบุ
จำนวนพื้นที่ว่างขั้นต่ำได้ด้วย
BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE
หรือจะระบุ
BOARD_partitionIMAGE_PARTITION_SIZE เพื่อบังคับให้
พาร์ติชันแบบไดนามิกมีขนาดที่เฉพาะเจาะจงก็ได้ เราไม่แนะนำให้ใช้ทั้ง 2 วิธีนี้
เว้นแต่จำเป็น
เช่น
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
ซึ่งจะบังคับให้ระบบไฟล์ใน product.img มีพื้นที่ว่าง
50 MiB
การเปลี่ยนแปลงระบบเป็นรูท
อุปกรณ์ที่เปิดตัวพร้อม Android 10 ต้องไม่ ใช้ระบบเป็นรูท
อุปกรณ์ที่มีพาร์ติชันแบบไดนามิก (ไม่ว่าจะเปิดตัวหรือติดตั้งพาร์ติชันแบบไดนามิกย้อนหลัง
) ต้องไม่ใช้ระบบเป็นรูท เคอร์เนล Linux ไม่สามารถ
ตีความพาร์ติชัน super จึงไม่สามารถเมานต์
system ได้ ตอนนี้ system ติดตั้งโดย
init ระยะแรกซึ่งอยู่ใน Ramdisk
อย่าตั้งค่า BOARD_BUILD_SYSTEM_ROOT_IMAGE ใน Android 10 BOARD_BUILD_SYSTEM_ROOT_IMAGE จะใช้เพื่อแยกความแตกต่างว่าระบบได้รับการติดตั้งโดยเคอร์เนลหรือโดย init ในระยะแรกใน Ramdisk
การตั้งค่า BOARD_BUILD_SYSTEM_ROOT_IMAGE เป็น true
จะทำให้เกิดข้อผิดพลาดในการบิลด์เมื่อ
PRODUCT_USE_DYNAMIC_PARTITIONS เป็น true ด้วย
เมื่อตั้งค่า BOARD_USES_RECOVERY_AS_BOOT เป็น "จริง" ระบบจะสร้างอิมเมจการกู้คืนเป็น boot.img ซึ่งมี ramdisk ของการกู้คืน ก่อนหน้านี้ Bootloader ใช้พารามิเตอร์บรรทัดคำสั่ง skip_initramfs Kernel
เพื่อตัดสินใจว่าจะบูตเข้าสู่โหมดใด สำหรับ
อุปกรณ์ Android 10, Bootloader ต้องไม่ส่ง
skip_initramfs ไปยังบรรทัดคำสั่งของเคอร์เนล แต่ Bootloader
ควรส่ง androidboot.force_normal_boot=1 เพื่อข้ามการกู้คืน
และบูต Android ปกติ อุปกรณ์ที่เปิดตัวด้วย Android 12
ขึ้นไปต้องใช้ bootconfig เพื่อส่งผ่าน androidboot.force_normal_boot=1
การเปลี่ยนแปลงการกำหนดค่า AVB
เมื่อใช้ Android Verified Boot 2.0 หากอุปกรณ์ไม่ได้ใช้ตัวอธิบายพาร์ติชันที่เชื่อมโยงกัน ก็ไม่จำเป็นต้องเปลี่ยนแปลงอะไร อย่างไรก็ตาม หากใช้พาร์ติชันที่เชื่อมโยงกันและพาร์ติชันที่ยืนยันแล้วรายการใดรายการหนึ่งเป็นแบบไดนามิก คุณจะต้องทำการเปลี่ยนแปลง
ต่อไปนี้คือตัวอย่างการกำหนดค่าสำหรับอุปกรณ์ที่เชื่อมโยง
vbmeta สำหรับพาร์ติชัน system และ
vendor
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
การกำหนดค่านี้ทำให้ Bootloader คาดหวังที่จะเห็นส่วนท้าย vbmetaที่ส่วนท้ายของพาร์ติชัน system และ
vendor เนื่องจากพาร์ติชันเหล่านี้จะไม่ปรากฏต่อ Bootloader อีกต่อไป (พาร์ติชันจะอยู่ใน super) จึงต้องมีการเปลี่ยนแปลง 2 อย่าง
-
เพิ่มพาร์ติชัน
vbmeta_systemและvbmeta_vendorลงในตารางพาร์ติชันของอุปกรณ์ สําหรับอุปกรณ์ A/B ให้เพิ่มvbmeta_system_a,vbmeta_system_bvbmeta_vendor_aและvbmeta_vendor_bหาก เพิ่มพาร์ติชันเหล่านี้อย่างน้อย 1 รายการ พาร์ติชันดังกล่าวควรมีขนาดเท่ากับ พาร์ติชันvbmeta -
เปลี่ยนชื่อแฟล็กการกำหนดค่าโดยเพิ่ม
VBMETA_และ ระบุพาร์ติชันที่การเชื่อมโยงขยายไปถึง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
อุปกรณ์อาจใช้พาร์ติชันเหล่านี้อย่างใดอย่างหนึ่ง ทั้ง 2 อย่าง หรือไม่ใช้เลยก็ได้ การเปลี่ยนแปลง จำเป็นเมื่อเชื่อมโยงกับพาร์ติชันเชิงตรรกะเท่านั้น
การเปลี่ยนแปลง Bootloader ของ AVB
หาก Bootloader มี libavb แบบฝัง ให้รวมแพตช์ต่อไปนี้
- 818cf56740775446285466eda984acedd4baeac0 — "libavb: Only query partition GUIDs when the cmdline needs them."
- 5abd6bc2578968d24406d834471adfd995a0c2e9 — "Allow system partition to be absent"
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 — "แก้ไข AvbSlotVerifyData->cmdline อาจเป็น NULL"
หากใช้พาร์ติชันที่เชื่อมโยง ให้รวมแพตช์เพิ่มเติมดังนี้
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: Support vbmeta blobs in beginning of partition."
การเปลี่ยนแปลงบรรทัดคำสั่งของเคอร์เนล
ต้องเพิ่มพารามิเตอร์ใหม่ androidboot.boot_devices
ลงในบรรทัดคำสั่งของเคอร์เนล init ใช้ตัวแปรนี้เพื่อ
เปิดใช้ลิงก์สัญลักษณ์ /dev/block/by-name โดยควรเป็น
คอมโพเนนต์เส้นทางของอุปกรณ์ไปยัง Symlink ที่มีชื่อพื้นฐานซึ่งสร้างโดย
ueventd นั่นคือ
/dev/block/platform/device-path/by-name/partition-name
อุปกรณ์ที่เปิดตัวด้วย Android 12 ขึ้นไปต้องใช้
bootconfig เพื่อส่ง androidboot.boot_devices ไปยัง init
ตัวอย่างเช่น หากซิมลิงก์แบบมีชื่อของพาร์ติชัน Super คือ
/dev/block/platform/soc/100000.ufshc/by-name/super,
คุณจะเพิ่มพารามิเตอร์บรรทัดคำสั่งในไฟล์ BoardConfig.mk ได้ดังนี้
BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc
การเปลี่ยนแปลง fstab
Device Tree และ Device Tree Overlay ต้องไม่มีรายการ fstab ใช้ไฟล์ fstab ที่จะเป็นส่วนหนึ่งของ ramdisk
ต้องทำการเปลี่ยนแปลงไฟล์ fstab สำหรับพาร์ติชันแบบตรรกะดังนี้
-
ฟิลด์แฟล็ก fs_mgr ต้องมีแฟล็ก
logicalและแฟล็กfirst_stage_mountซึ่งเปิดตัวใน Android 10 ซึ่งระบุว่าพาร์ติชันจะ ต้องติดตั้งในระยะแรก -
พาร์ติชันอาจระบุ
avb=vbmeta partition nameเป็นแฟล็กfs_mgrจากนั้นพาร์ติชันvbmetaที่ระบุ จะได้รับการเริ่มต้นโดยinitในระยะแรกก่อน พยายามติดตั้งอุปกรณ์ใดๆ -
ฟิลด์
devต้องเป็นชื่อพาร์ติชัน
รายการ fstab ต่อไปนี้จะตั้งค่า system, vendor และ product เป็นพาร์ติชันเชิงตรรกะ ตามกฎข้างต้น
#<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
คัดลอกไฟล์ fstab ไปยัง ramdisk ในระยะแรก
การเปลี่ยนแปลง SELinux
ต้องทำเครื่องหมายอุปกรณ์บล็อกพาร์ติชันขั้นสูงด้วยป้ายกำกับ
super_block_device ตัวอย่างเช่น หากซิมลิงก์การแบ่งพาร์ติชันขั้นสูงตามชื่อคือ
/dev/block/platform/soc/100000.ufshc/by-name/super,
ให้เพิ่มบรรทัดต่อไปนี้ลงใน file_contexts
/dev/block/platform/soc/10000\.ufshc/by-name/super u:object_r:super_block_device:s0
fastbootd
Bootloader (หรือเครื่องมือแฟลชที่ไม่ใช่พื้นที่ผู้ใช้) ไม่เข้าใจ พาร์ติชันแบบไดนามิก จึงแฟลชพาร์ติชันเหล่านั้นไม่ได้ เพื่อแก้ไขปัญหานี้ อุปกรณ์ ต้องใช้การติดตั้งใช้งานโปรโตคอล fastboot ในพื้นที่ผู้ใช้ ซึ่งเรียกว่า fastbootd
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้งาน fastbootd ได้ที่ย้าย Fastboot ไปยังพื้นที่ผู้ใช้
adb remount
สำหรับนักพัฒนาแอปที่ใช้บิลด์ eng หรือ userdebug adb remount
มีประโยชน์อย่างยิ่งสำหรับการทำซ้ำอย่างรวดเร็ว พาร์ติชันแบบไดนามิกทำให้เกิดปัญหาสำหรับ adb remount เนื่องจากไม่มีพื้นที่ว่าง
ภายในระบบไฟล์แต่ละระบบอีกต่อไป อุปกรณ์สามารถเปิดใช้
overlayfs เพื่อแก้ไขปัญหานี้ได้ ตราบใดที่ยังมีพื้นที่ว่างภายในพาร์ติชันหลัก
adb remount จะสร้างพาร์ติชันแบบไดนามิกชั่วคราวโดยอัตโนมัติ
และใช้ overlayfs สำหรับการเขียน พาร์ติชันชั่วคราวมีชื่อว่า scratch ดังนั้นอย่าใช้ชื่อนี้กับพาร์ติชันอื่นๆ
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีเปิดใช้ overlayfs ได้ที่ overlayfs README ใน AOSP
อัปเกรดอุปกรณ์ Android
หากอัปเกรดอุปกรณ์เป็น Android 10 และต้องการรวมการรองรับพาร์ติชันแบบไดนามิกไว้ใน OTA คุณไม่จำเป็นต้องเปลี่ยนตารางพาร์ติชันในตัว คุณต้องกำหนดค่าเพิ่มเติม
การเปลี่ยนแปลงการกำหนดค่าอุปกรณ์
หากต้องการติดตั้งการแบ่งพาร์ติชันแบบไดนามิกย้อนหลัง ให้เพิ่มแฟล็กต่อไปนี้ใน
device.mk
PRODUCT_USE_DYNAMIC_PARTITIONS := true PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true
การเปลี่ยนแปลงการกำหนดค่ากระดาน
คุณต้องตั้งค่าตัวแปรบอร์ดต่อไปนี้
- ตั้งค่า
BOARD_SUPER_PARTITION_BLOCK_DEVICESเป็นรายการอุปกรณ์ที่บล็อกซึ่งใช้ เพื่อจัดเก็บขอบเขตของพาร์ติชันแบบไดนามิก นี่คือรายการชื่อของพาร์ติชันจริงที่มีอยู่ ในอุปกรณ์ - ตั้งค่า
BOARD_SUPER_PARTITION_partition_DEVICE_SIZEเป็นขนาด ของอุปกรณ์บล็อกแต่ละรายการในBOARD_SUPER_PARTITION_BLOCK_DEVICESตามลำดับ นี่คือรายการขนาดของพาร์ติชันจริงที่มีอยู่ในอุปกรณ์ โดยปกติแล้วBOARD_partitionIMAGE_PARTITION_SIZEจะอยู่ในบอร์ดที่มีอยู่ การกำหนดค่า - ยกเลิกการตั้งค่า
BOARD_partitionIMAGE_PARTITION_SIZEที่มีอยู่สำหรับพาร์ติชันทั้งหมดในBOARD_SUPER_PARTITION_BLOCK_DEVICES - ตั้งค่า
BOARD_SUPER_PARTITION_SIZEเป็นผลรวมของBOARD_SUPER_PARTITION_partition_DEVICE_SIZE - ตั้งค่า
BOARD_SUPER_PARTITION_METADATA_DEVICEเป็นอุปกรณ์ที่บล็อกซึ่ง จัดเก็บข้อมูลเมตาของพาร์ติชันแบบไดนามิก โดยต้องเป็นหนึ่งในBOARD_SUPER_PARTITION_BLOCK_DEVICESโดยปกติแล้ว ค่านี้จะตั้งเป็นsystem - ตั้งค่า
BOARD_SUPER_PARTITION_GROUPS,BOARD_group_SIZEและBOARD_group_PARTITION_LISTตามลำดับ ดูรายละเอียดได้ที่ การเปลี่ยนแปลงการกำหนดค่าบอร์ดในอุปกรณ์ใหม่
เช่น หากอุปกรณ์มีพาร์ติชันระบบและพาร์ติชันของผู้ให้บริการอยู่แล้ว และคุณต้องการแปลง พาร์ติชันเหล่านั้นเป็นพาร์ติชันแบบไดนามิกและเพิ่มพาร์ติชันผลิตภัณฑ์ใหม่ระหว่างการอัปเดต ให้ตั้งค่าบอร์ดดังนี้
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
การเปลี่ยนแปลง SELinux
อุปกรณ์บล็อกพาร์ติชันขั้นสูงต้องมีแอตทริบิวต์
super_block_device_type เช่น หากอุปกรณ์มีพาร์ติชัน system และ vendor อยู่แล้ว คุณต้องการใช้พาร์ติชันเหล่านั้นเป็นอุปกรณ์บล็อกเพื่อจัดเก็บขอบเขตของพาร์ติชันแบบไดนามิก และระบบจะทำเครื่องหมายลิงก์แบบสัญลักษณ์ตามชื่อเป็น 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
จากนั้นเพิ่มบรรทัดต่อไปนี้ใน device.te
typeattribute system_block_device super_block_device_type;
สำหรับการกำหนดค่าอื่นๆ โปรดดูการใช้ พาร์ติชันแบบไดนามิกในอุปกรณ์ใหม่
ดูข้อมูลเพิ่มเติมเกี่ยวกับการอัปเดตแบบติดตั้งเพิ่มเติมได้ที่ OTA สำหรับอุปกรณ์ A/B ที่ไม่มีพาร์ติชันแบบไดนามิก
อิมเมจจากโรงงาน
สำหรับอุปกรณ์ที่เปิดตัวพร้อมรองรับพาร์ติชันแบบไดนามิก ให้หลีกเลี่ยงการใช้ fastboot ใน Userspace เพื่อแฟลชอิมเมจจากโรงงาน เนื่องจาก การบูตไปยัง Userspace จะช้ากว่าวิธีการแฟลชอื่นๆ
make dist จึงสร้างsuper.imgรูปภาพเพิ่มเติมที่แฟลชไปยังพาร์ติชัน super ได้โดยตรง โดยจะจัดกลุ่มเนื้อหาของพาร์ติชันเชิงตรรกะโดยอัตโนมัติ ซึ่งหมายความว่าจะมี system.img, vendor.img และอื่นๆ นอกเหนือจากข้อมูลเมตาของพาร์ติชัน super คุณแฟลชรูปภาพนี้ไปยังพาร์ติชัน super ได้โดยตรงโดยไม่ต้องใช้เครื่องมือเพิ่มเติมหรือใช้
fastbootd หลังจากสร้างแล้ว ระบบจะวาง super.img ไว้ใน
${ANDROID_PRODUCT_OUT}
สำหรับอุปกรณ์ A/B ที่เปิดตัวพร้อมพาร์ติชันแบบไดนามิก
super.img มีอิมเมจในช่อง A หลังจากแฟลช
อิมเมจ super โดยตรงแล้ว ให้ทำเครื่องหมายช่อง A เป็นช่องที่บูตได้ก่อนรีบูต
อุปกรณ์
สำหรับอุปกรณ์ที่ดัดแปลง make dist จะสร้างชุด
super_*.img อิมเมจที่แฟลชไปยัง
พาร์ติชันจริงที่เกี่ยวข้องได้โดยตรง ตัวอย่างเช่น make dist
สร้าง super_system.img และ super_vendor.img
เมื่อ BOARD_SUPER_PARTITION_BLOCK_DEVICES เป็นผู้จำหน่าย
ระบบ ระบบจะวางรูปภาพเหล่านี้ไว้ในโฟลเดอร์ OTA ใน
target_files.zip
การปรับแต่งอุปกรณ์จัดเก็บข้อมูล Device Mapper
การแบ่งพาร์ติชันแบบไดนามิกรองรับออบเจ็กต์ device-mapper แบบไม่กำหนดจำนวน ซึ่งอาจไม่ได้สร้างอินสแตนซ์ทั้งหมดตามที่คาดไว้ ดังนั้นคุณต้องติดตามการติดตั้งทั้งหมด และอัปเดตพร็อพเพอร์ตี้ Android ของพาร์ติชันที่เชื่อมโยงทั้งหมดด้วยอุปกรณ์จัดเก็บข้อมูลที่อยู่เบื้องหลัง
กลไกภายใน init จะติดตามการติดตั้งและอัปเดตพร็อพเพอร์ตี้ Android แบบไม่พร้อมกัน
เราไม่รับประกันว่าระยะเวลาที่ใช้จะอยู่ภายในระยะเวลาที่เฉพาะเจาะจง ดังนั้นคุณต้องให้เวลาเพียงพอเพื่อให้on propertyทริกเกอร์ทั้งหมดตอบสนอง พร็อพเพอร์ตี้คือ
dev.mnt.blk.<partition> โดยที่
<partition> คือ root,
system, data หรือ
vendor เช่น แต่ละพร็อพเพอร์ตี้จะเชื่อมโยงกับ
ชื่ออุปกรณ์จัดเก็บข้อมูลพื้นฐาน ดังที่แสดงในตัวอย่างต่อไปนี้
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]
init.rc ภาษาช่วยให้ขยายพร็อพเพอร์ตี้ Android ได้
ซึ่งเป็นส่วนหนึ่งของกฎ และแพลตฟอร์มสามารถปรับแต่งอุปกรณ์จัดเก็บข้อมูลได้
ตามต้องการด้วยคำสั่งต่อไปนี้
write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb 128 write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb 128
เมื่อการประมวลผลคำสั่งเริ่มขึ้นในinitระยะที่ 2
epoll loop จะใช้งานได้ และค่าจะเริ่มอัปเดต อย่างไรก็ตาม เนื่องจากทริกเกอร์ของพร็อพเพอร์ตี้จะยังไม่ทำงานจนกว่าจะถึงช่วงปลายinit จึงไม่สามารถใช้ในขั้นตอนการบูตเริ่มต้นเพื่อจัดการ root, system หรือ vendor ได้ คุณอาจคาดหวังว่าread_ahead_kbเริ่มต้นของเคอร์เนลจะเพียงพอจนกว่าสคริปต์ init.rc จะลบล้างได้ใน early-fs (เมื่อเริ่มใช้ Daemon และสิ่งอำนวยความสะดวกต่างๆ) ดังนั้น Google ขอแนะนําให้คุณใช้ฟีเจอร์ on property ร่วมกับพร็อพเพอร์ตี้ที่ควบคุมโดย init.rc เช่น sys.read_ahead_kb เพื่อจัดการกับการกำหนดเวลาการดำเนินการและป้องกันสภาวะแข่งขัน ดังตัวอย่างต่อไปนี้
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}