OEM และผู้ให้บริการ SoC ที่ต้องการใช้การอัปเดตระบบ A/B จะต้องตรวจสอบว่าโปรแกรมโหลดบูตใช้ HAL ของ boot_control และส่งพารามิเตอร์ที่ถูกต้องไปยังเคอร์เนล
ใช้ HAL การควบคุมการบูต
บูตโหลดเดอร์ที่รองรับ A/B ต้องใช้ boot_control
HAL ที่ hardware/libhardware/include/hardware/boot_control.h
คุณทดสอบการติดตั้งใช้งานได้โดยใช้ยูทิลิตี system/extras/bootctl
และ system/extras/tests/bootloader/
นอกจากนี้ คุณยังต้องใช้สถานะการทำงานของเครื่องจักรที่แสดงด้านล่างด้วย

ตั้งค่าเคอร์เนล
วิธีใช้การอัปเดตระบบ A/B
-
เลือกชุดแพตช์เคอร์เนลต่อไปนี้ (หากจำเป็น)
- หากบูตโดยไม่ใช้ RAM disk และใช้ "boot as recovery" ให้ใช้การคัดลอกเฉพาะส่วน android-review.googlesource.com/#/c/158491/
- หากต้องการตั้งค่า dm-verity โดยไม่ใช้ RAMDisk ให้ใช้การคัดลอกเฉพาะ 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>
คือรหัสของคีย์สาธารณะที่ใช้เพื่อยืนยันลายเซ็นตาราง Verity (ดูรายละเอียดที่ 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 ที่จัดรูปแบบในรูปแบบ
ตั้งค่าตัวแปรของบิลด์
บูตโหลดเดอร์ที่พร้อมใช้งาน 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
เมื่อเข้าสู่การกู้คืน บูตโหลดเดอร์ไม่สามารถใส่ตัวเลือก skip_initramfs
ในบรรทัดคำสั่งเคอร์เนล
สําหรับการอัปเดตที่ไม่ใช่ A/B พาร์ติชันการกู้คืนจะมีโค้ดที่ใช้เพื่ออัปเดต การอัปเดต A/B จะมีผลเมื่อ update_engine
ทำงานในอิมเมจระบบที่บูตตามปกติ
แต่ยังคงมีโหมดการกู้คืนที่ใช้เพื่อรีเซ็ตข้อมูลเป็นค่าเริ่มต้นและโหลดแพ็กเกจอัปเดตจากภายนอก (ซึ่งเป็นที่มาของชื่อ "การกู้คืน") โค้ดและข้อมูลสำหรับโหมดการกู้คืนจะจัดเก็บไว้ในพาร์ติชันการบูทปกติในแรมดิสก์ หากต้องการบูตเข้าสู่อิมเมจระบบ Bootloader จะบอกให้เคอร์เนลข้ามแรมดิสก์ (มิเช่นนั้นอุปกรณ์จะบูตเข้าสู่โหมดการกู้คืน โมด Recovery มีขนาดเล็ก (และข้อมูลส่วนใหญ่อยู่ในพาร์ติชันสำหรับบูตอยู่แล้ว) ดังนั้นพาร์ติชันสำหรับบูตจึงไม่มีขนาดใหญ่ขึ้น
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
) หรือผ่านบรรทัดคำสั่งของเคอร์เนลหรืออาร์กิวเมนต์ bootconfig androidboot.slot_suffix
โดยค่าเริ่มต้น Fastboot จะแฟลชสล็อตปัจจุบันในอุปกรณ์ A/B หากแพ็กเกจอัปเดตมีรูปภาพสำหรับอีกช่องที่ไม่ได้ใช้งานอยู่ด้วย Fastboot จะแฟลชรูปภาพเหล่านั้นด้วย ตัวเลือกที่ใช้ได้มีดังนี้
-
--slot SLOT
ลบล้างลักษณะการทำงานเริ่มต้นและแจ้งให้ Fastboot แฟลชสล็อตที่ส่งผ่านเป็นอาร์กิวเมนต์ -
--set-active [SLOT]
ตั้งค่าช่องเป็นใช้งานอยู่ หากไม่ได้ระบุอาร์กิวเมนต์ที่ไม่บังคับ ระบบจะตั้งค่าช่องปัจจุบันเป็น "ใช้งานอยู่" fastboot --help
ดูรายละเอียดเกี่ยวกับคำสั่ง
หากบูตโหลดเดอร์ใช้ Fastboot ก็ควรรองรับคำสั่ง set_active <slot>
ที่จะตั้งค่าช่องที่ใช้งานอยู่ในปัจจุบันเป็นช่องที่ระบุ (การดำเนินการนี้จะต้องล้าง Flag ที่บูตไม่ได้สำหรับช่องนั้นและรีเซ็ตจำนวนครั้งที่จะลองใหม่เป็นค่าเริ่มต้นด้วย) นอกจากนี้ บูตโหลดเดอร์ควรรองรับตัวแปรต่อไปนี้ด้วย
-
has-slot:<partition-base-name-without-suffix>
แสดงผลเป็น "ใช่" หากพาร์ติชันที่ระบุรองรับสล็อต และแสดงผลเป็น "ไม่" ในกรณีอื่น 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 ใดก็ได้ที่กําหนดไว้ในดิสก์เดียวกัน
พาร์ติชันคู่หนึ่งจะมีคำนำหน้า (เช่น system
หรือ boot
) และคำต่อท้ายต่อแต่ละช่อง (เช่น _a
) รายการพาร์ติชันที่เครื่องมือสร้างเพย์โหลดกำหนดการอัปเดตจะได้รับการกําหนดค่าโดยตัวแปร AB_OTA_PARTITIONS
make
ตัวอย่างเช่น หากรวมพาร์ติชัน bootloader_a
และ booloader_b
ไว้ด้วยกัน (_a
และ _b
เป็นนามสกุลของสล็อต) คุณจะอัปเดตพาร์ติชันเหล่านี้ได้โดยระบุข้อมูลต่อไปนี้ในการกำหนดค่าผลิตภัณฑ์หรือบอร์ด
AB_OTA_PARTITIONS := \ boot \ system \ bootloader
ระบบส่วนที่เหลือต้องไม่แก้ไขพาร์ติชันทั้งหมดที่อัปเดตโดย update_engine
ในระหว่างการอัปเดตแบบเพิ่มหรือ Delta ระบบจะใช้ข้อมูลไบนารีจากช่องปัจจุบันเพื่อสร้างข้อมูลในช่องใหม่ การแก้ไขใดๆ อาจทําให้ข้อมูลช่องใหม่ไม่ผ่านการยืนยันระหว่างกระบวนการอัปเดต และส่งผลให้อัปเดตไม่สําเร็จ
กำหนดค่าหลังการติดตั้ง
คุณสามารถกําหนดค่าขั้นตอนหลังการติดตั้งให้แตกต่างกันสําหรับพาร์ติชันที่อัปเดตแต่ละรายการได้โดยใช้ชุดคู่คีย์-ค่า หากต้องการเรียกใช้โปรแกรมที่อยู่ที่ /system/usr/bin/postinst
ในภาพใหม่ ให้ระบุเส้นทางที่สัมพันธ์กับรูทของระบบไฟล์ในพาร์ติชันระบบ
เช่น usr/bin/postinst
คือ system/usr/bin/postinst
(หากไม่ได้ใช้ดิสก์ RAM) นอกจากนี้ ให้ระบุประเภทระบบไฟล์ที่จะส่งไปยัง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 ในการบูตครั้งแรก