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

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

  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

แฟล็กฟีเจอร์

ฟีเจอร์ DSU อยู่ภายใต้ Flag ฟีเจอร์ settings_dynamic_android ก่อนใช้ DSU โปรดตรวจสอบว่าได้เปิดใช้ Flag ฟีเจอร์ที่เกี่ยวข้องแล้ว

การเปิดใช้ Flag ฟีเจอร์

รูปที่ 3 การเปิดใช้ Flag ฟีเจอร์

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

  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 ที่เผยแพร่