OTA สำหรับอุปกรณ์ A/B ที่ไม่มีพาร์ติชันแบบไดนามิก

Android 10 รองรับพาร์ติชันแบบไดนามิก ซึ่งเป็นระบบการแบ่งพาร์ติชันพื้นที่ผู้ใช้ที่สามารถสร้าง ปรับขนาด และลบพาร์ติชันในระหว่างการอัปเดตผ่านอากาศ (OTA)

หน้านี้จะอธิบายวิธีที่ไคลเอ็นต์ OTA ปรับขนาดพาร์ติชันแบบไดนามิกระหว่างการอัปเดตสำหรับอุปกรณ์ A/B ที่เปิดตัวโดยไม่รองรับพาร์ติชันแบบไดนามิก และวิธีที่ไคลเอ็นต์ OTA อัปเกรดเป็น Android 10

ฉากหลัง

ในระหว่างการอัปเดตอุปกรณ์ A/B เพื่อรองรับพาร์ติชันแบบไดนามิก ระบบจะเก็บตารางพาร์ติชัน GUID (GPT) ในอุปกรณ์ไว้ ดังนั้นจึงไม่มีพาร์ติชัน super ในอุปกรณ์ ระบบจะจัดเก็บข้อมูลเมตาที่ system_a และ system_b แต่คุณปรับแต่งได้โดยการเปลี่ยน BOARD_SUPER_PARTITION_METADATA_DEVICE

อุปกรณ์บล็อกแต่ละเครื่องจะมีช่องข้อมูลเมตา 2 ช่อง ระบบจะใช้เฉพาะช่องข้อมูลเมตาช่องเดียวในอุปกรณ์บล็อกแต่ละเครื่อง เช่น ข้อมูลเมตา 0 ที่ system_a และข้อมูลเมตา 1 ที่ system_b จะสอดคล้องกับพาร์ติชันที่ช่อง A และ B ตามลำดับ รันไทม์จะไม่สนใจว่ามีการอัปเดตสล็อตใด

ในหน้านี้ ช่องข้อมูลเมตาจะเรียกว่า Metadata S (แหล่งที่มา) และ Metadata T (เป้าหมาย) ในทํานองเดียวกัน พาร์ติชันจะเรียกว่า system_s, vendor_t และอื่นๆ

ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่าระบบบิลด์ได้ที่หัวข้อการอัปเกรดอุปกรณ์

ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีที่พาร์ติชันเป็นของกลุ่มการอัปเดตได้ที่การเปลี่ยนแปลงการกําหนดค่าบอร์ดและอุปกรณ์สําหรับอุปกรณ์ใหม่

ตัวอย่างข้อมูลเมตาในอุปกรณ์ ได้แก่

  • อุปกรณ์บล็อกจริง system_a
    • ข้อมูลเมตา 0
      • กลุ่ม foo_a
        • พาร์ติชันแบบลอจิค (แบบไดนามิก) system_a
        • พาร์ติชันแบบลอจิค (แบบไดนามิก) product_services_a
        • พาร์ติชันอื่นๆ ที่อัปเดตโดย Foo
      • กลุ่ม bar_a
        • พาร์ติชันแบบลอจิค (แบบไดนามิก) vendor_a
        • พาร์ติชันแบบลอจิค (แบบไดนามิก) product_a
        • พาร์ติชันอื่นๆ ที่อัปเดตโดย Bar
    • ข้อมูลเมตา 1 (ไม่ได้ใช้)
  • อุปกรณ์บล็อกจริง system_b
    • ข้อมูลเมตา 0 (ไม่ได้ใช้)
    • ข้อมูลเมตา 1
      • กลุ่ม foo_b
        • พาร์ติชันแบบลอจิค (แบบไดนามิก) system_b
        • พาร์ติชันแบบลอจิค (แบบไดนามิก) product_services_b
        • พาร์ติชันอื่นๆ ที่อัปเดตโดย Foo
      • กลุ่ม bar_b
        • พาร์ติชันแบบลอจิค (แบบไดนามิก) vendor_b
        • พาร์ติชันแบบลอจิค (แบบไดนามิก) product_b
        • พาร์ติชันอื่นๆ ที่อัปเดตโดย Bar

