Android 10 में, रूट फ़ाइल सिस्टम को अब ramdisk.img में शामिल नहीं किया जाता है. इसके बजाय, इसे system.img में मर्ज कर दिया जाता है. इसका मतलब है कि system.img हमेशा ऐसे बनाया जाता है जैसे कि BOARD_BUILD_SYSTEM_ROOT_IMAGE सेट किया गया हो. Android 10 वर्शन के साथ लॉन्च होने वाले डिवाइसों के लिए:
- सिस्टम-एज़-रूट पार्टीशन लेआउट का इस्तेमाल करें. यह लेआउट, बिल्ड के साथ अपने-आप लागू होता है. इसके व्यवहार में बदलाव करने का कोई विकल्प नहीं होता.
- ramdisk का इस्तेमाल करना ज़रूरी है, जो dm-linear के लिए ज़रूरी है.
BOARD_BUILD_SYSTEM_ROOT_IMAGEकोfalseपर सेट करना ज़रूरी है. इस सेटिंग का इस्तेमाल सिर्फ़ उन डिवाइसों के बीच अंतर करने के लिए किया जाता है जो रैमडिस्क का इस्तेमाल करते हैं और जो रैमडिस्क का इस्तेमाल नहीं करते हैं. इसके बजाय, वे सीधे तौर परsystem.imgको माउंट करते हैं.
सिस्टम-ऐज़-रूट कॉन्फ़िगरेशन का मतलब, Android 9 और Android 10 में अलग-अलग होता है. Android 9 के सिस्टम-ऐज़-रूट कॉन्फ़िगरेशन में, BOARD_BUILD_SYSTEM_ROOT_IMAGE को true पर सेट किया जाता है. इससे बिल्ड को रूट फ़ाइल सिस्टम को system.img में मर्ज करना पड़ता है. इसके बाद, system.img को रूट फ़ाइल सिस्टम (rootfs) के तौर पर माउंट करना पड़ता है. Android 9 के साथ लॉन्च किए गए डिवाइसों के लिए, यह कॉन्फ़िगरेशन ज़रूरी है. हालांकि, Android 9 पर अपग्रेड करने वाले डिवाइसों और Android के पुराने वर्शन पर चलने वाले डिवाइसों के लिए, यह ज़रूरी नहीं है. Android 10 के सिस्टम-ऐज़-रूट कॉन्फ़िगरेशन में, बिल्ड हमेशा $TARGET_SYSTEM_OUT और $TARGET_ROOT_OUT को system.img में मर्ज करता है. यह कॉन्फ़िगरेशन, Android 10 पर काम करने वाले सभी डिवाइसों के लिए डिफ़ॉल्ट व्यवहार है.
Android 10 में, डाइनैमिक पार्टीशन की सुविधा को बेहतर बनाया गया है. यह एक यूज़रस्पेस पार्टीशनिंग सिस्टम है. इसकी मदद से, ओवर-द-एयर (OTA) अपडेट किए जा सकते हैं. साथ ही, पार्टीशन बनाए जा सकते हैं, उनका साइज़ बदला जा सकता है या उन्हें मिटाया जा सकता है. इस बदलाव के तहत, Linux कर्नल अब Android 10 चलाने वाले डिवाइसों पर लॉजिकल सिस्टम पार्टीशन को माउंट नहीं कर सकता. इसलिए, इस ऑपरेशन को पहले चरण के init से मैनेज किया जाता है.
यहां दिए गए सेक्शन में, सिर्फ़ सिस्टम के ओटीए के लिए सिस्टम-ऐज़-रूट की ज़रूरी शर्तों के बारे में बताया गया है. साथ ही, डिवाइसों को सिस्टम-ऐज़-रूट का इस्तेमाल करने के लिए अपडेट करने के बारे में दिशा-निर्देश दिए गए हैं. इनमें, पार्टीशन लेआउट में बदलाव और dm-verity कर्नल की ज़रूरी शर्तें शामिल हैं. रैमडिस्क में हुए बदलावों के बारे में जानने के लिए, रैमडिस्क पार्टिशन देखें.
सिर्फ़ सिस्टम के लिए ओटीए के बारे में जानकारी
सिर्फ़ सिस्टम के लिए उपलब्ध ओटीए अपडेट की मदद से, Android के रिलीज़ किए गए वर्शन को अपडेट किया जा सकता है. system.img और product.img को अपडेट करने के लिए, अन्य पार्टीशन में बदलाव करने की ज़रूरत नहीं होती. इसके लिए, सिस्टम-ऐज़-रूट पार्टीशन लेआउट की ज़रूरत होती है. Android 10 पर काम करने वाले सभी डिवाइसों को, सिस्टम-ऐज़-रूट पार्टीशन लेआउट का इस्तेमाल करना होगा, ताकि सिर्फ़ सिस्टम से जुड़े ओटीए अपडेट चालू किए जा सकें.
- A/B डिवाइस,
systemपार्टीशन को rootfs के तौर पर माउंट करते हैं. ये डिवाइस पहले से ही सिस्टम-ऐज़-रूट का इस्तेमाल करते हैं. इसलिए, सिस्टम ओटीए को सपोर्ट करने के लिए, इनमें बदलाव करने की ज़रूरत नहीं होती. - नॉन-A/B डिवाइस,
systemपार्टिशन को/systemपर माउंट करते हैं. सिस्टम ओटीए को सपोर्ट करने के लिए, उन्हें सिस्टम-ऐज़-रूट पार्टिशन लेआउट का इस्तेमाल करने के लिए अपडेट करना होगा.
A/B और नॉन-A/B डिवाइसों के बारे में ज़्यादा जानने के लिए, A/B (बिना रुकावट) सिस्टम अपडेट लेख पढ़ें.
वेंडर ओवरले का इस्तेमाल करना (<=AOSP 14)
वेंडर ओवरले की मदद से, डिवाइस बूट होने के समय vendor
पार्टिशन में बदलाव किए जा सकते हैं. वेंडर ओवरले, product पार्टीशन में वेंडर मॉड्यूल का एक सेट होता है. डिवाइस बूट होने पर, ये मॉड्यूल vendor पार्टीशन पर ओवरले हो जाते हैं. इससे मौजूदा मॉड्यूल बदल जाते हैं और नए मॉड्यूल जुड़ जाते हैं.
जब डिवाइस बूट होता है, तो init प्रोसेस, पहले चरण का माउंट पूरा करती है और डिफ़ॉल्ट प्रॉपर्टी पढ़ती है. इसके बाद, यह हर सबडायरेक्ट्री को खोजता है
/product/vendor_overlay/<target_vendor_version> और उसे उसके vendor पार्टीशन डायरेक्ट्री में माउंट करता है. हालांकि, ऐसा तब ही होता है, जब ये शर्तें पूरी होती हैं:
/vendor/<overlay_dir>मौजूद है./product/vendor_overlay/<target_vendor_version>/<overlay_dir>में वही फ़ाइल कॉन्टेक्स्ट है जो/vendor/<overlay_dir>में है.initको/vendor/<overlay_dir>के फ़ाइल कॉन्टेक्स्ट पर माउंट करने की अनुमति है.
वेंडर ओवरले लागू करना
/product/vendor_overlay/<target_vendor_version> में वेंडर ओवरले फ़ाइलें इंस्टॉल करें. डिवाइस बूट होने पर, ये फ़ाइलें vendor पार्टीशन पर ओवरले हो जाती हैं. इससे एक ही नाम वाली फ़ाइलें बदल जाती हैं और नई फ़ाइलें जुड़ जाती हैं. वेंडर ओवरले, vendor पार्टीशन से फ़ाइलें नहीं हटा सकता.
वेंडर ओवरले फ़ाइलों का फ़ाइल कॉन्टेक्स्ट, उन टारगेट फ़ाइलों के जैसा होना चाहिए जिन्हें वे vendor पार्टीशन में बदलती हैं. डिफ़ॉल्ट रूप से, /product/vendor_overlay/<target_vendor_version> डायरेक्ट्री में मौजूद फ़ाइलों का कॉन्टेक्स्ट vendor_file होता है. अगर वेंडर ओवरले फ़ाइलों और उनकी जगह इस्तेमाल की जाने वाली फ़ाइलों के फ़ाइल कॉन्टेक्स्ट में अंतर है, तो डिवाइस के हिसाब से sepolicy में इसकी जानकारी दें. फ़ाइल का कॉन्टेक्स्ट, डायरेक्ट्री लेवल पर सेट किया जाता है. अगर किसी वेंडर ओवरले डायरेक्ट्री का फ़ाइल कॉन्टेक्स्ट, टारगेट डायरेक्ट्री से मेल नहीं खाता है और डिवाइस के हिसाब से सेपॉलिसी में सही फ़ाइल कॉन्टेक्स्ट नहीं दिया गया है, तो उस वेंडर ओवरले डायरेक्ट्री को टारगेट डायरेक्ट्री पर ओवरले नहीं किया जाता.
वेंडर ओवरले का इस्तेमाल करने के लिए, कर्नल को CONFIG_OVERLAY_FS=y सेट करके OverlayFS को चालू करना होगा. साथ ही, कर्नल को सामान्य कर्नल 4.4 या इसके बाद के वर्शन से मर्ज किया जाना चाहिए या "overlayfs:
override_creds=off option bypass creator_cred" के साथ पैच किया जाना चाहिए.
वेंडर ओवरले लागू करने का उदाहरण
इस तरीके में, वेंडर ओवरले लागू करने का तरीका बताया गया है. यह ओवरले, /vendor/lib/*, /vendor/etc/*, और /vendor/app/* डायरेक्ट्री पर ओवरले होता है.
-
device/<vendor>/<target>/vendor_overlay/<target_vendor_version>/में पहले से बनी वेंडर फ़ाइलें जोड़ें:device/google/device/vendor_overlay/28/lib/libfoo.so device/google/device/vendor_overlay/28/lib/libbar.so device/google/device/vendor_overlay/28/etc/baz.xml device/google/device/vendor_overlay/28/app/qux.apk
-
प्रीबिल्ट वेंडर फ़ाइलों को
device/google/device/device.mkमेंproduct/vendor_overlayपर इंस्टॉल करें:PRODUCT_COPY_FILES += \ $(call find-copy-subdir-files,*,device/google/device/vendor_overlay,$(TARGET_COPY_OUT_PRODUCT)/vendor_overlay)
-
अगर टारगेट
vendorपार्टीशन फ़ाइलों मेंvendor_fileके अलावा अन्य कॉन्टेक्स्ट हैं, तो फ़ाइल के कॉन्टेक्स्ट तय करें./vendor/lib/*,vendor_fileकॉन्टेक्स्ट का इस्तेमाल करता है. इसलिए, इस उदाहरण में उस डायरेक्ट्री को शामिल नहीं किया गया है.device/google/device-sepolicy/private/file_contextsमें यह जोड़ें:/(product|system/product)/vendor_overlay/[0-9]+/etc(/.*)? u:object_r:vendor_configs_file:s0 /(product|system/product)/vendor_overlay/[0-9]+/app(/.*)? u:object_r:vendor_app_file:s0
-
initप्रोसेस को,vendor_fileके अलावा अन्य फ़ाइल कॉन्टेक्स्ट पर वेंडर ओवरले को माउंट करने की अनुमति दें.initकॉन्टेक्स्ट पर पहले से ही माउंट करने की अनुमति होने की वजह से, इस उदाहरण मेंvendor_fileके लिए नीति तय नहीं की गई है.vendor_filedevice/google/device-sepolicy/public/init.teमें यह जोड़ें:allow init vendor_configs_file:dir mounton; allow init vendor_app_file:dir mounton;
वेंडर के ओवरले की पुष्टि करना
वेंडर ओवरले कॉन्फ़िगरेशन की पुष्टि करने के लिए, /product/vendor_overlay/<target_vendor_version>/<overlay_dir> में फ़ाइलें जोड़ें. इसके बाद, देखें कि क्या फ़ाइलें, /vendor/<overlay_dir> में मौजूद फ़ाइलों पर ओवरले की गई हैं.
userdebug बिल्ड के लिए, Atest का एक टेस्ट मॉड्यूल होता है:
$ atest -v fs_mgr_vendor_overlay_test
सिस्टम-ऐज़-रूट में अपडेट करना
सिस्टम-ऐज़-रूट का इस्तेमाल करने के लिए, नॉन-ए/बी डिवाइसों को अपडेट करना होगा. इसके लिए, आपको boot.img और system.img के लिए पार्टीशनिंग स्कीम अपडेट करनी होगी, dm-verity सेट अप करना होगा, और डिवाइस के हिसाब से रूट फ़ोल्डर पर बूट करने से जुड़ी सभी डिपेंडेंसी हटानी होंगी.
पार्टिशन अपडेट करना
A/B डिवाइसों में /boot को रिकवरी पार्टिशन के तौर पर इस्तेमाल किया जाता है. हालांकि, नॉन-A/B डिवाइसों में /recovery पार्टिशन को अलग रखना ज़रूरी है, क्योंकि इनमें फ़ॉलबैक स्लॉट पार्टिशन नहीं होता (उदाहरण के लिए, boot_a से boot_b). अगर नॉन-A/B डिवाइस से /recovery को हटा दिया जाता है और इसे A/B स्कीम की तरह बना दिया जाता है, तो /boot पार्टिशन को अपडेट करने के दौरान रिकवरी मोड काम नहीं करेगा. इस वजह से, नॉन-A/B डिवाइसों के लिए, /recovery पार्टिशन को /boot से अलग पार्टिशन होना ज़रूरी है. इसका मतलब है कि रिकवरी इमेज को अपडेट करने का तरीका वही रहेगा जो Android 8.1.0 या इससे पहले के वर्शन वाले डिवाइसों में इस्तेमाल किया जाता है.
यहां दी गई टेबल में, Android 9 से पहले और बाद में, नॉन-A/B डिवाइसों के लिए इमेज पार्टीशन के अंतर के बारे में बताया गया है.
| इमेज | रैमडिस्क (Android 9 से पहले) | सिस्टम-ऐज़-रूट (Android 9 के बाद) |
|---|---|---|
boot.img |
इसमें कर्नेल और ramdisk.img शामिल है:
ramdisk.img
-/
- init.rc
- init
- etc -> /system/etc
- system/ (mount point)
- vendor/ (mount point)
- odm/ (mount point)
... |
इसमें सिर्फ़ सामान्य बूट कर्नल होता है. |
recovery.img |
इसमें रिकवरी कर्नल और रिकवरी ramdisk.img शामिल है. |
|
system.img |
इसमें ये शामिल हैं:
system.img
-/
- bin/
- etc
- vendor -> /vendor
- ... |
इसमें ओरिजनल system.img और ramdisk.img का मर्ज किया गया कॉन्टेंट शामिल है:
system.img
-/
- init.rc
- init
- etc -> /system/etc
- system/
- bin/
- etc/
- vendor -> /vendor
- ...
- vendor/ (mount point)
- odm/ (mount point)
... |
पार्टिशन में कोई बदलाव नहीं होता है. ramdisk और system-as-root, दोनों में ही इस पार्टीशन स्कीम का इस्तेमाल किया जाता है:
/boot/system/system/recovery/vendorवगैरह
dm-verity सेट अप करना
सिस्टम-ऐज़-रूट में, कर्नल को system.img को / (माउंट पॉइंट) के नीचे dm-verity के साथ माउंट करना होगा. AOSP, system.img के लिए dm-verity की इन सुविधाओं के साथ काम करता है.
vboot 1.0
vboot 1.0 के लिए, कर्नल को /system पर मौजूद Android के हिसाब से मेटाडेटा को पार्स करना होगा. इसके बाद, dm-verity को सेट अप करने के लिए, इसे dm-verity पैरामीटर में बदलना होगा. इसके लिए, इन कर्नल पैच की ज़रूरत होती है.
नीचे दिए गए उदाहरण में, कर्नल कमांड लाइन में सिस्टम-ऐज़-रूट के लिए dm-verity से जुड़ी सेटिंग दिखाई गई हैं:
ro root=/dev/dm-0 rootwait skip_initramfs init=/init dm="system none ro,0 1 android-verity /dev/sda34" veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f
vboot 2.0
vboot 2.0 (AVB) के लिए, बूटलोडर को external/avb/libavb को इंटिग्रेट करना होगा. इसके बाद, यह /system के लिए हैशट्री डिस्क्रिप्टर को पार्स करता है और इसे dm-verity पैरामीटर में बदलता है. आखिर में, यह पैरामीटर को कर्नल कमांड लाइन के ज़रिए कर्नल को पास करता है. (/system के हैशट्री डिस्क्रिप्टर, /vbmeta पर या /system पर ही हो सकते हैं.)
vboot 2.0 के लिए, कर्नल के इन पैच की ज़रूरत होती है:
- https://android-review.googlesource.com/#/c/kernel/common/+/158491/
- कर्नेल 4.4 पैच, कर्नेल 4.9 पैच वगैरह.
नीचे दिए गए उदाहरण में, कर्नल कमांड लाइन में सिस्टम-ऐज़-रूट के लिए dm-verity से जुड़ी सेटिंग दिखाई गई हैं:
ro root=/dev/dm-0 rootwait skip_initramfs init=/init dm="1 vroot none ro 1,0 5159992 verity 1 PARTUUID=00000016-0000-0000-0000-000000000000 PARTUUID=00000016-0000-0000-0000-000000000000 4096 4096 644999 644999 sha1 d80b4a8be3b58a8ab86fad1b498640892d4843a2 8d08feed2f55c418fb63447fec0d32b1b107e42c 10 restart_on_corruption ignore_zero_blocks use_fec_from_device PARTUUID=00000016-0000-0000-0000-000000000000 fec_roots 2 fec_blocks 650080 fec_start 650080"
डिवाइस के हिसाब से रूट फ़ोल्डर इस्तेमाल करना
सिस्टम-ऐज़-रूट के साथ, डिवाइस पर सामान्य सिस्टम इमेज (जीएसआई) फ़्लैश होने के बाद (और Vendor Test Suite टेस्ट चलाने से पहले), BOARD_ROOT_EXTRA_FOLDERS के साथ जोड़े गए डिवाइस के हिसाब से रूट फ़ोल्डर हट जाते हैं. ऐसा इसलिए होता है, क्योंकि पूरी रूट डायरेक्ट्री के कॉन्टेंट को सिस्टम-ऐज़-रूट जीएसआई से बदल दिया जाता है. इन फ़ोल्डर को हटाने से, डिवाइस बूट नहीं हो पाएगा. ऐसा तब होगा, जब डिवाइस के हिसाब से रूट फ़ोल्डर पर कोई निर्भरता मौजूद हो. उदाहरण के लिए, उन्हें माउंट पॉइंट के तौर पर इस्तेमाल किया जाता है.
इस समस्या से बचने के लिए, डिवाइस के हिसाब से रूट फ़ोल्डर जोड़ने के लिए BOARD_ROOT_EXTRA_FOLDERS का इस्तेमाल न करें. अगर आपको डिवाइस के हिसाब से माउंट पॉइंट तय करने हैं, तो /mnt/vendor/<mount point> का इस्तेमाल करें. इसे इन बदलावों की सूची में जोड़ा गया है. वेंडर के हिसाब से तय किए गए इन माउंट पॉइंट को सीधे तौर पर fstab डिवाइस ट्री (पहले चरण के माउंट के लिए) और /vendor/etc/fstab.{ro.hardware} फ़ाइल, दोनों में तय किया जा सकता है. इसके लिए, किसी अतिरिक्त सेटअप की ज़रूरत नहीं होती. ऐसा इसलिए, क्योंकि fs_mgr इन्हें /mnt/vendor/* के तहत अपने-आप बना देता है.