डाइनैमिक सिस्टम अपडेट

डाइनैमिक सिस्टम अपडेट (डीएसयू) की मदद से, ऐसी Android सिस्टम इमेज बनाई जा सकती है जिसे उपयोगकर्ता इंटरनेट से डाउनलोड कर सकते हैं और मौजूदा सिस्टम इमेज को नुकसान पहुंचाए बिना आज़मा सकते हैं. इस दस्तावेज़ में, डीएसयू के साथ काम करने का तरीका बताया गया है.

Kernel से जुड़ी ज़रूरी शर्तें

कर्नेल की ज़रूरी शर्तों के बारे में जानने के लिए, डाइनैमिक पार्टीशन लागू करना लेख पढ़ें.

इसके अलावा, DSU, Android सिस्टम इमेज की पुष्टि करने के लिए, डिवाइस-मैपर-वैरिटी (dm-verity) कर्नेल की सुविधा पर निर्भर करता है. इसलिए, आपको ये कर्नेल कॉन्फ़िगरेशन चालू करने होंगे:

  • CONFIG_DM_VERITY=y
  • CONFIG_DM_VERITY_FEC=y

पार्टीशन से जुड़ी ज़रूरी शर्तें

Android 11 से, DSU के लिए ज़रूरी है कि /data partition, 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, फ़ाइल सिस्टम टाइप: ext4: encryption=aes-256-xts:aes-256-cts

अगर आपके प्लैटफ़ॉर्म पर इसमें ज़्यादा समय लगता है, तो यह देखें कि माउंट करने के लिए इस्तेमाल किए गए फ़्लैग में कोई ऐसा फ़्लैग तो नहीं है जो “sync” को लिखने की अनुमति देता है. इसके अलावा, बेहतर परफ़ॉर्मेंस पाने के लिए, “async” फ़्लैग का इस्तेमाल किया जा सकता है.

metadata पार्टीशन (16 एमबी या उससे ज़्यादा) ज़रूरी है, ताकि इंस्टॉल की गई इमेज से जुड़ा डेटा सेव किया जा सके. इसे पहले चरण के माउंट के दौरान माउंट किया जाना चाहिए.

userdata पार्टीशन में F2FS या ext4 फ़ाइल सिस्टम का इस्तेमाल किया जाना चाहिए. F2FS का इस्तेमाल करते समय, Android के सामान्य कर्नेल में उपलब्ध, F2FS से जुड़े सभी पैच शामिल करें.

DSU को kernel/common 4.9 के साथ डेवलप और टेस्ट किया गया था. हमारा सुझाव है कि इस सुविधा के लिए, kernel 4.9 और इसके बाद के वर्शन का इस्तेमाल करें.

वेंडर एचएएल का व्यवहार

Weaver HAL

weaver HAL, उपयोगकर्ता कुंजियों को सेव करने के लिए तय संख्या में स्लॉट उपलब्ध कराता है. डीएसयू के लिए, दो अतिरिक्त कुंजी स्लॉट का इस्तेमाल किया जाता है. अगर किसी OEM के पास weaver HAL है, तो उसके पास जेनरिक सिस्टम इमेज (जीएसआई) और होस्ट इमेज के लिए ज़रूरत के मुताबिक स्लॉट होने चाहिए.

Gatekeeper HAL

Gatekeeper HAL को बड़ी USER_ID वैल्यू के साथ काम करना चाहिए, क्योंकि GSI, HAL में UID को +1000000 से ऑफ़सेट करता है.

बूट की पुष्टि करना

अगर आपको पुष्टि किए गए बूट को बंद किए बिना, डेवलपर जीएसआई इमेज को लॉक की गई स्थिति में बूट करना है, तो device/<device_name>/device.mk फ़ाइल में यह लाइन जोड़कर, डेवलपर जीएसआई पासकोड शामिल करें:

$(call inherit-product, $(SRC_TARGET_DIR)/product/developer_gsi_keys.mk)

रोलबैक से सुरक्षा

DSU का इस्तेमाल करते समय, डाउनलोड की गई Android सिस्टम इमेज, डिवाइस पर मौजूद मौजूदा सिस्टम इमेज से नई होनी चाहिए. ऐसा करने के लिए, दोनों सिस्टम इमेज: Prop: com.android.build.system.security_patch -> '2019-04-05' के Android Verified Boot (AVB) के AVB प्रॉपर्टी डिस्क्रिप्टर में मौजूद, सुरक्षा पैच के लेवल की तुलना की जाती है.

