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

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

कर्नेल से जुड़ी ज़रूरी शर्तें

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

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

  • CONFIG_DM_VERITY=y
  • CONFIG_DM_VERITY_FEC=y

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

Android 11 से, डीएसयू के लिए ज़रूरी है कि /data पार्टिशन, F2FS या ext4 फ़ाइल सिस्टम का इस्तेमाल करे. F2FS से बेहतर परफ़ॉर्मेंस मिलती है. इसलिए, इसका इस्तेमाल करने का सुझाव दिया जाता है. हालांकि, दोनों में ज़्यादा अंतर नहीं होता.

यहां कुछ उदाहरण दिए गए हैं कि Pixel डिवाइस पर डाइनैमिक सिस्टम अपडेट होने में कितना समय लगता है:

  • F2FS का इस्तेमाल करने पर:
    • 109 सेकंड, 8 जीबी उपयोगकर्ता, 867 एमबी सिस्टम, फ़ाइल सिस्टम का टाइप: F2FS: encryption=aes-256-xts:aes-256-cts
    • 104 सेकंड, 8 जीबी उपयोगकर्ता, 867 एमबी सिस्टम, फ़ाइल सिस्टम का टाइप: F2FS: encryption=ice
  • ext4 का इस्तेमाल करने पर:
    • 135 सेकंड, 8 जीबी उपयोगकर्ता, 867 एमबी सिस्टम, फ़ाइल सिस्टम का टाइप: ext4: encryption=aes-256-xts:aes-256-cts

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

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

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

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

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

Weaver HAL

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

Gatekeeper HAL

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

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

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

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

रोलबैक प्रोटेक्शन

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

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

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

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

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

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

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

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

adb का इस्तेमाल करके डीएसयू लॉन्च करना

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

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

डीएसयू का मुख्य एंट्री पॉइंट, 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...);
    
    

यूआरएल, 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

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

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

DSU लोडर लॉन्च किया जा रहा है

पहली इमेज. डीएसयू लोडर लॉन्च करना

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

DSU इमेज इंस्टॉल होने की प्रोसेस

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

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

फ़ीचर फ़्लैग

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

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

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

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

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

जीसीई पर वेंडर के होस्ट सिस्टम इमेज (ज़रूरी नहीं)

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

इमेज को सार्वजनिक तौर पर ऐक्सेस किया जा सकता है, जैसा कि यहां दिखाया गया है:

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

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

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

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

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

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

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

ओईएम के साइन किए गए डीएसयू

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

कुंजी को निरस्त करने की सूची का फ़ॉर्मैट यह है:

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

डीएसयू की प्रोसेस

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

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

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

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

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

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

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

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

रैमडिस्क में पेयरिंग pubkey जोड़ना

साइन किए गए डीएसयू पैकेज की पुष्टि करने के लिए, oem_cert.avbpubkey को /avb/*.avbpubkey में डालना ज़रूरी है. सबसे पहले, पीईएम फ़ॉर्मैट में मौजूद सार्वजनिक कुंजी को एवीबी की सार्वजनिक कुंजी के फ़ॉर्मैट में बदलें:

$ 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 डिस्क्रिप्टर में एवीबी pubkey एट्रिब्यूट जनरेट करना

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

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

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

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

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

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

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

  • दूसरा तरीका: अगर निजी कुंजी उपलब्ध है, तो डीएसयू पार्टिशन पर हस्ताक्षर करने के लिए, इन निर्देशों का इस्तेमाल करें. डीएसयू पैकेज (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 का इस्तेमाल करना लेख पढ़ें.

स्थानीय तौर पर डीएसयू पैकेज की पुष्टि करना

हमारा सुझाव है कि इन निर्देशों का इस्तेमाल करके, स्थानीय तौर पर मौजूद सभी इमेज की पुष्टि, पेयरिंग सार्वजनिक कुंजी से करें:


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 -

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

डिफ़ॉल्ट रूप से, डीएसयू लोडर, जीएसआई इमेज के मेटाडेटा की ओर ले जाता है. यह मेटाडेटा https://...google.com/.../gsi-src.json है.

ओईएम, persist.sys.fflag.override.settings_dynamic_system.list प्रॉपर्टी तय करके, सूची को बदल सकते हैं. यह प्रॉपर्टी, उनके JSON डिस्क्रिप्टर की ओर ले जाती है. उदाहरण के लिए, कोई ओईएम, JSON मेटाडेटा उपलब्ध करा सकता है. इसमें जीएसआई के साथ-साथ, ओईएम की मालिकाना हक वाली इमेज भी शामिल हो सकती हैं. जैसे:

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

}

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

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

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