การอัปเดตระบบแบบไดนามิก (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
- 104 วินาที ผู้ใช้ 8G ระบบ 867M ประเภทระบบไฟล์: F2FS: encryption=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 ได้รับการพัฒนาและทดสอบด้วยเคอร์เนล/คอมมอน 4.9 เราขอแนะนำให้ใช้เคอร์เนล 4.9 ขึ้นไปสำหรับฟีเจอร์นี้
ลักษณะการทํางานของ HAL ของผู้ให้บริการ
Weaver HAL
HAL ของ Weaver มีจำนวนช่องคงที่สำหรับจัดเก็บคีย์ของผู้ใช้ DSU จะกินพื้นที่สล็อตกุญแจเพิ่มอีก 2 ช่อง หาก OEM มี HAL ของ Weaver จะต้องมีช่องเพียงพอสำหรับภาพระบบทั่วไป (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 ให้ใส่ระดับแพตช์ด้านความปลอดภัยของภาพระบบปัจจุบันลงใน 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
ระยะที่ 1 จะตรวจหาพาร์ติชัน DSU ที่ติดตั้งไว้และแทนที่พาร์ติชันในอุปกรณ์ชั่วคราวเมื่อเปิดใช้ DSU ที่ติดตั้งไว้ แพ็กเกจ DSU อาจมีพาร์ติชันที่ไม่มีพาร์ติชันที่สอดคล้องกันในอุปกรณ์
รูปที่ 5 กระบวนการ DSU ที่มีหลายพาร์ติชัน
DSU ที่ OEM ลงนาม
รูปภาพทั้งหมดในแพ็กเกจ DSU ต้องได้รับการเซ็นชื่อเพื่อให้มั่นใจว่ารูปภาพทั้งหมดที่ทำงานในอุปกรณ์ได้รับอนุญาตจากผู้ผลิตอุปกรณ์ ตัวอย่างเช่น สมมติว่ามีแพ็กเกจ DSU ที่มีภาพพาร์ติชัน 2 ภาพดังด้านล่าง
dsu.zip {
- system.img
- product.img
}
ทั้ง system.img
และ product.img
ต้องได้รับการรับรองโดยคีย์ OEM ก่อนที่จะใส่ลงในไฟล์ ZIP แนวทางปฏิบัติทั่วไปคือการใช้อัลกอริทึมแบบไม่สมมาตร เช่น RSA ซึ่งจะใช้คีย์ลับในการลงนามในแพ็กเกจ และใช้คีย์สาธารณะเพื่อตรวจสอบ แรมดิสก์ระยะที่ 1 ต้องมีคู่จับคู่
คีย์สาธารณะ เช่น /avb/*.avbpubkey
หากอุปกรณ์ใช้ AVB อยู่แล้ว ขั้นตอนการลงนามที่มีอยู่ก็เพียงพอแล้ว ส่วนต่อไปนี้แสดงภาพขั้นตอนการลงนามและไฮไลต์ตำแหน่งของคีย์สาธารณะ AVB ที่ใช้เพื่อยืนยันรูปภาพในแพ็กเกจ DSU
ข้อบ่งชี้ JSON ของ DSU
ตัวบ่งชี้ JSON ของ DSU จะอธิบายแพ็กเกจ DSU โดยรองรับ Primitive 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 กล่องโต้ตอบข้อกำหนดในการให้บริการ
ต่อไปนี้คือตัวบ่งชี้ 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
ค่าของช่องต้องตรงกันทุกประการos_version
เป็นจํานวนเต็มที่ไม่บังคับซึ่งระบุรุ่น Android ตัวอย่างเช่นos_version
สำหรับ Android 10 คือ10
และos_version
สำหรับ Android 11 คือ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 (รายการที่อนุญาตคีย์) จาก 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 ของคีย์ที่ถูกเพิกถอนในรูปแบบที่อธิบายไว้ในส่วนการสร้างคีย์สาธารณะ 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
จากนั้นใส่คีย์สาธารณะในแรมดิสก์ระยะที่ 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 ในข้อบ่งชี้ 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 ที่เผยแพร่