การอัปเดตระบบแบบไดนามิก (DSU) ช่วยให้คุณสร้างอิมเมจระบบ Android ที่ผู้ใช้สามารถดาวน์โหลดได้จากอินเทอร์เน็ต และทดลองใช้โดยไม่มีความเสี่ยงที่จะทำให้อิมเมจระบบปัจจุบันเสียหาย เอกสารนี้จะอธิบายวิธีการสนับสนุน DSU
ข้อกำหนดเคอร์เนล
ดู การใช้พาร์ติชันแบบไดนามิก สำหรับข้อกำหนดเคอร์เนล
นอกจากนี้ DSU ยังใช้ฟีเจอร์เคอร์เนลอุปกรณ์ 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, ระบบ 867M, ประเภทระบบไฟล์: F2FS: การเข้ารหัส=aes-256-xts:aes-256-cts
- 104s, ผู้ใช้ 8G, ระบบ 867M, ประเภทระบบไฟล์: F2FS: การเข้ารหัส=ice
- ใช้ ext4:
- 135s, ผู้ใช้ 8G, ระบบ 867M, ประเภทระบบไฟล์: ext4: การเข้ารหัส=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 มีจำนวนช่องคงที่สำหรับจัดเก็บคีย์ผู้ใช้ DSU ใช้ช่องกุญแจพิเศษสองช่อง หาก OEM มีช่างประกอบ HAL ก็จะต้องมีสล็อตเพียงพอสำหรับอิมเมจระบบทั่วไป (GSI) และอิมเมจโฮสต์
ผู้รักษาประตู HAL
Gatekeeper HAL จำเป็นต้องรองรับค่า USER_ID
ที่มีขนาดใหญ่ เนื่องจาก GSI ออฟเซ็ต UIDs เป็น HAL +1000000
ตรวจสอบการบูต
หากคุณต้องการสนับสนุนการบูต อิมเมจ GSI ของนักพัฒนา ใน สถานะ LOCKED โดยไม่ต้องปิดใช้งานการบูตที่ได้รับการยืนยัน ให้รวมคีย์ Developer GSI โดยเพิ่มบรรทัดต่อไปนี้ลงในไฟล์ device/<device_name>/device.mk
:
$(call inherit-product, $(SRC_TARGET_DIR)/product/developer_gsi_keys.mk)
การป้องกันการย้อนกลับ
เมื่อใช้ DSU อิมเมจระบบ Android ที่ดาวน์โหลดจะต้องใหม่กว่าอิมเมจระบบปัจจุบันบนอุปกรณ์ ซึ่งทำได้โดยการเปรียบเทียบระดับแพตช์ความปลอดภัยใน ตัวอธิบายคุณสมบัติ AVB ของ Android Verified Boot (AVB) ของอิมเมจระบบทั้งสอง: Prop: com.android.build.system.security_patch -> '2019-04-05'
สำหรับอุปกรณ์ที่ไม่ได้ใช้ AVB ให้ใส่ระดับแพตช์ความปลอดภัยของอิมเมจระบบปัจจุบันลงในเคอร์เนล cmdline หรือ bootconfig ด้วย bootloader: androidboot.system.security_patch=2019-04-05
ข้อกำหนดด้านฮาร์ดแวร์
เมื่อคุณเปิดใช้งานอินสแตนซ์ DSU ไฟล์ชั่วคราวสองไฟล์จะถูกจัดสรร:
- โลจิคัลพาร์ติชันสำหรับจัดเก็บ
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 ชี้ไปที่ไฟล์อิมเมจระบบ gzipped ที่ไม่กระจัดกระจาย ซึ่งคุณสามารถสร้างได้ด้วยคำสั่งต่อไปนี้:
$ 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 อยู่ภายใต้การตั้งค่าสถานะคุณลักษณะ 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 สามารถมีได้มากกว่าหนึ่งพาร์ติชัน ตัวอย่างเช่น สามารถมี 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 รองรับสองพื้นฐาน ขั้นแรก 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
ค่าของพวกเขาจะต้องตรงกันทุกประการos_version
เป็นจำนวนเต็มทางเลือกที่ระบุรุ่น Android ตัวอย่างเช่น สำหรับ Android 10,os_version
คือ10
และสำหรับ Android 11,os_version
คือ11
เมื่อระบุแอ็ตทริบิวต์นี้ จะต้องเท่ากับหรือมากกว่าคุณสมบัติระบบro.system.build.version.release
การตรวจสอบนี้ใช้ป้องกันการบูตอิมเมจ Android 10 GSI บนอุปกรณ์ของผู้จำหน่าย Android 11 ซึ่งยังไม่รองรับในขณะนี้ อนุญาตให้บูตอิมเมจ Android 11 GSI บนอุปกรณ์ Android 10 ได้vndk
เป็นอาร์เรย์ทางเลือกที่ระบุ VNDK ทั้งหมดที่รวมอยู่ในแพ็คเกจ DSU เมื่อมีการระบุ ตัวโหลด DSU จะตรวจสอบว่าหมายเลขที่ดึงมาจากคุณสมบัติระบบro.vndk.version
รวมอยู่ด้วยหรือไม่
เพิกถอนคีย์ DSU เพื่อความปลอดภัย
ในกรณีที่เกิดขึ้นไม่บ่อยนักเมื่อคู่คีย์ RSA ที่ใช้ในการลงนามอิมเมจ DSU ถูกบุกรุก ควรอัปเดต ramdisk โดยเร็วที่สุดเพื่อลบคีย์ที่ถูกบุกรุกออก นอกเหนือจากการอัปเดตพาร์ติชันสำหรับเริ่มระบบแล้ว คุณยังสามารถบล็อกคีย์ที่ถูกบุกรุกได้โดยใช้รายการเพิกถอนคีย์ DSU (บัญชีดำของคีย์) จาก HTTPS URL
รายการเพิกถอนคีย์ DSU ประกอบด้วยรายการคีย์สาธารณะ AVB ที่ถูกเพิกถอน ในระหว่างการติดตั้ง DSU คีย์สาธารณะภายในอิมเมจ DSU จะได้รับการตรวจสอบกับรายการเพิกถอน หากพบว่ารูปภาพมีคีย์สาธารณะที่ถูกเพิกถอน กระบวนการติดตั้ง DSU จะหยุดลง
URL รายการเพิกถอนคีย์ควรเป็น HTTPS URL เพื่อรับรองความปลอดภัย และระบุไว้ในสตริงทรัพยากร:
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 pubkey -
status
ระบุสถานะการเพิกถอนคีย์ ปัจจุบัน ค่าที่รองรับเพียงค่าเดียวคือ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 ที่พร้อมใช้งานหลังจากการสร้างคีย์ ดูส่วน การเพิ่ม pubkey การจับคู่ลงใน ramdisk สำหรับคำแนะนำในการสร้างคีย์สาธารณะ AVB จากใบรับรอง x509
หากต้องการแปลงใบรับรอง 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
}
หลังจากเซ็นชื่อรูปภาพทั้งสองแล้ว ให้ใช้คำสั่งต่อไปนี้เพื่อสร้างไฟล์ 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 ที่เผยแพร่