คุณสามารถใช้เครื่องมือ lpdump ในส่วน system/extras/partition_tools เพื่อถ่ายโอนข้อมูลเมตาในอุปกรณ์ เช่น

lpdump --slot 0 /dev/block/by-name/system_a
lpdump --slot 1 /dev/block/by-name/system_b

ติดตั้งการอัปเดต

ในอุปกรณ์ที่ใช้ Android 9 หรือต่ำกว่า ไคลเอ็นต์ OTA ในอุปกรณ์จะไม่รองรับการแมปพาร์ติชันแบบไดนามิกก่อนการอัปเดต ระบบจะสร้างชุดแพตช์เพิ่มเติมเพื่อให้ใช้การแมปกับพาร์ติชันที่มีอยู่ได้โดยตรง

ตัวสร้าง OTA จะสร้างไฟล์ super.img สุดท้ายที่มีเนื้อหาของพาร์ติชันแบบไดนามิกทั้งหมด จากนั้นจะแยกอิมเมจออกเป็นหลายอิมเมจที่ตรงกับขนาดของอุปกรณ์บล็อกจริงซึ่งสอดคล้องกับระบบ ผู้ให้บริการ และอื่นๆ รูปภาพเหล่านี้จะมีชื่อว่า super_system.img, super_vendor.img และอื่นๆ ไคลเอ็นต์ OTA จะใช้รูปภาพเหล่านี้กับพาร์ติชันจริงแทนการใช้รูปภาพสำหรับพาร์ติชันเชิงตรรกะ (แบบไดนามิก)

เนื่องจากไคลเอ็นต์ OTA ไม่ทราบวิธีแมปพาร์ติชันแบบไดนามิก ระบบจะปิดใช้ขั้นตอนหลังการติดตั้งทั้งหมดโดยอัตโนมัติสำหรับพาร์ติชันเหล่านี้เมื่อสร้างแพ็กเกจการอัปเดต ดูรายละเอียดเพิ่มเติมได้ที่การกำหนดค่าหลังการติดตั้ง

ขั้นตอนการอัปเดตจะเหมือนกับใน Android 9

ก่อนการอัปเดต

ro.boot.dynamic_partitions=
ro.boot.dynamic_partitions_retrofit=

หลังจากอัปเดตแล้ว

ro.boot.dynamic_partitions=true
ro.boot.dynamic_partitions_retrofit=true

การอัปเดตในอนาคตหลังจากการดัดแปลง

หลังจากการอัปเดตการต่ออายุ ไคลเอ็นต์ OTA จะอัปเดตให้ทำงานร่วมกับพาร์ติชันแบบไดนามิกได้ ขอบเขตของพาร์ติชันต้นทางจะไม่ครอบคลุมพาร์ติชันฟิสิคัลเป้าหมาย

ขั้นตอนอัปเดตโดยใช้แพ็กเกจอัปเดตปกติ

  1. เริ่มต้นข้อมูลเมตาของพาร์ติชัน super
    1. สร้างข้อมูลเมตา M ใหม่จากข้อมูลเมตา S (ข้อมูลเมตาของแหล่งที่มา) เช่น หากข้อมูลเมตา S ใช้ [system_s, vendor_s, product_s] เป็นอุปกรณ์บล็อก ข้อมูลเมตา M ใหม่จะใช้ [system_t, vendor_t, product_t] เป็นอุปกรณ์บล็อก ระบบจะทิ้งกลุ่มและพาร์ติชันทั้งหมดใน M
    2. เพิ่มกลุ่มเป้าหมายและพาร์ติชันตามช่อง dynamic_partition_metadata ในไฟล์ Manifest อัปเดต คุณจะดูขนาดของแต่ละพาร์ติชันได้ใน new_partition_info
    3. เขียน M ไปยัง T ข้อมูลเมตา
    4. แมปพาร์ติชันที่เพิ่มลงในโปรแกรมแมปอุปกรณ์เป็นแบบเขียนได้
  2. ใช้การอัปเดตในอุปกรณ์ที่บล็อก
    1. หากจำเป็น ให้แมปพาร์ติชันต้นทางในโปรแกรมแมปอุปกรณ์เป็นอ่านอย่างเดียว ซึ่งจำเป็นสำหรับการโหลดจากอุปกรณ์อื่นเนื่องจากระบบไม่ได้แมปพาร์ติชันต้นทางก่อนการอัปเดต
    2. ใช้การอัปเดตแบบเต็มหรือแบบ Delta กับอุปกรณ์บล็อกทั้งหมดในช่องเป้าหมาย
    3. ใส่ค่าพาร์ติชันเพื่อเรียกใช้สคริปต์หลังการติดตั้ง แล้วถอดพาร์ติชันออก
  3. ยกเลิกการแมปพาร์ติชันเป้าหมาย