जिन डिवाइसों में AVB का इस्तेमाल नहीं किया जा रहा है उनके लिए, मौजूदा सिस्टम इमेज के सुरक्षा पैच लेवल को कर्नेल cmdline या bootconfig में डालें. इसके लिए, बूटलोडर का इस्तेमाल करें: androidboot.system.security_patch=2019-04-05.

हार्डवेयर की ज़रूरी शर्तें

DSU इंस्टेंस लॉन्च करने पर, दो अस्थायी फ़ाइलें असाइन की जाती हैं:

  • GSI.img (1~1.5 G) को स्टोर करने के लिए लॉजिकल पार्टीशन
  • GSI को चलाने के लिए, सैंडबॉक्स के तौर पर 8 जीबी का खाली /data पार्टीशन

हमारा सुझाव है कि डीएसयू इंस्टेंस लॉन्च करने से पहले, कम से कम 10 जीबी खाली जगह सुरक्षित कर लें. डीएसयू, एसडी कार्ड से भी स्टोरेज को ऐलोकेट कर सकता है. अगर कोई एसडी कार्ड मौजूद है, तो उसे स्टोरेज के लिए सबसे ज़्यादा प्राथमिकता दी जाती है. कम क्षमता वाले डिवाइसों के लिए, एसडी कार्ड की सुविधा का होना ज़रूरी है. ऐसा इसलिए, क्योंकि इनमें शायद ज़रूरत के मुताबिक स्टोरेज न हो. अगर एसडी कार्ड मौजूद है, तो पक्का करें कि उसे फ़ोन के स्टोरेज के तौर पर इस्तेमाल न किया जा रहा हो. डीएसयू, अडॉप्ट किए गए एसडी कार्ड के साथ काम नहीं करता.

उपलब्ध फ़्रंटएंड

adb, OEM ऐप्लिकेशन या एक-क्लिक वाले DSU लोडर (Android 11 या इसके बाद के वर्शन में) का इस्तेमाल करके, DSU को लॉन्च किया जा सकता है.

adb का इस्तेमाल करके DSU लॉन्च करना

adb का इस्तेमाल करके DSU को लॉन्च करने के लिए, ये कमांड डालें:

$ 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

किसी ऐप्लिकेशन का इस्तेमाल करके डीएसयू लॉन्च करना

डीएसयू का मुख्य एंट्री पॉइंट, 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 एक सिस्टम एपीआई है. इसलिए, ऐप्लिकेशन को सामान्य एसडीके एपीआई की मदद से नहीं बनाया जा सकता. साथ ही, इसे Google Play पर पब्लिश नहीं किया जा सकता. इस ऐप्लिकेशन का मकसद है:

  1. वेंडर के तय किए गए स्कीम की मदद से, इमेज की सूची और उससे जुड़ा यूआरएल फ़ेच करें.
  2. सूची में मौजूद इमेज को डिवाइस के साथ मैच करें और उपयोगकर्ता को चुनने के लिए, काम करने वाली इमेज दिखाएं.
  3. DynamicSystemClient.start को इस तरह से शुरू करें:

    DynamicSystemClient aot = new DynamicSystemClient(...)
       aot.start(
            ...URL of the selected image...,
            ...uncompressed size of the selected image...);
    
    

यह यूआरएल, सिस्टम इमेज की ऐसी फ़ाइल पर ले जाता है जिसे ज़िप किया गया हो और जिसमें कोई स्पेस न हो. इस फ़ाइल को बनाने के लिए, ये निर्देश इस्तेमाल किए जा सकते हैं:

$ 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

एक-क्लिक वाला डीएसयू लोडर

Android 11 में, एक-क्लिक वाला डीएसयू लोडर उपलब्ध है. यह डेवलपर सेटिंग में एक फ़्रंटएंड है.

DSU लोडर लॉन्च करना

पहली इमेज. DSU लोडर लॉन्च करना

