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
เป็นรูปแบบ.der
openssl x509 -in <x509-pem-certificate> -outform der -out <x509-der-certificate>
-
สร้าง
zImage
เพื่อรวมใบรับรองเป็นส่วนหนึ่งของพวงกุญแจระบบ หากต้องการยืนยัน ให้ตรวจสอบรายการprocfs
(ต้องเปิดใช้KEYS_CONFIG_DEBUG_PROC_KEYS
): การรวมใบรับรอง .X509 สำเร็จแสดงว่ามีคีย์สาธารณะ ในพวงกุญแจระบบ (ไฮไลต์ระบุรหัสคีย์สาธารณะ)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 ในการบูตครั้งแรก