การอัปเดตระบบแบบไดนามิก (DSU) ช่วยให้คุณสร้างอิมเมจระบบ Android ที่ผู้ใช้สามารถดาวน์โหลดจากอินเทอร์เน็ตและทดลองใช้ได้โดยไม่ต้องเสี่ยงต่อการทำให้อิมเมจระบบปัจจุบันเสียหาย เอกสารนี้อธิบายวิธีรองรับ DSU
ข้อกำหนดของเคอร์เนล
ดูข้อกำหนดของเคอร์เนลได้ที่ การใช้พาร์ติชันแบบไดนามิก
นอกจากนี้ DSU ยังอาศัยฟีเจอร์เคอร์เนล device-mapper-verity (dm-verity) เพื่อยืนยันอิมเมจระบบ Android ดังนั้นคุณต้องเปิดใช้การกำหนดค่าเคอร์เนลต่อไปนี้
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
ข้อกำหนดของพาร์ติชัน
ตั้งแต่ Android 11 เป็นต้นไป DSU กำหนดให้/data
พาร์ติชันต้องใช้ระบบไฟล์ F2FS หรือ ext4 F2FS ให้ประสิทธิภาพที่ดีกว่าและ
ขอแนะนำให้ใช้ แต่ความแตกต่างไม่ควรมีนัยสำคัญ
ตัวอย่างระยะเวลาที่การอัปเดตระบบแบบไดนามิกใช้กับอุปกรณ์ Pixel มีดังนี้
- การใช้ F2FS
- 109s, 8G user, 867M system, file system type: F2FS: encryption=aes-256-xts:aes-256-cts
- 104s, 8G user, 867M system, file system type: F2FS: encryption=ice
- การใช้ ext4
- 135s, 8G user, 867M system, file system type: ext4: encryption=aes-256-xts:aes-256-cts
หากแพลตฟอร์มของคุณใช้เวลานานกว่านี้มาก คุณอาจต้องตรวจสอบว่าแฟล็กการเมานต์มีแฟล็กที่ทำให้เกิดการเขียน "sync" หรือไม่ หรือคุณจะระบุแฟล็ก "async" อย่างชัดเจนเพื่อให้ได้ประสิทธิภาพที่ดีขึ้นก็ได้
ต้องมีพาร์ติชัน metadata
(16 MB ขึ้นไป) เพื่อจัดเก็บข้อมูลที่เกี่ยวข้อง
กับรูปภาพที่ติดตั้ง ต้องติดตั้งในระหว่างการติดตั้งในระยะแรก
พาร์ติชัน userdata
ต้องใช้ระบบไฟล์ F2FS หรือ ext4 เมื่อใช้ F2FS
ให้รวมแพตช์ที่เกี่ยวข้องกับ F2FS ทั้งหมดที่มีอยู่ในเคอร์เนลทั่วไปของ Android
DSU ได้รับการพัฒนาและทดสอบด้วยเคอร์เนล/common 4.9 เราขอแนะนำให้ใช้ เคอร์เนล 4.9 ขึ้นไปสำหรับฟีเจอร์นี้
ลักษณะการทำงานของ HAL ของผู้ให้บริการ
HAL ของ Weaver
HAL ของ Weaver มีช่องจำนวนคงที่สำหรับจัดเก็บคีย์ของผู้ใช้ DSU ใช้ช่องคีย์เพิ่มเติม 2 ช่อง หาก OEM มี HAL ของ Weaver จะต้องมี สล็อตเพียงพอสำหรับอิมเมจระบบทั่วไป (GSI) และอิมเมจโฮสต์
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 ที่ดาวน์โหลดจะต้องใหม่กว่า
รูปภาพระบบปัจจุบันในอุปกรณ์ โดยจะเปรียบเทียบระดับแพตช์ความปลอดภัยใน
การบูตที่ยืนยันแล้วของ 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 G) - พาร์ติชัน
/data
ขนาด 8 GB ที่ว่างเปล่าเป็นแซนด์บ็อกซ์สำหรับเรียกใช้ GSI
เราขอแนะนำให้จองพื้นที่ว่างอย่างน้อย 10 GB ก่อนเปิดตัวอินสแตนซ์ DSU DSU ยังรองรับการจัดสรรจากการ์ด SD ด้วย เมื่อมีการ์ด 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 คือ android.os.image.DynamicSystemClient.java
API
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, ไม่ใช่แบบกระจัดกระจาย ซึ่งคุณสร้างได้ ด้วยคำสั่งต่อไปนี้
$ 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.gz
p.aosp_taimen-userdebug.2018dev.raw.gz
โปรแกรมโหลด DSU แบบคลิกเดียว
Android 11 ขอแนะนำโปรแกรมโหลด DSU แบบคลิกเดียว ซึ่ง เป็นส่วนหน้าในการตั้งค่านักพัฒนาแอป
รูปที่ 1 เปิดใช้โปรแกรมโหลด DSU
เมื่อนักพัฒนาแอปคลิกปุ่ม DSU Loader ระบบจะดึงข้อมูลตัวอธิบาย DSU JSON ที่กำหนดค่าไว้ล่วงหน้าจากเว็บและแสดงรูปภาพที่เกี่ยวข้องทั้งหมดในเมนูลอย เลือกรูปภาพเพื่อเริ่มการติดตั้ง DSU และความคืบหน้า จะแสดงในแถบการแจ้งเตือน
รูปที่ 2 ความคืบหน้าในการติดตั้งอิมเมจ DSU
โดยค่าเริ่มต้น โปรแกรมโหลด DSU จะโหลดตัวอธิบาย JSON ที่มีรูปภาพ GSI ส่วนต่อไปนี้แสดงวิธีสร้างแพ็กเกจ DSU ที่ลงนามโดย OEM และโหลด จากโปรแกรมโหลด DSU
Feature Flag
ฟีเจอร์ DSU อยู่ภายใต้settings_dynamic_android
แฟล็กฟีเจอร์ ก่อน
ใช้ DSU ให้ตรวจสอบว่าได้เปิดใช้ฟีเจอร์แฟล็กที่เกี่ยวข้องแล้ว
รูปที่ 3 การเปิดใช้ฟีเจอร์แฟล็ก
UI ของฟีเจอร์แฟล็กอาจไม่พร้อมใช้งานในอุปกรณ์ที่ใช้บิลด์ของผู้ใช้ ใน
กรณีนี้ ให้ใช้คำสั่ง adb
แทน
$ adb shell setprop persist.sys.fflag.override.settings_dynamic_system 1
ผู้ให้บริการโฮสต์อิมเมจระบบใน GCE (ไม่บังคับ)
ที่เก็บข้อมูลที่เป็นไปได้สำหรับอิมเมจระบบคือที่เก็บข้อมูล 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 ที่ใช้เพื่อยืนยันรูปภาพในแพ็กเกจ DSU
ตัวอธิบาย JSON ของ DSU
ตัวอธิบาย JSON ของ DSU จะอธิบายแพ็กเกจ DSU โดยรองรับ 2 องค์ประกอบพื้นฐาน
ประการแรก include
Primitive มีตัวอธิบาย JSON เพิ่มเติมหรือเปลี่ยนเส้นทาง
โปรแกรมโหลด DSU ไปยังตำแหน่งใหม่ เช่น
{
"include": ["https://.../gsi-release/gsi-src.json"]
}
ประการที่ 2 ใช้ Primitive 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 กล่องโต้ตอบข้อกำหนดในการให้บริการ
โปรดดูตัวอย่างตัวอธิบาย JSON ของ DSU สำหรับ 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 ของคีย์ที่ถูกเพิกถอนในรูปแบบที่อธิบายไว้ ในส่วนการสร้างคีย์สาธารณะ AVBstatus
ระบุสถานะการเพิกถอนของคีย์ ปัจจุบันค่าที่รองรับมีเพียงREVOKED
reason
เป็นสตริงที่ไม่บังคับซึ่งอธิบายเหตุผลในการเพิกถอน
ขั้นตอน 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 ได้ที่ส่วนการเพิ่มคีย์สาธารณะการจับคู่ลงใน ramdisk
วิธีแปลงใบรับรอง x509 เป็นรูปแบบ PEM
$ openssl x509 -pubkey -noout -in oem_cert_pub.x509.pem > oem_cert_pub.pem
ข้ามขั้นตอนนี้หากใบรับรองเป็นไฟล์ PEM อยู่แล้ว
เพิ่มคีย์สาธารณะสำหรับการจับคู่ลงใน 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 ในตัวอธิบาย 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 ที่เผยแพร่