जब डेवलपर डीएसयू लोडर बटन पर क्लिक करता है, तो यह वेब से पहले से कॉन्फ़िगर किया गया डीएसयू JSON डिस्क्रिप्टर फ़ेच करता है. साथ ही, फ़्लोटिंग मेन्यू में लागू होने वाली सभी इमेज दिखाता है. डीएसयू इंस्टॉल करने के लिए कोई इमेज चुनें. इसके बाद, सूचना बार में प्रोग्रेस दिखेगी.

डीएसयू इमेज इंस्टॉल होने की प्रोग्रेस

दूसरी इमेज. डीएसयू इमेज इंस्टॉल होने की प्रोग्रेस

डिफ़ॉल्ट रूप से, DSU लोडर एक JSON डिस्क्रिप्टर लोड करता है, जिसमें जीएसआई इमेज होती हैं. नीचे दिए गए सेक्शन में, OEM से हस्ताक्षर किए गए DSU पैकेज बनाने और उन्हें DSU लोडर से लोड करने का तरीका बताया गया है.

फ़ीचर फ़्लैग

डीएसयू की सुविधा, settings_dynamic_android फ़ीचर फ़्लैग के तहत आती है. डीएसयू का इस्तेमाल करने से पहले, पक्का करें कि उससे जुड़ा सुविधा फ़्लैग चालू हो.

फ़ीचर फ़्लैग को चालू करना.

तीसरी इमेज. फ़ीचर फ़्लैग चालू करना

हो सकता है कि उपयोगकर्ता के बनाए गए बिल्ड वाले डिवाइस पर, फ़ीचर फ़्लैग का यूज़र इंटरफ़ेस (यूआई) उपलब्ध न हो. इस मामले में, इसके बजाय adb कमांड का इस्तेमाल करें:

$ adb shell setprop persist.sys.fflag.override.settings_dynamic_system 1

वेंडर, GCE पर सिस्टम इमेज होस्ट करता है (ज़रूरी नहीं)

सिस्टम इमेज को Google Compute Engine (GCE) बकेट में सेव किया जा सकता है. रिलीज़ एडमिन, रिलीज़ की गई सिस्टम इमेज को जोड़ने/मिटाने/बदलने के लिए, GCP स्टोरेज कंसोल का इस्तेमाल करता है.

इमेज ऐसी होनी चाहिए जिन्हें कोई भी ऐक्सेस कर सके, जैसा कि यहां दिखाया गया है:

GCE में सार्वजनिक ऐक्सेस

चौथी इमेज. GCE में सार्वजनिक ऐक्सेस

किसी आइटम को सार्वजनिक बनाने का तरीका, Google Cloud के दस्तावेज़ में उपलब्ध है.

ZIP फ़ाइल में कई-पार्टिशन वाला डीएसयू

Android 11 से, DSU में एक से ज़्यादा पार्टिशन हो सकते हैं. उदाहरण के लिए, इसमें system.img के अलावा product.img भी शामिल हो सकता है. जब डिवाइस बूट होता है, तो पहला चरण init, इंस्टॉल किए गए DSU के सेगमेंट का पता लगाता है. साथ ही, इंस्टॉल किए गए DSU के चालू होने पर, डिवाइस पर मौजूद सेगमेंट को कुछ समय के लिए बदल देता है. DSU पैकेज में ऐसा पार्टीशन हो सकता है जो डिवाइस पर मौजूद न हो.

एक से ज़्यादा पार्टीशन वाली डीएसयू प्रोसेस

पांचवीं इमेज. एक से ज़्यादा पार्टीशन वाली डीएसयू प्रोसेस

OEM के हस्ताक्षर वाला DSU

यह पक्का करने के लिए कि डिवाइस पर चल रही सभी इमेज, डिवाइस बनाने वाली कंपनी ने अनुमति दी है, DSU पैकेज में मौजूद सभी इमेज पर हस्ताक्षर होने चाहिए. उदाहरण के लिए, मान लें कि एक DSU पैकेज है, जिसमें दो पार्टीशन इमेज हैं, जैसे कि यहां दी गई इमेज:

dsu.zip {
    - system.img
    - product.img
}

