การอัปเดตระบบแบบไดนามิก (DSU) ช่วยให้คุณสร้างอิมเมจระบบ Android ที่ผู้ใช้ดาวน์โหลดจากอินเทอร์เน็ตและทดลองใช้ได้โดยไม่ต้องเสี่ยงต่อการทำให้อิมเมจระบบปัจจุบันเสียหาย เอกสารนี้อธิบายวิธีรองรับ DSU
ข้อกำหนดของเคอร์เนล
ดูข้อกำหนดของเคอร์เนลได้ที่ การใช้พาร์ติชันแบบไดนามิก
นอกจากนี้ DSU ยังใช้ฟีเจอร์เคอร์เนล Device-Mapper-Verity (dm-verity) เพื่อยืนยันอิมเมจระบบ Android ดังนั้นคุณต้องเปิดใช้การกำหนดค่าเคอร์เนลต่อไปนี้
CONFIG_DM_VERITY=yCONFIG_DM_VERITY_FEC=y
ข้อกำหนดของพาร์ติชัน
ตั้งแต่ Android 11 เป็นต้นไป DSU กำหนดให้พาร์ติชัน /data ต้องใช้ระบบไฟล์ F2FS หรือ ext4 F2FS ให้ประสิทธิภาพที่ดีกว่าและขอแนะนำให้ใช้ แต่ความแตกต่างควรมีนัยสำคัญ
ตัวอย่างระยะเวลาที่ใช้ในการอัปเดตระบบแบบไดนามิกในอุปกรณ์ Pixel มีดังนี้
- การใช้ F2FS
- 109 วินาที, ผู้ใช้ 8 GB, ระบบ 867 MB, ประเภทระบบไฟล์: F2FS: การเข้ารหัส=aes-256-xts:aes-256-cts
- 104 วินาที, ผู้ใช้ 8 GB, ระบบ 867 MB, ประเภทระบบไฟล์: F2FS: การเข้ารหัส=ice
- การใช้ ext4
- 135 วินาที, ผู้ใช้ 8 GB, ระบบ 867 MB, ประเภทระบบไฟล์: ext4: การเข้ารหัส=aes-256-xts:aes-256-cts
หากแพลตฟอร์มของคุณใช้เวลานานกว่านี้มาก คุณอาจต้องตรวจสอบว่าแฟล็กการติดตั้งมีแฟล็กที่ทำให้เกิดการเขียน "ซิงค์" หรือไม่ หรือคุณสามารถระบุแฟล็ก "ไม่พร้อมกัน" อย่างชัดเจนเพื่อให้ได้ประสิทธิภาพที่ดีขึ้น
พาร์ติชัน metadata (ขนาด 16 MB ขึ้นไป) จำเป็นสำหรับการจัดเก็บข้อมูลที่เกี่ยวข้องกับอิมเมจที่ติดตั้ง โดยต้องติดตั้งในระหว่างการติดตั้งระยะแรก
พาร์ติชัน userdata ต้องใช้ระบบไฟล์ F2FS หรือ ext4 เมื่อใช้ F2FS,
ให้รวมแพตช์ทั้งหมดที่เกี่ยวข้องกับ F2FS ซึ่งมีอยู่ใน
เคอร์เนลทั่วไปของ Android
DSU ได้รับการพัฒนาและทดสอบด้วยเคอร์เนล/ทั่วไป 4.9 เราขอแนะนำให้ใช้เคอร์เนล 4.9 ขึ้นไปสำหรับฟีเจอร์นี้
ลักษณะการทำงานของ Vendor HAL
Weaver HAL
Weaver HAL มีสล็อตจำนวนคงที่ สำหรับจัดเก็บคีย์ของผู้ใช้ DSU ใช้สล็อตคีย์เพิ่มเติม 2 สล็อต หาก OEM มี Weaver HAL ก็ต้องมีสล็อตเพียงพอสำหรับอิมเมจระบบทั่วไป (GSI) และอิมเมจโฮสต์
Gatekeeper HAL
Gatekeeper HAL ต้อง
รองรับค่า USER_ID ขนาดใหญ่ เนื่องจาก GSI จะชดเชย UID ไปยัง HAL ด้วยค่า
+1000000
การเปิดเครื่องที่ได้รับการยืนยัน
หากต้องการรองรับการบูตอิมเมจ GSI ของนักพัฒนาแอป
ในสถานะ LOCKEDโดยไม่ปิดใช้
การเปิดเครื่องที่ได้รับการยืนยัน ให้ใส่คีย์ GSI ของนักพัฒนาแอปโดยเพิ่มบรรทัดต่อไปนี้
ลงในไฟล์device/<device_name>/device.mk
$(call inherit-product, $(SRC_TARGET_DIR)/product/developer_gsi_keys.mk)
การป้องกันการย้อนกลับ
เมื่อใช้ DSU อิมเมจระบบ Android ที่ดาวน์โหลดต้องใหม่กว่าอิมเมจระบบปัจจุบันในอุปกรณ์ ซึ่งทำได้โดยการเปรียบเทียบระดับแพตช์ด้านความปลอดภัยในตัวอธิบายพร็อพเพอร์ตี้ AVB ของการเปิดเครื่องที่ได้รับการยืนยัน (AVB) ของอิมเมจระบบทั้ง 2 รายการ: Prop: com.android.build.system.security_patch ->
'2019-04-05'
สำหรับอุปกรณ์ที่ไม่ได้ใช้ AVB ให้ใส่ระดับแพตช์ด้านความปลอดภัยของอิมเมจระบบปัจจุบันลงใน cmdline หรือ bootconfig ของเคอร์เนลด้วย Bootloader androidboot.system.security_patch=2019-04-05
ข้อกำหนดเกี่ยวกับฮาร์ดแวร์
เมื่อเปิดใช้อินสแตนซ์ DSU ระบบจะจัดสรรไฟล์ชั่วคราว 2 ไฟล์ดังนี้
- พาร์ติชันเชิงตรรกะสำหรับจัดเก็บ
GSI.img(1~1.5 GB) - พาร์ติชัน
/dataว่างขนาด 8 GB เป็นแซนด์บ็อกซ์สำหรับเรียกใช้ GSI
เราขอแนะนำให้จองพื้นที่ว่างอย่างน้อย 10 GB ก่อนเปิดใช้อินสแตนซ์ DSU นอกจากนี้ DSU ยังรองรับการจัดสรรจากการ์ด SD ด้วย เมื่อมีการ์ด SD ระบบจะให้ความสำคัญกับการจัดสรรจากการ์ด SD เป็นอันดับแรก การรองรับการ์ด SD มีความสำคัญอย่างยิ่งสำหรับอุปกรณ์ที่มีกำลังไฟต่ำซึ่งอาจมีที่จัดเก็บข้อมูลภายในไม่เพียงพอ เมื่อมีการ์ด SD ให้ตรวจสอบว่าไม่ได้นำไปใช้เป็นพื้นที่เก็บข้อมูลภายใน DSU ไม่รองรับ การ์ด SD ที่นำไปใช้เป็นพื้นที่เก็บข้อมูลภายใน
ส่วนหน้าที่มี
คุณสามารถเปิดใช้ DSU ได้โดยใช้ adb, แอป OEM หรือตัวโหลด DSU แบบคลิกเดียว (ใน Android 11 ขึ้นไป)
เปิดใช้ DSU โดยใช้ adb
หากต้องการเปิดใช้ DSU โดยใช้ adb ให้ป้อนคำสั่งต่อไปนี้
$ simg2img out/target/product/.../system.img system.raw
$ gzip -c system.raw > system.raw.gz
$ adb push system.raw.gz /storage/emulated/0/Download
$ adb shell am start-activity \
-n com.android.dynsystem/com.android.dynsystem.VerificationActivity \
-a android.os.image.action.START_INSTALL \
-d file:///storage/emulated/0/Download/system.raw.gz \
--el KEY_SYSTEM_SIZE $(du -b system.raw|cut -f1) \
--el KEY_USERDATA_SIZE 8589934592
เปิดใช้ DSU โดยใช้แอป
จุดแรกเข้าหลักของ DSU คือ API android.os.image.DynamicSystemClient.java
public class DynamicSystemClient {
...
...
/**
* Start installing DynamicSystem from URL with default userdata size.
*
* @param systemUrl A network URL or a file URL to system image.
* @param systemSize size of system image.
*/
public void start(String systemUrl, long systemSize) {
start(systemUrl, systemSize, DEFAULT_USERDATA_SIZE);
}
คุณต้องรวม/ติดตั้งแอปนี้ไว้ล่วงหน้าในอุปกรณ์ เนื่องจาก DynamicSystemClient เป็นระบบ API คุณจึงสร้างแอปด้วย SDK API ปกติไม่ได้และเผยแพร่ใน Google Play ไม่ได้ วัตถุประสงค์ของแอปนี้คือ
- ดึงรายการอิมเมจและ URL ที่เกี่ยวข้องด้วยสคีมาที่กำหนดโดยผู้ให้บริการ
- จับคู่อิมเมจในรายการกับอุปกรณ์และแสดงอิมเมจที่เข้ากันได้เพื่อให้ผู้ใช้เลือก
เรียกใช้
DynamicSystemClient.startดังนี้DynamicSystemClient aot = new DynamicSystemClient(...) aot.start( ...URL of the selected image..., ...uncompressed size of the selected image...);
URL จะชี้ไปยังไฟล์อิมเมจระบบที่บีบอัดด้วย gzip และไม่ใช่แบบ Sparse ซึ่งคุณสร้างได้ด้วยคำสั่งต่อไปนี้
$ simg2img ${OUT}/system.img ${OUT}/system.raw
$ gzip ${OUT}/system.raw
$ ls ${OUT}/system.raw.gz
ชื่อไฟล์ควรเป็นไปตามรูปแบบต่อไปนี้
<android version>.<lunch name>.<user defined title>.raw.gz
ตัวอย่าง
o.aosp_taimen-userdebug.2018dev.raw.gzp.aosp_taimen-userdebug.2018dev.raw.gz
ตัวโหลด DSU แบบคลิกเดียว
Android 11 ขอแนะนำตัวโหลด DSU แบบคลิกเดียว ซึ่งเป็นส่วนหน้าในการตั้งค่าสำหรับนักพัฒนาแอป
รูปที่ 1 การเปิดใช้ตัวโหลด DSU
เมื่อนักพัฒนาแอปคลิกปุ่มตัวโหลด DSU ระบบจะดึงตัวอธิบาย DSU JSON ที่กำหนดค่าไว้ล่วงหน้าจากเว็บและแสดงอิมเมจที่เกี่ยวข้องทั้งหมดในเมนูแบบลอย เลือกอิมเมจเพื่อเริ่มการติดตั้ง DSU และความคืบหน้าจะแสดงในแถบการแจ้งเตือน
รูปที่ 2 ความคืบหน้าในการติดตั้งอิมเมจ DSU
โดยค่าเริ่มต้น ตัวโหลด DSU จะโหลดตัวอธิบาย JSON ที่มีอิมเมจ GSI ส่วนต่อไปนี้จะแสดงวิธีสร้างแพ็กเกจ DSU ที่ลงนามโดย OEM และโหลดแพ็กเกจเหล่านั้นจากตัวโหลด DSU
แฟล็กฟีเจอร์
ฟีเจอร์ DSU อยู่ภายใต้แฟล็กฟีเจอร์ settings_dynamic_android โปรดตรวจสอบว่าได้เปิดใช้แฟล็กฟีเจอร์ที่เกี่ยวข้องก่อนใช้ DSU
รูปที่ 3 การเปิดใช้แฟล็กฟีเจอร์
UI ของแฟล็กฟีเจอร์อาจไม่พร้อมใช้งานในอุปกรณ์ที่ใช้บิลด์ของผู้ใช้ ในกรณีนี้ ให้ใช้คำสั่ง adb แทน
$ adb shell setprop persist.sys.fflag.override.settings_dynamic_system 1
อิมเมจระบบโฮสต์ของผู้ให้บริการใน GCE (ไม่บังคับ)
ตำแหน่งที่เก็บข้อมูลที่เป็นไปได้ตำแหน่งหนึ่งสำหรับอิมเมจระบบคือ Bucket ของ Google Compute Engine (GCE) ผู้ดูแลระบบการเผยแพร่ใช้ คอนโซลพื้นที่เก็บข้อมูล GCP เพื่อ เพิ่ม/ลบ/เปลี่ยนแปลงอิมเมจระบบที่เผยแพร่
อิมเมจต้องเข้าถึงได้แบบสาธารณะ ดังที่แสดงไว้ที่นี่
รูปที่ 4 การเข้าถึงแบบสาธารณะใน GCE
ขั้นตอนในการทำให้รายการเป็นแบบสาธารณะมีอยู่ใน เอกสารประกอบของ Google Cloud
DSU หลายพาร์ติชันในไฟล์ ZIP
ตั้งแต่ Android 11 เป็นต้นไป DSU สามารถมีพาร์ติชันมากกว่า 1 พาร์ติชัน เช่น อาจมี product.img นอกเหนือจาก system.img เมื่ออุปกรณ์บูต init ระยะแรกจะตรวจหาพาร์ติชัน DSU ที่ติดตั้งและแทนที่พาร์ติชันในอุปกรณ์ชั่วคราวเมื่อเปิดใช้ DSU ที่ติดตั้ง แพ็กเกจ DSU อาจมีพาร์ติชันที่ไม่มีพาร์ติชันที่เกี่ยวข้องในอุปกรณ์
รูปที่ 5 กระบวนการ DSU ที่มีหลายพาร์ติชัน
DSU ที่ลงนามโดย OEM
เพื่อให้แน่ใจว่าผู้ผลิตอุปกรณ์อนุญาตอิมเมจทั้งหมดที่ทำงานในอุปกรณ์แล้ว อิมเมจทั้งหมดภายในแพ็กเกจ DSU ต้องลงนาม ตัวอย่างเช่น สมมติว่ามีแพ็กเกจ DSU ที่มีอิมเมจพาร์ติชัน 2 รายการดังนี้
dsu.zip {
- system.img
- product.img
}
ทั้ง system.img และ product.img ต้องลงนามด้วยคีย์ OEM ก่อนที่จะใส่ลงในไฟล์ ZIP แนวทางปฏิบัติทั่วไปคือการใช้อัลกอริทึมแบบอสมมาตร เช่น RSA ซึ่งใช้คีย์ลับในการลงนามในแพ็กเกจและใช้คีย์สาธารณะในการยืนยัน Ramdisk ระยะแรกต้องมีคีย์สาธารณะสำหรับการจับคู่ เช่น /avb/*.avbpubkey หากอุปกรณ์นำ AVB ไปใช้แล้ว ขั้นตอนการลงนามที่มีอยู่จะเพียงพอ ส่วนต่อไปนี้จะแสดงกระบวนการลงนามและไฮไลต์ตำแหน่งของ AVB Pubkey ที่ใช้ยืนยันอิมเมจในแพ็กเกจ DSU
ตัวอธิบาย DSU JSON
ตัวอธิบาย DSU JSON อธิบายแพ็กเกจ DSU โดยรองรับ 2 ค่าดั้งเดิม
ค่าดั้งเดิม include จะรวมตัวอธิบาย JSON เพิ่มเติมหรือเปลี่ยนเส้นทางตัวโหลด DSU ไปยังตำแหน่งใหม่ ตัวอย่าง
{
"include": ["https://.../gsi-release/gsi-src.json"]
}
ค่าดั้งเดิม image ใช้เพื่ออธิบายแพ็กเกจ DSU ที่เผยแพร่ ค่าดั้งเดิมของอิมเมจมีแอตทริบิวต์หลายรายการดังนี้
แอตทริบิวต์
nameและdetailsเป็นสตริงที่จะแสดงในกล่องโต้ตอบเพื่อให้ผู้ใช้เลือกแอตทริบิวต์
cpu_api,vndkและos_versionใช้สำหรับการตรวจสอบความเข้ากันได้ ซึ่งอธิบายไว้ในส่วนถัดไปแอตทริบิวต์
pubkeyที่ไม่บังคับจะอธิบายคีย์สาธารณะที่จับคู่กับคีย์ลับที่ใช้ลงนามในแพ็กเกจ DSU เมื่อระบุไว้ บริการ DSU จะตรวจสอบได้ว่าอุปกรณ์มีคีย์ที่ใช้ยืนยันแพ็กเกจ DSU หรือไม่ ซึ่งจะช่วยหลีกเลี่ยงการติดตั้งแพ็กเกจ DSU ที่ไม่รู้จัก เช่น การติดตั้ง DSU ที่ลงนามโดย OEM-A ในอุปกรณ์ที่ผลิตโดย OEM-Bแอตทริบิวต์
tosที่ไม่บังคับจะชี้ไปยังไฟล์ข้อความที่อธิบายข้อกำหนดในการให้บริการสำหรับแพ็กเกจ DSU ที่เกี่ยวข้อง เมื่อนักพัฒนาแอปเลือกแพ็กเกจ DSU ที่ระบุแอตทริบิวต์ข้อกำหนดในการให้บริการ กล่องโต้ตอบที่แสดงในรูปที่ 6 จะเปิดขึ้นเพื่อขอให้นักพัฒนาแอปยอมรับข้อกำหนดในการให้บริการก่อนที่จะติดตั้งแพ็กเกจ DSU
รูปที่ 6 กล่องโต้ตอบข้อกำหนดในการให้บริการ
ตัวอย่างตัวอธิบาย DSU JSON สำหรับ GSI
{
"images":[
{
"name":"GSI+GMS x86",
"os_version":"10",
"cpu_abi": "x86",
"details":"exp-QP1A.190711.020.C4-5928301",
"vndk":[
27,
28,
29
],
"pubkey":"",
"tos": "https://dl.google.com/developers/android/gsi/gsi-tos.txt",
"uri":"https://.../gsi/gsi_gms_x86-exp-QP1A.190711.020.C4-5928301.zip"
},
{
"name":"GSI+GMS ARM64",
"os_version":"10",
"cpu_abi": "arm64-v8a",
"details":"exp-QP1A.190711.020.C4-5928301",
"vndk":[
27,
28,
29
],
"pubkey":"",
"tos": "https://dl.google.com/developers/android/gsi/gsi-tos.txt",
"uri":"https://.../gsi/gsi_gms_arm64-exp-QP1A.190711.020.C4-5928301.zip"
},
{
"name":"GSI ARM64",
"os_version":"10",
"cpu_abi": "arm64-v8a",
"details":"exp-QP1A.190711.020.C4-5928301",
"vndk":[
27,
28,
29
],
"pubkey":"",
"uri":"https://.../gsi/aosp_arm64-exp-QP1A.190711.020.C4-5928301.zip"
},
{
"name":"GSI x86_64",
"os_version":"10",
"cpu_abi": "x86_64",
"details":"exp-QP1A.190711.020.C4-5928301",
"vndk":[
27,
28,
29
],
"pubkey":"",
"uri":"https://.../gsi/aosp_x86_64-exp-QP1A.190711.020.C4-5928301.zip"
}
]
}
การจัดการความเข้ากันได้
ระบบใช้แอตทริบิวต์หลายรายการเพื่อระบุความเข้ากันได้ระหว่างแพ็กเกจ DSU กับอุปกรณ์ในเครื่อง
cpu_apiเป็นสตริงที่อธิบายสถาปัตยกรรมของอุปกรณ์ แอตทริบิวต์นี้เป็นแอตทริบิวต์ที่ต้องระบุและจะเปรียบเทียบกับพร็อพเพอร์ตี้ระบบro.product.cpu.abiค่าของแอตทริบิวต์ทั้ง 2 รายการต้องตรงกันทุกประการos_versionเป็นจำนวนเต็มที่ไม่บังคับซึ่งระบุรุ่น Android เช่น สำหรับ Android 10os_versionคือ10และสำหรับ Android 11os_versionคือ11เมื่อระบุแอตทริบิวต์นี้ ค่าของแอตทริบิวต์ต้องเท่ากับหรือมากกว่าพร็อพเพอร์ตี้ระบบro.system.build.version.releaseการตรวจสอบนี้ใช้เพื่อป้องกันไม่ให้บูตอิมเมจ GSI ของ Android 10 ในอุปกรณ์ของผู้ให้บริการ Android 11 ซึ่งปัจจุบันไม่รองรับ แต่ระบบอนุญาตให้บูตอิมเมจ GSI ของ Android 11 ในอุปกรณ์ Android 10 ได้vndkเป็นอาร์เรย์ที่ไม่บังคับซึ่งระบุ VNDK ทั้งหมดที่รวมอยู่ในแพ็กเกจ DSU เมื่อระบุไว้ ตัวโหลด DSU จะตรวจสอบว่ามีการรวมตัวเลขที่แยกออกมาจากพร็อพเพอร์ตี้ระบบro.vndk.versionหรือไม่
เพิกถอนคีย์ DSU เพื่อความปลอดภัย
ในกรณีที่หายากมากที่คู่คีย์ RSA ที่ใช้ลงนามในอิมเมจ DSU ถูกบุกรุก คุณควรจะอัปเดต Ramdisk โดยเร็วที่สุดเพื่อนำคีย์ที่ถูกบุกรุกออก นอกเหนือจากการอัปเดตพาร์ติชันการบูตแล้ว คุณยังบล็อกคีย์ที่ถูกบุกรุกได้โดยใช้รายการเพิกถอนคีย์ DSU (บัญชีดำคีย์) จาก URL HTTPS
รายการเพิกถอนคีย์ DSU มีรายการคีย์สาธารณะ AVB ที่เพิกถอนแล้ว ระหว่างการติดตั้ง DSU ระบบจะตรวจสอบคีย์สาธารณะภายในอิมเมจ DSU กับรายการเพิกถอน หากพบว่าอิมเมจมีคีย์สาธารณะที่เพิกถอนแล้ว กระบวนการติดตั้ง DSU จะหยุดลง
URL รายการเพิกถอนคีย์ควรเป็น URL HTTPS เพื่อให้มั่นใจในความปลอดภัย และระบุไว้ในสตริงทรัพยากรดังนี้
frameworks/base/packages/DynamicSystemInstallationService/res/values/strings.xml@key_revocation_list_url
ค่าของสตริงคือ https://dl.google.com/developers/android/gsi/gsi-keyblacklist.json ซึ่งเป็นรายการเพิกถอนสำหรับคีย์ GSI ที่ Google เผยแพร่ คุณสามารถซ้อนทับและปรับแต่งสตริงทรัพยากรนี้ได้ เพื่อให้ OEM ที่ใช้ฟีเจอร์ DSU สามารถจัดหาและดูแลรักษาบัญชีดำคีย์ของตนเองได้ ซึ่งเป็นวิธีที่ OEM สามารถบล็อกคีย์สาธารณะบางรายการได้โดยไม่ต้องอัปเดตอิมเมจ Ramdisk ของอุปกรณ์
รูปแบบของรายการเพิกถอนมีดังนี้
{
"entries":[
{
"public_key":"bf14e439d1acf231095c4109f94f00fc473148e6",
"status":"REVOKED",
"reason":"Key revocation test key"
},
{
"public_key":"d199b2f29f3dc224cca778a7544ea89470cbef46",
"status":"REVOKED",
"reason":"Key revocation test key"
}
]
}
public_keyคือ SHA-1 Digest ของคีย์ที่เพิกถอนในรูปแบบที่อธิบายไว้ ในส่วนการสร้าง AVB Pubkeystatusระบุสถานะการเพิกถอนของคีย์ ปัจจุบันค่าที่รองรับมีเพียงREVOKEDreasonเป็นสตริงที่ไม่บังคับซึ่งอธิบายเหตุผลในการเพิกถอน
ขั้นตอน DSU
ส่วนนี้อธิบายวิธีดำเนินการตามขั้นตอนการกำหนดค่า DSU หลายขั้นตอน
สร้างคู่คีย์ใหม่
ใช้คำสั่ง openssl เพื่อสร้างคู่คีย์ส่วนตัว/สาธารณะ RSA ในรูปแบบ .pem (เช่น ขนาด 2048 บิต)
$ openssl genrsa -out oem_cert_pri.pem 2048
$ openssl rsa -in oem_cert_pri.pem -pubout -out oem_cert_pub.pem
คุณอาจเข้าถึงคีย์ส่วนตัวไม่ได้และระบบจะเก็บคีย์ส่วนตัวไว้ใน โมดูลความปลอดภัยฮาร์ดแวร์ (HSM) เท่านั้น ในกรณีนี้ อาจมีใบรับรองคีย์สาธารณะ x509 พร้อมใช้งานหลังจากสร้างคีย์ ดูวิธีการสร้างคีย์สาธารณะ AVB จากใบรับรอง x509 ได้ที่ส่วนการเพิ่ม Pubkey สำหรับการจับคู่ลงใน Ramdisk
วิธีแปลงใบรับรอง x509 เป็นรูปแบบ PEM
$ openssl x509 -pubkey -noout -in oem_cert_pub.x509.pem > oem_cert_pub.pem
ข้ามขั้นตอนนี้หากใบรับรองเป็นไฟล์ PEM อยู่แล้ว
เพิ่ม Pubkey สำหรับการจับคู่ลงใน Ramdisk
ต้องวาง oem_cert.avbpubkey ไว้ใต้ /avb/*.avbpubkey เพื่อยืนยันแพ็กเกจ DSU ที่ลงนาม ขั้นแรก ให้แปลงคีย์สาธารณะในรูปแบบ PEM เป็นรูปแบบคีย์สาธารณะ AVB ดังนี้
$ avbtool extract_public_key --key oem_cert_pub.pem --output oem_cert.avbpubkey
จากนั้นใส่คีย์สาธารณะลงใน Ramdisk ระยะแรกโดยทำตามขั้นตอนต่อไปนี้
เพิ่มโมดูลที่สร้างไว้ล่วงหน้าเพื่อคัดลอก
avbpubkeyเช่น เพิ่มdevice/<company>/<board>/oem_cert.avbpubkeyและdevice/<company>/<board>/avb/Android.mkที่มีเนื้อหาดังนี้include $(CLEAR_VARS) LOCAL_MODULE := oem_cert.avbpubkey LOCAL_MODULE_CLASS := ETC LOCAL_SRC_FILES := $(LOCAL_MODULE) ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true) LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/first_stage_ramdisk/avb else LOCAL_MODULE_PATH := $(TARGET_RAMDISK_OUT)/avb endif include $(BUILD_PREBUILT)ทำให้เป้าหมาย droidcore ขึ้นอยู่กับ
oem_cert.avbpubkeyที่เพิ่มเข้ามาdroidcore: oem_cert.avbpubkey
สร้างแอตทริบิวต์ AVB pubkey ในตัวอธิบาย JSON
oem_cert.avbpubkey อยู่ในรูปแบบไบนารีของคีย์สาธารณะ AVB ใช้ SHA-1 เพื่อให้อ่านได้ก่อนที่จะใส่ลงในตัวอธิบาย JSON ดังนี้
$ sha1sum oem_cert.avbpubkey | cut -f1 -d ' '
3e62f2be9d9d813ef5........866ac72a51fd20
ซึ่งจะเป็นเนื้อหาของแอตทริบิวต์ pubkey ของตัวอธิบาย JSON
"images":[
{
...
"pubkey":"3e62f2be9d9d813ef5........866ac72a51fd20",
...
},
ลงนามในแพ็กเกจ DSU
ใช้วิธีใดวิธีหนึ่งต่อไปนี้เพื่อลงนามในแพ็กเกจ DSU
วิธีที่ 1: ใช้ซ้ำอาร์ติแฟกต์ที่สร้างขึ้นโดยกระบวนการลงนาม AVB เดิมเพื่อสร้างแพ็กเกจ DSU อีกวิธีหนึ่งคือการแยกอิมเมจที่ลงนามแล้วออกจากแพ็กเกจที่เผยแพร่และใช้อิมเมจที่แยกออกมาเพื่อสร้างไฟล์ ZIP โดยตรง
วิธีที่ 2: ใช้คำสั่งต่อไปนี้เพื่อลงนามในพาร์ติชัน DSU หากมีคีย์ส่วนตัว ระบบจะลงนาม
imgแต่ละรายการภายในแพ็กเกจ DSU (ไฟล์ ZIP) แยกกัน$ key_len=$(openssl rsa -in oem_cert_pri.pem -text | grep Private-Key | sed -e 's/.*(\(.*\) bit.*/\1/') $ for partition in system product; do avbtool add_hashtree_footer \ --image ${OUT}/${partition}.img \ --partition_name ${partition} \ --algorithm SHA256_RSA${key_len} \ --key oem_cert_pri.pem done
ดูข้อมูลเพิ่มเติมเกี่ยวกับการเพิ่ม add_hashtree_footer โดยใช้ avbtool ได้ที่
การใช้ avbtool
ยืนยันแพ็กเกจ DSU ในเครื่อง
เราขอแนะนำให้ยืนยันอิมเมจในเครื่องทั้งหมดกับคีย์สาธารณะสำหรับการจับคู่ด้วยคำสั่งต่อไปนี้
for partition in system product; do
avbtool verify_image --image ${OUT}/${partition}.img --key oem_cert_pub.pem
done
เอาต์พุตที่คาดไว้จะมีลักษณะดังนี้
Verifying image dsu/system.img using key at oem_cert_pub.pem
vbmeta: Successfully verified footer and SHA256_RSA2048 vbmeta struct in dsu/system.img
: Successfully verified sha1 hashtree of dsu/system.img for image of 898494464 bytes
Verifying image dsu/product.img using key at oem_cert_pub.pem
vbmeta: Successfully verified footer and SHA256_RSA2048 vbmeta struct in dsu/product.img
: Successfully verified sha1 hashtree of dsu/product.img for image of 905830400 bytes
สร้างแพ็กเกจ DSU
ตัวอย่างต่อไปนี้สร้างแพ็กเกจ DSU ที่มี system.img และ product.img
dsu.zip {
- system.img
- product.img
}
หลังจากลงนามในอิมเมจทั้ง 2 รายการแล้ว ให้ใช้คำสั่งต่อไปนี้เพื่อสร้างไฟล์ ZIP
$ mkdir -p dsu
$ cp ${OUT}/system.img dsu
$ cp ${OUT}/product.img dsu
$ cd dsu && zip ../dsu.zip *.img && cd -
ปรับแต่ง DSU แบบคลิกเดียว
โดยค่าเริ่มต้น ตัวโหลด DSU จะชี้ไปยังข้อมูลเมตาของอิมเมจ GSI ซึ่งคือ https://...google.com/.../gsi-src.json
OEM สามารถเขียนทับรายการได้โดยกำหนดพร็อพเพอร์ตี้ persist.sys.fflag.override.settings_dynamic_system.list ที่ชี้ไปยังตัวอธิบาย JSON ของตนเอง ตัวอย่างเช่น OEM อาจให้ข้อมูลเมตา JSON ที่มีทั้ง GSI และอิมเมจที่เป็นกรรมสิทธิ์ของ OEM ดังนี้
{
"include": ["https://dl.google.com/.../gsi-src.JSON"]
"images":[
{
"name":"OEM image",
"os_version":"10",
"cpu_abi": "arm64-v8a",
"details":"...",
"vndk":[
27,
28,
29
],
"spl":"...",
"pubkey":"",
"uri":"https://.../....zip"
},
}
OEM สามารถเชื่อมโยงข้อมูลเมตา DSU ที่เผยแพร่แล้วได้ ดังที่แสดงในรูปที่ 7
รูปที่ 7 การเชื่อมโยงข้อมูลเมตา DSU ที่เผยแพร่แล้ว