ขั้นตอนการอัปเดตโดยใช้แพ็กเกจอัปเดตการต่ออายุ

หากใช้แพ็กเกจการอัปเดตเพื่อติดตั้งอุปกรณ์รุ่นเก่าในอุปกรณ์ที่เปิดใช้พาร์ติชันแบบไดนามิกอยู่แล้ว ไคลเอ็นต์ OTA จะใช้ไฟล์ super.img ที่แยกแล้วในอุปกรณ์แบบบล็อกโดยตรง ขั้นตอนอัปเดตจะคล้ายกับการอัปเดตเพื่อติดตั้งอุปกรณ์เสริม ดูรายละเอียดได้ที่การอัปเดตย้อนหลัง

ตัวอย่างเช่น สมมติว่า

  • ช่อง A คือช่องที่ใช้งานอยู่
  • system_a มีข้อมูลเมตาที่ใช้งานอยู่ที่ช่อง 0
  • system_a, vendor_a และ product_a ใช้เป็นเครื่องบล็อก

เมื่อไคลเอ็นต์ OTA ได้รับแพ็กเกจการอัปเดตการต่ออายุ แพ็กเกจดังกล่าวจะมีผลกับ super_system.img ใน system_b จริง super_vendor.img ใน vendor_b จริง และ super_product.img ใน product_b จริง อุปกรณ์บล็อกที่จับต้องได้ system_b มีข้อมูลเมตาที่ถูกต้องเพื่อจับคู่ system_b, vendor_b และ product_b เชิงตรรกะในเวลาบูต

สร้างแพ็กเกจอัปเดต

OTA ที่เพิ่มขึ้น

เมื่อสร้าง OTA ที่เพิ่มขึ้นสำหรับอุปกรณ์ที่ติดตั้งอุปกรณ์เสริม การอัปเดตจะขึ้นอยู่กับว่าบิลด์ฐานกำหนด PRODUCT_USE_DYNAMIC_PARTITIONS และ PRODUCT_RETROFIT_DYNAMIC_PARTITIONS หรือไม่

  • หากบิลด์ฐานไม่ได้กําหนดตัวแปร แสดงว่าเป็นการอัปเดตเพื่อติดตั้งอุปกรณ์ต่อท้าย แพ็กเกจอัปเดตมีไฟล์ super.img ที่แยกออกและปิดใช้ขั้นตอนหลังการติดตั้ง
  • หากบิลด์ฐานกำหนดตัวแปรไว้ การดำเนินการนี้จะเหมือนกับการอัปเดตตามปกติที่มีพาร์ติชันแบบไดนามิก แพ็กเกจการอัปเดตมีอิมเมจสำหรับพาร์ติชันเชิงตรรกะ (แบบไดนามิก) คุณเปิดใช้ขั้นตอนหลังการติดตั้งได้

OTA แบบสมบูรณ์

