OEM และผู้ให้บริการ SoC ที่ต้องการใช้การอัปเดตระบบ A/B ต้องตรวจสอบว่าโปรแกรมโหลดระบบ ใช้ HAL ของ boot_control และส่งพารามิเตอร์ที่ถูกต้องไปยัง เคอร์เนล
ใช้ HAL การควบคุมการบูต
      Bootloader ที่ใช้ A/B ได้ต้องใช้ HAL ของ boot_control ที่
      hardware/libhardware/include/hardware/boot_control.h คุณทดสอบการติดตั้งใช้งานได้โดยใช้
      system/extras/bootctl
      ยูทิลิตีและ
      system/extras/tests/bootloader/
    
นอกจากนี้ คุณยังต้องใช้เครื่องสถานะที่แสดงด้านล่างด้วย
 
    ตั้งค่าเคอร์เนล
วิธีใช้การอัปเดตระบบ A/B
- 
        เลือกแพตช์เคอร์เนลชุดต่อไปนี้ (หากจำเป็น)
        - หากบูตโดยไม่มี ramdisk และใช้ "boot as recovery" ให้ cherrypick android-review.googlesource.com/#/c/158491/
- หากต้องการตั้งค่า dm-verity โดยไม่มี ramdisk ให้ cherrypick android-review.googlesource.com/#/q/status:merged+project:kernel/common+branch:android-3.18+topic:A_B_Changes_3.18
 
- 
        ตรวจสอบว่าอาร์กิวเมนต์บรรทัดคำสั่งของเคอร์เนลมีอาร์กิวเมนต์เพิ่มเติมต่อไปนี้
        skip_initramfs rootwait ro init=/init root="/dev/dm-0 dm=system none ro,0 1 android-verity <public-key-id> <path-to-system-partition>"<public-key-id>คือรหัสของคีย์สาธารณะที่ใช้เพื่อ ยืนยันลายเซ็นตารางความถูกต้อง (ดูรายละเอียดได้ที่ dm-verity)
- 
        เพิ่มใบรับรอง .X509 ที่มีคีย์สาธารณะลงในพวงกุญแจระบบ
        - 
            คัดลอกใบรับรอง .X509 ที่จัดรูปแบบในรูปแบบ .derไปยังรูทของไดเรกทอรีkernelหากใบรับรอง .X509 จัดรูปแบบเป็นไฟล์.pemให้ใช้คำสั่งopensslต่อไปนี้เพื่อแปลงจาก.pemเป็นรูปแบบ.deropenssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate> 
- 
            สร้าง zImageเพื่อรวมใบรับรองเป็นส่วนหนึ่งของพวงกุญแจระบบ หากต้องการยืนยัน ให้ตรวจสอบรายการprocfs(ต้องเปิดใช้KEYS_CONFIG_DEBUG_PROC_KEYS):angler:/# cat /proc/keys 1c8a217e I------ 1 perm 1f010000 0 0 asymmetri Android: 7e4333f9bba00adfe0ede979e28ed1920492b40f: X509.RSA 0492b40f [] 2d454e3e I------ 1 perm 1f030000 0 0 keyring .system_keyring: 1/4 
- 
            แทนที่ช่องว่างด้วย #แล้วส่งเป็น<public-key-id>ในบรรทัดคำสั่งของเคอร์เนล เช่น ส่งAndroid:#7e4333f9bba00adfe0ede979e28ed1920492b40fแทน<public-key-id>
 
- 
            คัดลอกใบรับรอง .X509 ที่จัดรูปแบบในรูปแบบ 
ตั้งค่าตัวแปรบิลด์
Bootloader ที่ใช้ A/B ได้ต้องเป็นไปตามเกณฑ์ตัวแปรบิลด์ต่อไปนี้
| ต้องกำหนดเป้าหมาย A/B | 
 /device/google/marlin/+/android-7.1.0_r1/device-common.mkคุณเลือกที่จะทำขั้นตอน dex2oat หลังการติดตั้ง (แต่ก่อนการรีบูต) ที่อธิบายไว้ใน
          การคอมไพล์ได้ | 
|---|---|
| ขอแนะนำอย่างยิ่งสำหรับเป้าหมาย A/B | 
 | 
| กำหนดเป้าหมาย A/B ไม่ได้ | 
 | 
