การอัปเดตระบบแบบไดนามิก (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
- 109 วินาที ผู้ใช้ 8G ระบบ 867M ประเภทระบบไฟล์: F2FS: encryption=aes-256-xts:aes-256-cts
- 104s, ผู้ใช้ 8G, ระบบ 867M, ประเภทระบบไฟล์: F2FS: encrypted=ice
- การใช้ ext4
- 135 วินาที ผู้ใช้ 8 GB ระบบ 867 MB ประเภทระบบไฟล์: ext4: encryption=aes-256-xts:aes-256-cts
หากใช้เวลานานกว่ามากในแพลตฟอร์มของคุณ คุณอาจต้องตรวจสอบว่า Flag การต่อเชื่อมมี Flag ที่ทำให้การเขียน "sync" หรือไม่ หรือจะระบุ Flag "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 สำหรับที่เรามีอยู่ ก็จำเป็นต้องมีช่องที่เพียงพอสำหรับอิมเมจระบบทั่วไป (GSI) และอิมเมจโฮสต์
HAL ของ Gatekeeper
HAL ของ Gatekeeper ต้องรองรับค่า USER_ID
ขนาดใหญ่ เนื่องจาก GSI จะเลื่อน UID ไปยัง HAL เพิ่มขึ้น 1000000
ยืนยันการเปิดเครื่อง
หากต้องการรองรับการบูตภาพ GSI ของนักพัฒนาแอปในสถานะล็อกโดยไม่ปิดใช้การบูตที่ยืนยันแล้ว ให้ใส่คีย์ 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 ให้วางระดับแพตช์ความปลอดภัยของอิมเมจระบบปัจจุบันใน kernel 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 ไว้ ให้ตรวจสอบว่าไม่ได้ใช้การ์ดดังกล่าว 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
แฟล็กฟีเจอร์
ฟีเจอร์ DSU อยู่ภายใต้ Flag ฟีเจอร์ settings_dynamic_android
ก่อนใช้ DSU โปรดตรวจสอบว่าได้เปิดใช้ Flag ฟีเจอร์ที่เกี่ยวข้องแล้ว
รูปที่ 3 การเปิดใช้ Flag ฟีเจอร์
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 โดยรองรับ Primitive 2 รายการ
ประการแรก ค่าดั้งเดิม include
มีข้อบ่งชี้ JSON เพิ่มเติมหรือการเปลี่ยนเส้นทางตัวโหลด DSU ไปยังตำแหน่งใหม่ เช่น
{
"include": ["https://.../gsi-release/gsi-src.json"]
}
ประการที่ 2 คือ รายการพื้นฐาน 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
ค่าของช่องต้องตรงกันทุกประการ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 10vndk
เป็นอาร์เรย์ที่ไม่บังคับที่ระบุ VNDK ทั้งหมดที่รวมอยู่ในแพ็กเกจ DSU เมื่อระบุไว้ ตัวโหลด DSU จะตรวจสอบว่าหมายเลขที่ดึงมาจากพร็อพเพอร์ตี้ระบบro.vndk.version
รวมอยู่ไหม
เพิกถอนคีย์ DSU เพื่อความปลอดภัย
ในกรณีที่เกิดขึ้นได้ยากมากเมื่อคู่คีย์ RSA ที่ใช้ลงนามในภาพ DSU มีการประนีประนอม คุณควรอัปเดต RAM Disk โดยเร็วที่สุดเพื่อนำคีย์ที่มีการประนีประนอมออก นอกจากการอัปเดตพาร์ติชันการเปิดเครื่องแล้ว ยังบล็อกคีย์ที่ถูกบุกรุกโดยใช้รายการยกเลิกคีย์ DSU (รายการคีย์ที่ไม่อนุญาต) จาก HTTPS URL ได้ด้วย
รายการเพิกถอนคีย์ 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 ของคีย์ที่เพิกถอนในรูปแบบที่อธิบายไว้ในส่วนการสร้าง AVB pubkeystatus
ระบุสถานะการเพิกถอนของคีย์ ปัจจุบันค่าที่รองรับเพียงค่าเดียวคือ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
จากนั้นใส่คีย์สาธารณะในแรมดิสก์ระยะที่ 1 โดยทำตามขั้นตอนต่อไปนี้
เพิ่มโมดูลที่สร้างไว้ล่วงหน้าเพื่อคัดลอก
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 ที่เผยแพร่