การแบ่งพาร์ติชันแบบไดนามิกจะใช้โมดูล Device Mapper แบบ dm-linear ในเคอร์เนล Linux พาร์ติชัน super
มีข้อมูลเมตาที่แสดงชื่อและช่วงบล็อกของพาร์ติชันแบบไดนามิกแต่ละพาร์ติชันภายใน super
ในระหว่างระยะที่ 1 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 แบบอ่านอย่างเดียวทั้งหมดที่ไม่ได้ใช้โดยโปรแกรมบูตต้องเป็นแบบไดนามิกและต้องนำออกจากตารางพาร์ติชัน 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 - overhead -
สําหรับอุปกรณ์ที่ไม่ใช่ 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
เพื่อบังคับให้พาร์ติชันแบบไดนามิกมีขนาดใหญ่ที่เจาะจง เราไม่แนะนำให้ใช้ทั้งสองวิธีนี้เว้นแต่จะจำเป็น
เช่น
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
ซึ่งจะบังคับให้ระบบไฟล์ใน product.img
มีพื้นที่ว่างที่ไม่ได้ใช้ 50 MiB
การเปลี่ยนแปลงระบบในฐานะรูท
อุปกรณ์ที่ใช้ Android 10 ต้องไม่ใช้ "รูท" ของระบบ
อุปกรณ์ที่มีพาร์ติชันแบบไดนามิก (ไม่ว่าจะเปิดตัวด้วยหรือติดตั้งพาร์ติชันแบบไดนามิกในภายหลัง) ต้องไม่ใช้ระบบเป็นรูท เคอร์เนลของ Linux ตีความพาร์ติชัน super
ไม่ได้ จึงต่อเชื่อม system
เองไม่ได้ ตอนนี้ system
ได้รับการต่อเชื่อมโดย init
ระยะแรกที่อยู่ในแรมดิสก์
อย่าตั้งค่า BOARD_BUILD_SYSTEM_ROOT_IMAGE
ใน Android 10 จะใช้ Flag BOARD_BUILD_SYSTEM_ROOT_IMAGE
เพื่อแยกแยะว่าระบบได้รับการมาสก์โดยเคอร์เนลหรือโดย init
ระยะที่ 1 ในแรมดิสก์
การตั้งค่า BOARD_BUILD_SYSTEM_ROOT_IMAGE
เป็น true
จะทำให้เกิดข้อผิดพลาดในบิลด์เมื่อ PRODUCT_USE_DYNAMIC_PARTITIONS
คือ true
ด้วย
เมื่อตั้งค่า BOARD_USES_RECOVERY_AS_BOOT
เป็น "จริง" ระบบจะสร้างอิมเมจการกู้คืนเป็น boot.img ซึ่งมี RAMdisk ของการกู้คืน ก่อนหน้านี้ บูตโหลดเดอร์ใช้พารามิเตอร์บรรทัดคำสั่ง skip_initramfs
kernel
เพื่อเลือกโหมดที่จะบูต สำหรับอุปกรณ์ Android 10 บูตโหลดเดอร์ต้องไม่ส่ง skip_initramfs
ไปยังบรรทัดคำสั่งของเคิร์นเนล แต่ควรส่ง 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
เมื่อใช้การกำหนดค่านี้ บูตโหลดเดอร์จะคาดหวังว่าจะพบส่วนท้าย vbmeta ที่ส่วนท้ายของพาร์ติชัน system
และ vendor
เนื่องจาก bootloader มองไม่เห็นพาร์ติชันเหล่านี้อีกต่อไป (พาร์ติชันอยู่ใน super
) จึงต้องมีการทำการเปลี่ยนแปลง 2 อย่าง
-
เพิ่มพาร์ติชัน
vbmeta_system
และvbmeta_vendor
ลงในตารางพาร์ติชันของอุปกรณ์ สําหรับอุปกรณ์ A/B ให้เพิ่มvbmeta_system_a
,vbmeta_system_b
,vbmeta_vendor_a
และvbmeta_vendor_b
หากเพิ่มพาร์ติชันเหล่านี้อย่างน้อย 1 พาร์ติชัน พาร์ติชันควรมีขนาดเดียวกับพาร์ติชันvbmeta
-
เปลี่ยนชื่อ Flag การกําหนดค่าโดยเพิ่ม
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
หากโปรแกรมโหลดบูตฝัง libavb ให้ใส่แพตช์ต่อไปนี้
- 818cf56740775446285466eda984acedd4baeac0 — "libavb: ค้นหาเฉพาะ GUID ของพาร์ติชันเมื่อ cmdline ต้องการ"
- 5abd6bc2578968d24406d834471adfd995a0c2e9 — "Allow system partition to be absent"
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 — "แก้ไข AvbSlotVerifyData->cmdline อาจไม่มีข้อมูล"
หากใช้พาร์ติชันที่เชื่อมโยง ให้ใส่แพตช์เพิ่มเติม ดังนี้
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: รองรับ vbmeta blob ในช่วงต้นของพาร์ติชัน"
การเปลี่ยนแปลงบรรทัดคำสั่งของเคอร์เนล
คุณต้องเพิ่มพารามิเตอร์ใหม่ 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
ตัวอย่างเช่น หากซูเปอร์พาร์ติชันตามชื่อคือ /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
โครงสร้างอุปกรณ์และการวางซ้อนโครงสร้างอุปกรณ์ต้องไม่มีรายการ fstab ใช้ไฟล์ fstab ที่จะเป็นส่วนหนึ่งของ RAM
คุณต้องทําการเปลี่ยนแปลงในไฟล์ fstab สําหรับพาร์ติชันตรรกะ
-
ช่อง Flag ของ fs_mgr ต้องมี Flag
logical
และ Flagfirst_stage_mount
ซึ่งเปิดตัวใน Android 10 ซึ่งบ่งบอกว่าต้องทำการต่อเชื่อมพาร์ติชันในระยะแรก -
พาร์ติชันอาจระบุ
avb=vbmeta partition name
เป็นแฟล็กfs_mgr
จากนั้นพาร์ติชันvbmeta
ที่ระบุจะเริ่มต้นโดยระยะแรกinit
ก่อนที่จะพยายามต่อเชื่อมอุปกรณ์ -
ช่อง
dev
ต้องเป็นชื่อพาร์ติชัน
รายการ fstab ต่อไปนี้ตั้งค่าระบบ ผู้ให้บริการ และผลิตภัณฑ์เป็นพาร์ติชันเชิงตรรกะตามกฎข้างต้น
#<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 ไปยัง RAM disk ระยะที่ 1
การเปลี่ยนแปลง 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
บูตโหลดเดอร์ (หรือเครื่องมือแฟลชที่ไม่ใช่พื้นที่ผู้ใช้) ไม่เข้าใจพาร์ติชันแบบไดนามิก จึงแฟลชพาร์ติชันดังกล่าวไม่ได้ ในการแก้ปัญหานี้ อุปกรณ์ต้องใช้การใช้งานโปรโตคอล fastboot ใน User Space ซึ่งเรียกว่า fastbootd
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้ fastbootd ได้ที่การย้าย Fastboot ไปยังพื้นที่ผู้ใช้
adb remount
สําหรับนักพัฒนาแอปที่ใช้บิลด์ eng หรือ userdebug adb remount
จะมีประโยชน์อย่างยิ่งสำหรับการทำซ้ำอย่างรวดเร็ว พาร์ติชันแบบไดนามิกก่อให้เกิดปัญหาสำหรับ adb remount
เนื่องจากไม่มีพื้นที่ว่างภายในระบบไฟล์แต่ละระบบอีกต่อไป อุปกรณ์สามารถเปิดใช้ overlayfs เพื่อแก้ไขปัญหานี้ได้ ตราบใดที่มีพื้นที่ว่างภายในซูเปอร์พาร์ติชัน adb remount
จะสร้างพาร์ติชันแบบไดนามิกชั่วคราวโดยอัตโนมัติและใช้การวางซ้อนสำหรับการเขียน พาร์ติชันชั่วคราวจะมีชื่อว่า scratch
ดังนั้นอย่าใช้ชื่อนี้กับพาร์ติชันอื่นๆ
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีเปิดใช้ overlayfs ได้ที่ overlayfs README ใน AOSP
อัปเกรดอุปกรณ์ Android
หากอัปเกรดอุปกรณ์เป็น Android 10 และต้องการเพิ่มการรองรับพาร์ติชันแบบไดนามิกใน OTA คุณไม่จําเป็นต้องเปลี่ยนตารางพาร์ติชันในตัว ต้องมีการกําหนดค่าเพิ่มเติมบางอย่าง
การเปลี่ยนแปลงการกำหนดค่าอุปกรณ์
หากต้องการปรับค่าใช้จ่ายในการแบ่งพาร์ติชันแบบไดนามิก ให้เพิ่ม Flag ต่อไปนี้ใน
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 ในพื้นที่ผู้ใช้เพื่อแฟลชอิมเมจโรงงาน เนื่องจากการบูตไปยังพื้นที่ผู้ใช้จะช้ากว่าวิธีการแฟลชอื่นๆ
ในการแก้ปัญหานี้ make dist
จะสร้างsuper.img
เพิ่มเติมที่สามารถแฟลชไปยังพาร์ติชัน Super ได้โดยตรง โดยจะรวมเนื้อหาของพาร์ติชันเชิงตรรกะโดยอัตโนมัติ ซึ่งหมายความว่าจะมี system.img
,
vendor.img
และอื่นๆ นอกเหนือจากข้อมูลเมตาของพาร์ติชัน super
คุณสามารถแฟลชภาพนี้ลงในพาร์ติชัน super
ได้โดยตรงโดยไม่ต้องใช้เครื่องมือเพิ่มเติมหรือใช้ fastbootd หลังจากบิลด์แล้ว super.img
จะอยู่ใน
${ANDROID_PRODUCT_OUT}
สำหรับอุปกรณ์ A/B ที่เปิดด้วยพาร์ติชันแบบไดนามิก super.img
จะมีอิมเมจในช่อง A หลังจากแฟลชซูเปอร์อิมเมจโดยตรงแล้ว ให้ทำเครื่องหมายช่อง A เป็นเปิดเครื่องได้ก่อนเริ่มต้นอุปกรณ์ใหม่
สำหรับอุปกรณ์เพิ่มเติม make dist
จะสร้างชุดอิมเมจ super_*.img
ที่แฟลชไปยังพาร์ติชันจริงที่เกี่ยวข้องได้โดยตรง เช่น make dist
สร้าง super_system.img
และ super_vendor.img
เมื่อ BOARD_SUPER_PARTITION_BLOCK_DEVICES
เป็นผู้ให้บริการระบบ รูปภาพเหล่านี้จะอยู่ในโฟลเดอร์ OTA ใน target_files.zip
การปรับแต่งพื้นที่เก็บข้อมูลของอุปกรณ์แมปเปอร์
การแบ่งพาร์ติชันแบบไดนามิกรองรับออบเจ็กต์ 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
เมื่อการประมวลผลคําสั่งเริ่มขึ้นในระยะที่ 2 init
จะทํางาน และค่าต่างๆ จะเริ่มอัปเดตepoll loop
อย่างไรก็ตาม เนื่องจากทริกเกอร์พร็อพเพอร์ตี้จะไม่ทำงานจนกว่าจะถึงช่วงปลายinit
จึงใช้ไม่ได้ในระยะเริ่มต้นของบูตเพื่อจัดการ root
, system
หรือ vendor
คุณอาจคาดหวังว่าค่าเริ่มต้น read_ahead_kb
ของเคอร์เนลจะเพียงพอจนกว่าสคริปต์ init.rc
จะลบล้างได้ใน early-fs
(เมื่อระบบเริ่มทำงานเดรัม่อนและยูทิลิตีต่างๆ) ดังนั้น 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}