system.img और product.img, दोनों को ZIP फ़ाइल में डालने से पहले OEM पासकोड से हस्ताक्षर करना ज़रूरी है. आम तौर पर, असिमेट्रिक एल्गोरिदम का इस्तेमाल किया जाता है. उदाहरण के लिए, आरएसए. इसमें पैकेज पर हस्ताक्षर करने के लिए सीक्रेट कुंजी का इस्तेमाल किया जाता है और उसकी पुष्टि करने के लिए सार्वजनिक कुंजी का इस्तेमाल किया जाता है. पहले चरण की रैम डिस्क में, /avb/*.avbpubkey जैसे पेयरिंग के लिए सार्वजनिक पासकोड शामिल होना चाहिए. अगर डिवाइस में पहले से ही एवीबी (ऑडियो वीडियो बुक) का इस्तेमाल किया जा रहा है, तो साइन करने की मौजूदा प्रोसेस ही काफ़ी होगी. नीचे दिए गए सेक्शन में, हस्ताक्षर करने की प्रोसेस के बारे में बताया गया है. साथ ही, AVB पब्लिक पासकोड की जगह को हाइलाइट किया गया है. इसका इस्तेमाल, डीएसयू पैकेज में मौजूद इमेज की पुष्टि करने के लिए किया जाता है.

डीएसयू का JSON डिस्क्रिप्टर

DSU JSON डिस्क्रिप्टर में, DSU पैकेज के बारे में बताया गया है. यह दो प्राइमिटिव के साथ काम करता है. सबसे पहले, include प्राइमिटिव में अतिरिक्त JSON डिस्क्रिप्टर शामिल होते हैं या DSU लोडर को किसी नई जगह पर रीडायरेक्ट करते हैं. उदाहरण के लिए:

{
    "include": ["https://.../gsi-release/gsi-src.json"]
}

दूसरा, रिलीज़ किए गए डीएसयू पैकेज के बारे में बताने के लिए, image प्राइमिटिव का इस्तेमाल किया जाता है. इमेज प्रिमटिव में कई एट्रिब्यूट होते हैं:

  • name और details एट्रिब्यूट, डायलॉग बॉक्स में दिखने वाली स्ट्रिंग होती हैं, ताकि उपयोगकर्ता उन्हें चुन सके.

  • cpu_api, vndk, और os_version एट्रिब्यूट का इस्तेमाल, काम करने की जांच के लिए किया जाता है. इस बारे में अगले सेक्शन में बताया गया है.

  • pubkey एट्रिब्यूट की वैल्यू, सार्वजनिक कुंजी के बारे में बताती है. यह कुंजी, उस गुप्त कुंजी के साथ जोड़ी जाती है जिसका इस्तेमाल डीएसयू पैकेज पर हस्ताक्षर करने के लिए किया जाता है. हालांकि, इस एट्रिब्यूट का इस्तेमाल करना ज़रूरी नहीं है. यह जानकारी देने पर, डीएसयू सेवा यह जांच कर सकती है कि डिवाइस में डीएसयू पैकेज की पुष्टि करने के लिए इस्तेमाल की जाने वाली कुंजी है या नहीं. इससे, किसी ऐसे डीएसयू पैकेज को इंस्टॉल करने से बचा जा सकता है जिसकी पुष्टि नहीं की गई है. उदाहरण के लिए, OEM-A के हस्ताक्षर वाला डीएसयू, OEM-B के बनाए गए डिवाइस पर इंस्टॉल करना.

  • tos एट्रिब्यूट (ज़रूरी नहीं) एक टेक्स्ट फ़ाइल पर ले जाता है. इसमें, उससे जुड़े डीएसयू पैकेज की सेवा की शर्तों के बारे में बताया गया होता है. जब कोई डेवलपर, सेवा की शर्तों के एट्रिब्यूट के साथ डीएसयू पैकेज चुनता है, तो फ़िगर 6 में दिखाया गया डायलॉग बॉक्स खुलता है. इसमें, डेवलपर से डीएसयू पैकेज इंस्टॉल करने से पहले, सेवा की शर्तों को स्वीकार करने के लिए कहा जाता है.

    सेवा की शर्तों वाला डायलॉग बॉक्स

    छठी इमेज. सेवा की शर्तों वाला डायलॉग बॉक्स

रेफ़रंस के लिए, यहां जीएसआई के लिए डीएसयू का JSON डिस्क्रिप्टर दिया गया है:

{
   "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"
      }
   ]
}

कंपैटिबिलिटी मैनेजमेंट

डीएसयू पैकेज और स्थानीय डिवाइस के बीच काम करने की जानकारी देने के लिए, कई एट्रिब्यूट का इस्तेमाल किया जाता है:

  • 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 11 वाले डिवाइस पर Android 10 GSI इमेज को बूट होने से रोकने के लिए किया जाता है. फ़िलहाल, यह सुविधा काम नहीं करती. Android 10 डिवाइस पर, Android 11 GSI इमेज को बूट करने की अनुमति है.

  • vndk एक वैकल्पिक कलेक्शन है, जिसमें DSU पैकेज में शामिल सभी VNDKs की जानकारी होती है. इसकी जानकारी देने पर, डीएसयू लोडर यह जांच करता है कि ro.vndk.version सिस्टम प्रॉपर्टी से निकाला गया नंबर शामिल है या नहीं.

सुरक्षा के लिए डीएसयू कुंजियों को रद्द करना

बहुत ही कम मामलों में, DSU इमेज पर हस्ताक्षर करने के लिए इस्तेमाल की गई RSA कुंजी के जोड़े का इस्तेमाल किया जाता है. अगर इस कुंजी के साथ छेड़छाड़ की जाती है, तो रैमडिस्क को जल्द से जल्द अपडेट किया जाना चाहिए, ताकि इस कुंजी को हटाया जा सके. बूट पार्टीशन को अपडेट करने के अलावा, एचटीटीपीएस यूआरएल से डीएसयू की कुंजी रद्द करने की सूची (कुंजी की ब्लैकलिस्ट) का इस्तेमाल करके, हैक की गई कुंजियों को ब्लॉक किया जा सकता है.

डीएसयू की कुंजी रद्द करने की सूची में, रद्द की गई AVB सार्वजनिक कुंजियों की सूची होती है. डीएसयू इंस्टॉल करने के दौरान, डीएसयू इमेज में मौजूद सार्वजनिक कुंजियों की पुष्टि, रद्द की गई कुंजियों की सूची के साथ की जाती है. अगर इमेज में रद्द की गई सार्वजनिक कुंजी मिलती है, तो डीएसयू इंस्टॉल करने की प्रोसेस रुक जाती है.

कुंजी रद्द करने की सूची का यूआरएल, एचटीटीपीएस यूआरएल होना चाहिए, ताकि सुरक्षा की पुष्टि की जा सके. साथ ही, यह रिसॉर्स स्ट्रिंग में दिया गया होना चाहिए:

frameworks/base/packages/DynamicSystemInstallationService/res/values/strings.xml@key_revocation_list_url

स्ट्रिंग की वैल्यू https://dl.google.com/developers/android/gsi/gsi-keyblacklist.json है. यह Google की ओर से जारी की गई जीएसआई पासकोड की रद्द की गई सूची है. इस संसाधन स्ट्रिंग को ओवरले किया जा सकता है और पसंद के मुताबिक बनाया जा सकता है, ताकि डीएसयू सुविधा का इस्तेमाल करने वाले OEM, अपनी कुंजी की ब्लैकलिस्ट उपलब्ध करा सकें और उसे मैनेज कर सकें. इससे OEM, डिवाइस की रैमडिस्क इमेज को अपडेट किए बिना, कुछ सार्वजनिक पासकोड को ब्लॉक कर सकता है.

रद्द करने की सूची का फ़ॉर्मैट यह है:

{
   "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 पब्लिक कुंजी जनरेट करना सेक्शन में बताए गए फ़ॉर्मैट में होता है.
  • status से, पासकोड रद्द करने की स्थिति का पता चलता है. फ़िलहाल, सिर्फ़ REVOKED वैल्यू का इस्तेमाल किया जा सकता है.
  • reason एक वैकल्पिक स्ट्रिंग है, जिसमें रद्द करने की वजह बताई गई है.

डीएसयू से जुड़ी प्रोसेस

इस सेक्शन में, डीएसयू कॉन्फ़िगरेशन के कई तरीकों के बारे में बताया गया है.

नया कुंजी जोड़ा जनरेट करना

.pem फ़ॉर्मैट में आरएसए निजी/सार्वजनिक कुंजी का जोड़ा जनरेट करने के लिए, openssl कमांड का इस्तेमाल करें. उदाहरण के लिए, 2048 बिट के साइज़ के साथ:

$ openssl genrsa -out oem_cert_pri.pem 2048
$ openssl rsa -in oem_cert_pri.pem -pubout -out oem_cert_pub.pem

ऐसा हो सकता है कि निजी कुंजी को ऐक्सेस न किया जा सके और उसे सिर्फ़ हार्डवेयर सुरक्षा मॉड्यूल (एचएसएम) में रखा गया हो. इस मामले में, कुंजी जनरेट करने के बाद, x509 सार्वजनिक पासकोड सर्टिफ़िकेट उपलब्ध हो सकता है. x509 सर्टिफ़िकेट से AVB की सार्वजनिक कुंजी जनरेट करने के निर्देशों के लिए, ramdisk में पेयरिंग पब्लिक कुंजी जोड़ना सेक्शन देखें.

x509 सर्टिफ़िकेट को PEM फ़ॉर्मैट में बदलने के लिए:

$ openssl x509 -pubkey -noout -in oem_cert_pub.x509.pem > oem_cert_pub.pem

अगर सर्टिफ़िकेट पहले से ही पीईएम फ़ाइल है, तो इस चरण को छोड़ दें.

RAM डिस्क में, पेयरिंग पब्लिक पासकोड जोड़ना

हस्ताक्षर किए गए डीएसयू पैकेज की पुष्टि करने के लिए, oem_cert.avbpubkey को /avb/*.avbpubkey में डालना होगा. सबसे पहले, सार्वजनिक कुंजी को 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)
    
  2. जोड़े गए oem_cert.avbpubkey के आधार पर, droidcore टारगेट बनाएं:

    droidcore: oem_cert.avbpubkey
    

JSON डिस्क्रिप्टर में AVB pubkey एट्रिब्यूट जनरेट करना

oem_cert.avbpubkey, AVB सार्वजनिक पासकोड बाइनरी फ़ॉर्मैट में है. इसे JSON डिस्क्रिप्टर में डालने से पहले, SHA-1 का इस्तेमाल करके इसे पढ़ने लायक बनाएं:

$ sha1sum oem_cert.avbpubkey | cut -f1 -d ' '
3e62f2be9d9d813ef5........866ac72a51fd20

यह JSON डिस्क्रिप्टर के pubkey एट्रिब्यूट का कॉन्टेंट होगा.

   "images":[
      {
         ...
         "pubkey":"3e62f2be9d9d813ef5........866ac72a51fd20",
         ...
      },

डीएसयू पैकेज पर हस्ताक्षर करना

डीएसयू पैकेज पर हस्ताक्षर करने के लिए, इनमें से कोई एक तरीका अपनाएं:

  • पहला तरीका: DSU पैकेज बनाने के लिए, एवीबी साइनिंग की मूल प्रोसेस से बनाए गए आर्टफ़ैक्ट का फिर से इस्तेमाल करें. इसके अलावा, रिलीज़ पैकेज से पहले से हस्ताक्षर की गई इमेज निकालकर, सीधे ZIP फ़ाइल बनाने के लिए उनका इस्तेमाल किया जा सकता है.

  • दूसरा तरीका: अगर निजी कुंजी उपलब्ध है, तो डीएसयू के पार्टीशन पर हस्ताक्षर करने के लिए, नीचे दिए गए निर्देशों का इस्तेमाल करें. DSU पैकेज (ZIP फ़ाइल) में मौजूद हर img पर अलग से हस्ताक्षर किया जाता है:

    $ 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
    

avbtool का इस्तेमाल करके add_hashtree_footer जोड़ने के बारे में ज़्यादा जानकारी के लिए, 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

डीएसयू पैकेज बनाना

यहां दिए गए उदाहरण में, ऐसा डीएसयू पैकेज बनाया गया है जिसमें 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 -

एक क्लिक वाले डीएसयू को पसंद के मुताबिक बनाना

डिफ़ॉल्ट रूप से, डीएसयू लोडर, 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"
      },

}

ओईएम, पब्लिश किए गए डीएसयू मेटाडेटा को चेन कर सकता है, जैसा कि सातवीं इमेज में दिखाया गया है.

पब्लिश किए गए डीएसयू मेटाडेटा को चेन करना

सातवीं इमेज. पब्लिश किए गए डीएसयू मेटाडेटा को चेन करना