ผู้ให้บริการ OEM และ SoC ที่ต้องการใช้การอัปเดตระบบ A/B ต้องตรวจสอบ Bootloader ติดตั้งใช้งาน Boot_control HAL และส่งพารามิเตอร์ที่ถูกต้องไปยัง เคอร์เนล
ใช้งาน HAL การควบคุมการเปิดเครื่อง
Bootloader ที่รองรับ A/B ต้องใช้ boot_control
HAL ที่
hardware/libhardware/include/hardware/boot_control.h
คุณสามารถทดสอบการติดตั้งใช้งานได้โดยใช้
system/extras/bootctl
ยูทิลิตีและ
system/extras/tests/bootloader/
นอกจากนี้ คุณต้องติดตั้งใช้งานเครื่องสถานะดังที่แสดงด้านล่างด้วย
ตั้งค่าเคอร์เนล
วิธีใช้การอัปเดตระบบ A/B
-
ตรวจสอบชุดแพตช์ของเคอร์เนลต่อไปนี้ (หากจำเป็น)
- หากเปิดเครื่องโดยไม่มี RAM และใช้ "บูตเป็นการกู้คืน" ให้ cherry-pick android-review.googlesource.com/#/c/158491/
- หากต้องการตั้งค่า dm-verity โดยไม่มี RAM ให้ cherry-pick 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>
ในบรรทัดคำสั่งของเคอร์เนล เช่น PassAndroid:#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-ed
ดังนี้ (ช่องจะมีชื่อว่า 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 พาร์ติชันการกู้คืนจะมีโค้ดที่ใช้อัปเดต อัลฟา/เบต้า
การอัปเดตจะดำเนินการโดย update_engine
ที่ทำงานในอิมเมจระบบที่เปิดเครื่องตามปกติ
ยังมีโหมดการกู้คืนเพื่อใช้การรีเซ็ตข้อมูลเป็นค่าเริ่มต้นและการโหลดจากแหล่งที่ไม่รู้จัก
(ซึ่งเป็นที่มาของชื่อ "การกู้คืน") โค้ดและข้อมูลสำหรับโหมดการกู้คืน
จัดเก็บไว้ในพาร์ติชันการเปิดเครื่องปกติใน RAM เพื่อบูตเข้าสู่อิมเมจระบบ
Bootloader บอกเคอร์เนลให้ข้าม RAM ดิสก์ (มิฉะนั้นอุปกรณ์จะเริ่มต้นระบบเข้าสู่การกู้คืน
โหมดการกู้คืนมีขนาดเล็ก (และส่วนใหญ่อยู่ในพาร์ติชันการเปิดเครื่องอยู่แล้ว) การเปิดเครื่อง
ขนาดพาร์ติชันไม่เพิ่มขึ้น
Fstab
อาร์กิวเมนต์ slotselect
ต้องอยู่ในบรรทัดสำหรับ A/B-ed
พาร์ติชัน เช่น
<path-to-block-device>/vendor /vendor ext4 ro wait,verify=<path-to-block-device>/metadata,slotselect
ไม่ควรตั้งชื่อพาร์ติชันเป็น vendor
แต่ให้แบ่งพาร์ติชัน vendor_a
หรือ
ระบบจะเลือก vendor_b
และต่อเชื่อมบนจุดต่อเชื่อม /vendor
อาร์กิวเมนต์ช่องเคอร์เนล
คำต่อท้ายช่องปัจจุบันควรส่งผ่านโหนดแผนผังอุปกรณ์ (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" หากระบุ พาร์ติชันรองรับสล็อต "ไม่" current-slot
แสดงคำต่อท้ายของสล็อตที่จะบูตจากรายการถัดไป-
slot-count
แสดงผลจำนวนเต็มที่แทนจำนวนสล็อตที่ใช้ได้ ปัจจุบันมีการรองรับ 2 สล็อต ดังนั้นค่านี้จึงเป็น2
-
slot-successful:<slot-suffix>
แสดงค่า "yes" หากช่องโฆษณาที่ระบุเป็น ทำเครื่องหมายว่าเปิดเครื่องเรียบร้อยแล้ว "ไม่" หรือไม่เช่นนั้น -
slot-unbootable:<slot-suffix>
แสดงค่า "yes" หากช่องที่ระบุมีการทำเครื่องหมายไว้ ว่าไม่สามารถบูตได้, "ไม่" หรือไม่เช่นนั้น -
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
เช่น หากพาร์ติชันคู่หนึ่งคือ 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) นอกจากนี้ ให้ระบุประเภทระบบไฟล์ที่จะส่งต่อไปยัง
การเรียกใช้ระบบ 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 ครั้งแรก