| ไม่บังคับสำหรับบิลด์การแก้ไขข้อบกพร่อง | PRODUCT_PACKAGES_DEBUG += update_engine_client | 
ตั้งค่าพาร์ติชัน (สล็อต)
      อุปกรณ์ A/B ไม่จำเป็นต้องมีพาร์ติชันการกู้คืนหรือพาร์ติชันแคช เนื่องจาก Android ไม่ได้ใช้พาร์ติชันเหล่านี้อีกต่อไป
       ตอนนี้พาร์ติชันข้อมูลจะใช้สำหรับแพ็กเกจ OTA ที่ดาวน์โหลด และ
      โค้ดอิมเมจการกู้คืนจะอยู่ในพาร์ติชันการบูต พาร์ติชันทั้งหมดที่ใช้การทดสอบ A/B ควรมีชื่อ
      ดังนี้ (ช่องจะมีชื่อเป็น a, b ฯลฯ เสมอ) boot_a,
      boot_b, system_a, system_b, vendor_a,
      vendor_b
    
แคช
สำหรับการอัปเดตที่ไม่ใช่ A/B ระบบจะใช้พาร์ติชันแคชเพื่อจัดเก็บแพ็กเกจ OTA ที่ดาวน์โหลดมาและเพื่อ จัดเก็บบล็อกชั่วคราวขณะใช้การอัปเดต ไม่มีวิธีที่เหมาะสมในการกำหนดขนาดพาร์ติชันแคช เนื่องจากขนาดที่ต้องการจะขึ้นอยู่กับการอัปเดตที่คุณต้องการใช้ กรณีที่แย่ที่สุด คือพาร์ติชันแคชมีขนาดใหญ่เท่ากับอิมเมจระบบ การอัปเดต A/B ไม่จำเป็นต้อง ซ่อนบล็อก (เนื่องจากคุณเขียนไปยังพาร์ติชันที่ไม่ได้ใช้ในปัจจุบันเสมอ) และ การอัปเดต A/B แบบสตรีมมิงไม่จำเป็นต้องดาวน์โหลดแพ็กเกจ OTA ทั้งหมดก่อนที่จะใช้
การกู้คืน
      ตอนนี้ดิสก์ RAM สำหรับการกู้คืนอยู่ในไฟล์ boot.img แล้ว เมื่อเข้าสู่โหมดการกู้คืน Bootloader จะไม่สามารถใส่ตัวเลือก skip_initramfs ในบรรทัดคำสั่งของเคอร์เนลได้
    
      สำหรับการอัปเดตที่ไม่ใช่ A/B พาร์ติชันการกู้คืนจะมีโค้ดที่ใช้ในการใช้การอัปเดต A/B
      updates are applied by update_engine running in the regular booted system image.
      แต่ก็ยังมีโหมดการกู้คืนที่ใช้เพื่อรีเซ็ตข้อมูลเป็นค่าเริ่มต้นและโหลดแพ็กเกจการอัปเดตด้านข้าง (ซึ่งเป็นที่มาของชื่อ "การกู้คืน") โค้ดและข้อมูลสำหรับโหมดการกู้คืน
      จะจัดเก็บไว้ในพาร์ติชันการบูตปกติใน Ramdisk เพื่อบูตเข้าสู่รูปภาพระบบ
      Bootloader จะบอกเคอร์เนลให้ข้าม Ramdisk (มิฉะนั้นอุปกรณ์จะบูตเข้าสู่โหมดการกู้คืน
       โหมดการกู้คืนมีขนาดเล็ก (และส่วนใหญ่ก็อยู่ในพาร์ติชันการบูตอยู่แล้ว) ดังนั้นพาร์ติชันการบูตจึงไม่เพิ่มขนาด
    
Fstab
      อาร์กิวเมนต์ slotselect ต้องอยู่ในบรรทัดสำหรับพาร์ติชันที่ทำการทดสอบ A/B
       เช่น
    
<path-to-block-device>/vendor /vendor ext4 ro wait,verify=<path-to-block-device>/metadata,slotselect
      ไม่ควรตั้งชื่อพาร์ติชันว่า vendor แต่ระบบจะเลือกและติดตั้งพาร์ติชัน vendor_a หรือ
      vendor_b ใน/vendorเมานต์พอยต์แทน
    
อาร์กิวเมนต์ของสล็อตเคอร์เนล
      ควรส่งต่อคำต่อท้ายของสล็อตปัจจุบันผ่านโหนด Device Tree (DT) ที่เฉพาะเจาะจง
      (/firmware/android/slot_suffix) หรือผ่านบรรทัดคำสั่งเคอร์เนล
      androidboot.slot_suffix หรืออาร์กิวเมนต์ bootconfig
    
โดยค่าเริ่มต้น fastboot จะแฟลชสล็อตปัจจุบันในอุปกรณ์ A/B หากแพ็กเกจการอัปเดตมีรูปภาพสำหรับสล็อตอื่นที่ไม่ใช่สล็อตปัจจุบันด้วย fastboot จะแฟลชรูปภาพเหล่านั้นด้วย ตัวเลือกที่มี ได้แก่
- 
        --slot SLOTลบล้างลักษณะการทำงานเริ่มต้นและแจ้งให้ fastboot แฟลชสล็อตที่ส่งผ่านเป็น อาร์กิวเมนต์
- 
        --set-active [SLOT]ตั้งค่าช่องเป็นใช้งานอยู่ หากไม่ได้ระบุอาร์กิวเมนต์ที่ไม่บังคับ ระบบจะตั้งค่าช่องปัจจุบันเป็นใช้งานอยู่
- fastboot --helpดูรายละเอียดเกี่ยวกับคำสั่ง
      หาก Bootloader ใช้ fastboot ก็ควรจะรองรับคำสั่ง
      set_active <slot> ที่ตั้งค่าสล็อตที่ใช้งานอยู่ปัจจุบันเป็นสล็อตที่ระบุ (คำสั่งนี้
      ต้องล้างค่าสถานะที่บูตไม่ได้สำหรับสล็อตนั้นและรีเซ็ตจำนวนครั้งที่ลองใหม่เป็นค่าเริ่มต้นด้วย
      ) นอกจากนี้ Bootloader ควรจะรองรับตัวแปรต่อไปนี้ด้วย
    
- 
        has-slot:<partition-base-name-without-suffix>แสดงผล "yes" หากพาร์ติชันที่ระบุรองรับสล็อต และแสดงผล "no" ในกรณีอื่นๆ
- current-slot. แสดงผลคำต่อท้ายของสล็อตที่จะบูตจากครั้งถัดไป
- 
        slot-countแสดงผลจำนวนเต็มที่แสดงจำนวนช่วงเวลาที่ว่าง ปัจจุบันรองรับ 2 ช่อง ดังนั้นค่านี้จึงเป็น2
- 
        slot-successful:<slot-suffix>แสดงผล "yes" หากมีการทำเครื่องหมายว่าสล็อตที่ระบุ บูตสำเร็จ หรือ "no" ในกรณีอื่นๆ
- 
        slot-unbootable:<slot-suffix>แสดงผล "yes" หากมีการทำเครื่องหมายว่าสล็อตที่ระบุ บูตไม่ได้ และแสดงผล "no" ในกรณีอื่นๆ
- 
        slot-retry-count:<slot-suffix>จำนวนการลองใหม่ที่เหลืออยู่เพื่อพยายาม บูตช่องที่ระบุ
      หากต้องการดูตัวแปรทั้งหมด ให้เรียกใช้
      fastboot getvar all
    
สร้างแพ็กเกจ OTA
      เครื่องมือแพ็กเกจ OTA จะใช้คำสั่งเดียวกันกับคำสั่ง
      สำหรับอุปกรณ์ที่ไม่ใช่ A/B ต้องสร้างไฟล์ target_files.zip โดย
      กำหนดตัวแปรบิลด์สำหรับเป้าหมาย A/B เครื่องมือแพ็กเกจ OTA จะระบุ
      และสร้างแพ็กเกจในรูปแบบสำหรับโปรแกรมอัปเดต A/B โดยอัตโนมัติ
    
ตัวอย่าง
- 
        วิธีสร้าง OTA แบบเต็ม
        ./build/make/tools/releasetools/ota_from_target_files \ dist_output/tardis-target_files.zip \ ota_update.zip
- 
        วิธีสร้าง OTA แบบเพิ่ม
        ./build/make/tools/releasetools/ota_from_target_files \ -i PREVIOUS-tardis-target_files.zip \ dist_output/tardis-target_files.zip \ incremental_ota_update.zip
กำหนดค่าพาร์ติชัน
      update_engine สามารถอัปเดตพาร์ติชัน A/B คู่ใดก็ได้ที่กำหนดไว้ในดิสก์เดียวกัน
      พาร์ติชัน 2 รายการจะมีคำนำหน้าร่วมกัน (เช่น system หรือ boot)
      และคำต่อท้ายต่อช่อง (เช่น _a) รายการพาร์ติชันที่เครื่องมือสร้างเพย์โหลด
      กำหนดการอัปเดตจะได้รับการกำหนดค่าโดยตัวแปร AB_OTA_PARTITIONS
    
      ตัวอย่างเช่น หากมีพาร์ติชันคู่ bootloader_a และ
      booloader_b (_a และ _b เป็นคำต่อท้ายของสล็อต
      ) คุณสามารถอัปเดตพาร์ติชันเหล่านี้ได้โดยระบุข้อมูลต่อไปนี้ในการกำหนดค่าผลิตภัณฑ์หรือบอร์ด
      
    
AB_OTA_PARTITIONS := \ boot \ system \ bootloader
      พาร์ติชันทั้งหมดที่อัปเดตโดย update_engine ต้องไม่ได้รับการแก้ไขโดยส่วนอื่นๆ ของ
      ระบบ ในระหว่างการอัปเดตแบบเพิ่มทีละรายการหรือเดลต้า ระบบจะใช้ข้อมูลไบนารีจากช่องปัจจุบัน
      เพื่อสร้างข้อมูลในช่องใหม่ การแก้ไขใดๆ อาจทำให้ข้อมูลช่องใหม่
      ยืนยันไม่สำเร็จระหว่างกระบวนการอัปเดต และส่งผลให้อัปเดตไม่สำเร็จ
    
กำหนดค่าหลังการติดตั้ง
      คุณสามารถกำหนดค่าขั้นตอนหลังการติดตั้งที่แตกต่างกันสำหรับแต่ละพาร์ติชันที่อัปเดตได้โดยใช้ชุด
      คู่คีย์-ค่า หากต้องการเรียกใช้โปรแกรมที่อยู่ใน /system/usr/bin/postinst ในอิมเมจใหม่
      ให้ระบุเส้นทางที่สัมพันธ์กับรูทของระบบไฟล์ในพาร์ติชันของระบบ
    
      เช่น usr/bin/postinst คือ system/usr/bin/postinst (หากไม่ได้
      ใช้ RAM Disk) นอกจากนี้ ให้ระบุประเภทระบบไฟล์ที่จะส่งไปยัง
      mount(2) การเรียกใช้ระบบ เพิ่มข้อมูลต่อไปนี้ลงในไฟล์ .mk ของผลิตภัณฑ์หรืออุปกรณ์ (หากมี)
    
AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=usr/bin/postinst \ FILESYSTEM_TYPE_system=ext4
คอมไพล์แอป
แอปสามารถคอมไพล์ในเบื้องหลังก่อนการรีบูตด้วยอิมเมจระบบใหม่ หากต้องการคอมไพล์ แอปในเบื้องหลัง ให้เพิ่มข้อมูลต่อไปนี้ลงในการกำหนดค่าอุปกรณ์ของผลิตภัณฑ์ (ใน device.mk ของผลิตภัณฑ์)
- 
        รวมคอมโพเนนต์ดั้งเดิมไว้ในการสร้างเพื่อให้แน่ใจว่าสคริปต์การคอมไพล์และไบนารีจะได้รับการคอมไพล์และรวมไว้ในอิมเมจระบบ
        # A/B OTA dexopt package PRODUCT_PACKAGES += otapreopt_script 
- 
        เชื่อมต่อสคริปต์การคอมไพล์กับ update_engineเพื่อให้ทำงานเป็น ขั้นตอนหลังการติดตั้ง# A/B OTA dexopt update_engine hookup AB_OTA_POSTINSTALL_CONFIG += \ RUN_POSTINSTALL_system=true \ POSTINSTALL_PATH_system=system/bin/otapreopt_script \ FILESYSTEM_TYPE_system=ext4 \ POSTINSTALL_OPTIONAL_system=true
หากต้องการความช่วยเหลือในการติดตั้งไฟล์ที่ผ่านการเพิ่มประสิทธิภาพล่วงหน้าในพาร์ติชันระบบที่ 2 ที่ไม่ได้ใช้ โปรดดู การติดตั้งไฟล์ DEX_PREOPT ในการบูตครั้งแรก
