Android 10 รองรับพาร์ติชันแบบไดนามิก ซึ่งเป็นระบบการแบ่งพาร์ติชันในพื้นที่ผู้ใช้ ที่สร้าง ปรับขนาด และทำลายพาร์ติชันได้ในระหว่างการอัปเดตผ่านอากาศ (OTA)
หน้านี้อธิบายวิธีที่ไคลเอ็นต์ OTA ปรับขนาดพาร์ติชันแบบไดนามิกระหว่างการอัปเดตสำหรับอุปกรณ์ที่ไม่ใช่ A/B
สำหรับอุปกรณ์ที่ไม่ใช่ A/B ระบบจะใช้การอัปเดต OTA สำหรับพาร์ติชันแบบไดนามิก
โดยใช้ updater ภายในแพ็กเกจการอัปเดต
อัปเดตอุปกรณ์ที่จะเปิดตัว
ส่วนนี้ใช้กับอุปกรณ์ที่ไม่ใช่ A/B ที่เปิดตัวพร้อมการรองรับพาร์ติชันแบบไดนามิก อุปกรณ์เหล่านี้จะอัปเกรดจาก Android 10 เป็นรุ่นที่สูงกว่า
สร้างแพ็กเกจอัปเดต
แพ็กเกจการอัปเดต OTA สร้างขึ้นโดย
ota_from_target_files สคริปต์ที่อยู่ใน
build/make/tools/releasetools โดยค่าเริ่มต้น สคริปต์
จะสร้างแพ็กเกจที่อัปเดตพาร์ติชัน system และ
vendor หากมีพาร์ติชันแบบไดนามิกเพิ่มเติม เช่น product
product_services หรือ odm
ต้องสร้างการอัปเดตในโค้ดเฉพาะอุปกรณ์
หากต้องการสร้างข้อมูลอัปเดต ให้ใช้
FullOTA_GetBlockDifferences() และ
IncrementalOTA_GetBlockDifferences() ในโมดูล Python แบบขยาย ฟังก์ชันทั้ง 2 รายการนี้
จะแสดงรายการออบเจ็กต์ BlockDifference
ซึ่งแต่ละรายการจะอธิบายแพตช์การอัปเดตที่จะใช้กับ
พาร์ติชัน ไม่ควรแก้ไขพาร์ติชันที่ฟังก์ชันทั้ง 2 นี้ส่งคืนด้วยตนเองหรือยืนยันที่อื่น เช่น ใน *_InstallBegin() หรือ *_InstallEnd()
ตัวอย่างการสร้างการอัปเดต
# device/yoyodyne/tardis/releasetools.py import os from common import BlockDifference, EmptyImage, GetUserImage # The joined list of user image partitions of source and target builds. # - Items should be added to the list if new dynamic partitions are added. # - Items should not be removed from the list even if dynamic partitions are # deleted. When generating an incremental OTA package, this script needs to # know that an image is present in source build but not in target build. USERIMAGE_PARTITIONS = [ "product", "odm", ] def GetUserImages(input_tmp, input_zip): return {partition: GetUserImage(partition, input_tmp, input_zip) for partition in USERIMAGE_PARTITIONS if os.path.exists(os.path.join(input_tmp, "IMAGES", partition + ".img"))} def FullOTA_GetBlockDifferences(info): images = GetUserImages(info.input_tmp, info.input_zip) return [BlockDifference(partition, image) for partition, image in images.items()] def IncrementalOTA_GetBlockDifferences(info): source_images = GetUserImages(info.source_tmp, info.source_zip) target_images = GetUserImages(info.target_tmp, info.target_zip) # Use EmptyImage() as a placeholder for partitions that will be deleted. for partition in source_images: target_images.setdefault(partition, EmptyImage()) # Use source_images.get() because new partitions are not in source_images. return [BlockDifference(partition, target_image, source_images.get(partition)) for partition, target_image in target_images.items()]
โฟลว์การอัปเดต
เบื้องหลัง เราได้เพิ่มฟังก์ชันต่อไปนี้ลงในสคริปต์ edify
unmap_partition(name)- ยกเลิกการแมปพาร์ติชันหากมีการแมปไว้ ไม่เช่นนั้นก็ไม่ต้องดำเนินการใดๆ
- แสดงผลสตริง
tเมื่อสำเร็จ หรือสตริงว่างเมื่อไม่สำเร็จ
map_partition(name)- แมปพาร์ติชันหากยังไม่ได้แมป
- แสดงผลเส้นทางแบบสัมบูรณ์ของอุปกรณ์บล็อกที่แมปเมื่อสำเร็จ หรือสตริงว่างเมื่อไม่สำเร็จ
update_dynamic_partitions(op_list)- ใช้รายการการดำเนินการที่ระบุในข้อมูลเมตาของพาร์ติชันแบบไดนามิก ยกเลิกการแมปพาร์ติชันหากจำเป็น
-
แสดงผล
tเมื่อสำเร็จ หรือสตริงว่างเมื่อไม่สำเร็จ
อาร์กิวเมนต์ op_list ของ
update_dynamic_partitions ชี้ไปยังไฟล์ใน
แพ็กเกจการอัปเดต แต่ละบรรทัดในไฟล์จะระบุการดำเนินการ หากการดำเนินการใดล้มเหลว update_dynamic_partitions จะแสดงผลสตริงว่างทันที การดำเนินการมีดังนี้
resize partition-name size- ยกเลิกการแมปพาร์ติชัน แล้วปรับขนาดเป็น size
remove partition_name- ยกเลิกการแมปพาร์ติชัน แล้วนำออก
add partition-name group-name- เพิ่มพาร์ติชันใหม่ลงในกลุ่มที่ระบุ
- ยกเลิกหากไม่มีกลุ่มหรือมีพาร์ติชันอยู่แล้ว
move partition-name group-name- ย้ายพาร์ติชันไปยังกลุ่มที่ระบุ
- ยกเลิกหากไม่มีกลุ่มหรือพาร์ติชัน
-
add_group group-name maximum-size- เพิ่มกลุ่มที่มีชื่อและขนาดสูงสุดที่ระบุ
- ยกเลิกหากมีกลุ่มอยู่แล้ว
- maximum_size 0 หมายความว่าไม่มีการจำกัดขนาด พาร์ติชันในกลุ่ม ต้องมีการทดสอบเพิ่มเติมเพื่อ ตรวจสอบว่าพาร์ติชันในกลุ่มไม่เกิน พื้นที่ว่างในอุปกรณ์
-
resize_group group-name maximum-size- ปรับขนาดกลุ่มให้มีขนาดสูงสุดที่กำหนด
- ยกเลิกหากไม่มีกลุ่ม
- maximum_size 0 หมายความว่าไม่มีการจำกัดขนาด พาร์ติชันในกลุ่ม ต้องมีการทดสอบเพิ่มเติมเพื่อ ตรวจสอบว่าพาร์ติชันในกลุ่มไม่เกิน พื้นที่ว่างในอุปกรณ์
remove_group group-name- นำกลุ่มออก
- ยกเลิกหากมีพาร์ติชันในกลุ่ม
remove_all_groups- ยกเลิกการแมปพาร์ติชันทั้งหมดจาก Device Mapper
- นำพาร์ติชันและกลุ่มทั้งหมดออก
OTA ที่เพิ่มขึ้น
การอัปเดต OTA แบบเพิ่มทีละรายการใช้ตรรกะต่อไปนี้
- ลดขนาดพาร์ติชัน/ลบพาร์ติชัน/ย้ายพาร์ติชันออกจาก กลุ่ม (เพื่อให้มีพื้นที่เพียงพอในการลดขนาดกลุ่ม)
- ลดขนาดกลุ่ม (เพื่อให้มีพื้นที่เพียงพอสำหรับขยายกลุ่ม)
- ขยายกลุ่ม (เพื่อให้มีพื้นที่เพียงพอในการขยาย/เพิ่ม พาร์ติชัน)
- ขยายพาร์ติชัน/เพิ่มพาร์ติชัน/ย้ายพาร์ติชันไปยังกลุ่มใหม่
โดยละเอียดแล้ว update-script จะสร้างขึ้นด้วยตรรกะต่อไปนี้
for each shrinking partition:
block_image_update(map_partition(name), …)
update_dynamic_partitions(op_list)
for each growing / adding partition:
block_image_update(map_partition(name), …)
ระบบจะสร้างไฟล์ op_list สำหรับ
update_dynamic_partitions โดยใช้ตรรกะต่อไปนี้
for each deleting partition:
remove
for each partition that changes groups:
move to "default"
for each shrinking partition:
resize
for each shrinking / removing group:
resize_group / remove_group
for each growing / adding group:
resize_group / add_group
for each adding partition:
add
for each growing / adding partition:
resize
for each partition that changes groups:
move to target groupOTA แบบเต็ม
การอัปเดต OTA แบบเต็มใช้ตรรกะต่อไปนี้
- ลบกลุ่มและพาร์ติชันที่มีอยู่ทั้งหมด
- เพิ่มกลุ่ม
- เพิ่มพาร์ติชัน
โดยละเอียดแล้ว update-script จะสร้างขึ้นด้วยตรรกะต่อไปนี้
update_dynamic_partitions(op_list)
for each adding partition:
block_image_update(map_partition(name), …)
ระบบจะสร้างไฟล์ op_list สำหรับ
update_dynamic_partitions โดยใช้ตรรกะต่อไปนี้
remove_all_groups
for each adding group:
add_group
for each adding partition:
add
for each adding partition:
resize