อัปเดตระบบแบบไดนามิก

การอัปเดตระบบแบบไดนามิก (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 วินาที, ผู้ใช้ 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 ไม่ได้ วัตถุประสงค์ของแอปนี้คือ

  1. ดึงรายการอิมเมจและ URL ที่เกี่ยวข้องด้วยสคีมาที่กำหนดโดยผู้ให้บริการ
  2. จับคู่อิมเมจในรายการกับอุปกรณ์และแสดงอิมเมจที่เข้ากันได้เพื่อให้ผู้ใช้เลือก
  3. เรียกใช้ 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.gz
  • p.aosp_taimen-userdebug.2018dev.raw.gz

ตัวโหลด DSU แบบคลิกเดียว

Android 11 ขอแนะนำตัวโหลด DSU แบบคลิกเดียว ซึ่งเป็นส่วนหน้าในการตั้งค่าสำหรับนักพัฒนาแอป

เปิดใช้โปรแกรมโหลด DSU

รูปที่ 1 การเปิดใช้ตัวโหลด DSU

เมื่อนักพัฒนาแอปคลิกปุ่มตัวโหลด DSU ระบบจะดึงตัวอธิบาย DSU JSON ที่กำหนดค่าไว้ล่วงหน้าจากเว็บและแสดงอิมเมจที่เกี่ยวข้องทั้งหมดในเมนูแบบลอย เลือกอิมเมจเพื่อเริ่มการติดตั้ง DSU และความคืบหน้าจะแสดงในแถบการแจ้งเตือน

ความคืบหน้าในการติดตั้งอิมเมจ 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 เพื่อ เพิ่ม/ลบ/เปลี่ยนแปลงอิมเมจระบบที่เผยแพร่

อิมเมจต้องเข้าถึงได้แบบสาธารณะ ดังที่แสดงไว้ที่นี่

การเข้าถึงแบบสาธารณะใน GCE

รูปที่ 4 การเข้าถึงแบบสาธารณะใน GCE

ขั้นตอนในการทำให้รายการเป็นแบบสาธารณะมีอยู่ใน เอกสารประกอบของ Google Cloud

DSU หลายพาร์ติชันในไฟล์ ZIP

ตั้งแต่ Android 11 เป็นต้นไป DSU สามารถมีพาร์ติชันมากกว่า 1 พาร์ติชัน เช่น อาจมี product.img นอกเหนือจาก system.img เมื่ออุปกรณ์บูต init ระยะแรกจะตรวจหาพาร์ติชัน DSU ที่ติดตั้งและแทนที่พาร์ติชันในอุปกรณ์ชั่วคราวเมื่อเปิดใช้ 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 10 os_version คือ 10 และสำหรับ Android 11 os_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 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 พร้อมใช้งานหลังจากสร้างคีย์ ดูวิธีการสร้างคีย์สาธารณะ 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 ระยะแรกโดยทำตามขั้นตอนต่อไปนี้

  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)
    
  2. ทำให้เป้าหมาย 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

การเชื่อมโยงข้อมูลเมตา DSU ที่เผยแพร่

รูปที่ 7 การเชื่อมโยงข้อมูลเมตา DSU ที่เผยแพร่แล้ว