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

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

  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, ไม่ใช่แบบกระจัดกระจาย ซึ่งคุณสร้างได้ ด้วยคำสั่งต่อไปนี้

$ 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 Loader ระบบจะดึงข้อมูลตัวอธิบาย DSU JSON ที่กำหนดค่าไว้ล่วงหน้าจากเว็บและแสดงรูปภาพที่เกี่ยวข้องทั้งหมดในเมนูลอย เลือกรูปภาพเพื่อเริ่มการติดตั้ง DSU และความคืบหน้า จะแสดงในแถบการแจ้งเตือน

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

รูปภาพต้องเข้าถึงได้แบบสาธารณะ ดังที่แสดงที่นี่

การเข้าถึงแบบสาธารณะใน 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 ที่ใช้เพื่อยืนยันรูปภาพในแพ็กเกจ 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 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
  • 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 ได้ที่ส่วนการเพิ่มคีย์สาธารณะการจับคู่ลงใน 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 ของระยะแรกโดยทำตามขั้นตอนต่อไปนี้

  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 ในตัวอธิบาย 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 ที่เผยแพร่