ระบบจะสร้างแพ็กเกจ OTA แบบสมบูรณ์ 2 รายการสำหรับอุปกรณ์ที่ติดตั้งอุปกรณ์เสริม

  • $(PRODUCT)-ota-retrofit-$(TAG).zip ประกอบด้วย super.img แบบแยกเสมอ และปิดใช้ขั้นตอนหลังการติดตั้งสำหรับการอัปเดตการต่ออายุ
    • ซึ่งสร้างขึ้นโดยมีอาร์กิวเมนต์เพิ่มเติม --retrofit_dynamic_partitions ให้กับสคริปต์ ota_from_target_files
    • ซึ่งใช้ได้กับทุกบิลด์
  • $(PRODUCT)-ota-$(TAG).zip มีรูปภาพที่สมเหตุสมผลสำหรับการอัปเดตในอนาคต
    • ใช้กับบิลด์ที่เปิดใช้พาร์ติชันแบบไดนามิกเท่านั้น ดูรายละเอียดเกี่ยวกับการบังคับใช้นโยบายนี้ด้านล่าง

ปฏิเสธการอัปเดตแบบไม่เปลี่ยนรุ่นในบิลด์เก่า

ใช้แพ็กเกจ OTA แบบเต็มปกติกับบิลด์ที่เปิดใช้พาร์ติชันแบบไดนามิกเท่านั้น หากเซิร์ฟเวอร์ OTA ได้รับการกําหนดค่าอย่างไม่ถูกต้องและพุชแพ็กเกจเหล่านี้ไปยังอุปกรณ์ที่ใช้ Android 9 หรือต่ำกว่า อุปกรณ์จะบูตไม่สำเร็จ ไคลเอ็นต์ OTA ใน Android 9 และต่ำกว่าไม่สามารถแยกความแตกต่างระหว่างแพ็กเกจ OTA สำหรับการต่ออายุและแพ็กเกจ OTA แบบเต็มปกติได้ ดังนั้นไคลเอ็นต์จะไม่ปฏิเสธแพ็กเกจแบบเต็ม

หากต้องการป้องกันไม่ให้อุปกรณ์ยอมรับแพ็กเกจ OTA แบบเต็ม คุณสามารถกำหนดให้ต้องมีขั้นตอนหลังการติดตั้งเพื่อตรวจสอบการกำหนดค่าอุปกรณ์ที่มีอยู่ เช่น

device/device_name/dynamic_partitions/check_dynamic_partitions

#!/system/bin/sh
DP_PROPERTY_NAME="ro.boot.dynamic_partitions"
DP_RETROFIT_PROPERTY_NAME="ro.boot.dynamic_partitions_retrofit"

DP_PROPERTY=$(getprop ${DP_PROPERTY_NAME})
DP_RETROFIT_PROPERTY=$(getprop ${DP_RETROFIT_PROPERTY_NAME})

if [ "${DP_PROPERTY}" != "true" ] || [ "${DP_RETROFIT_PROPERTY}" != "true" ] ; then
    echo "Error: applied non-retrofit update on build without dynamic" \
         "partitions."
    echo "${DP_PROPERTY_NAME}=${DP_PROPERTY}"
    echo "${DP_RETROFIT_PROPERTY_NAME}=${DP_RETROFIT_PROPERTY}"
    exit 1
fi

device/device_name/dynamic_partitions/Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= check_dynamic_partitions
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_SRC_FILES := check_dynamic_partitions
LOCAL_PRODUCT_MODULE := true
include $(BUILD_PREBUILT)

device/device_name/device.mk

PRODUCT_PACKAGES += check_dynamic_partitions

# OPTIONAL=false so that the error in check_dynamic_partitions will be
# propagated to OTA client.
AB_OTA_POSTINSTALL_CONFIG += \
    RUN_POSTINSTALL_product=true \
    POSTINSTALL_PATH_product=bin/check_dynamic_partitions \
    FILESYSTEM_TYPE_product=ext4 \
    POSTINSTALL_OPTIONAL_product=false \

เมื่อใช้แพ็กเกจ OTA ปกติในอุปกรณ์ที่ไม่ได้เปิดใช้พาร์ติชันแบบไดนามิก ไคลเอ็นต์ OTA จะทำงานcheck_dynamic_partitionsเป็นขั้นตอนหลังการติดตั้งและปฏิเสธการอัปเดต