Android 10 में, रूट फ़ाइल सिस्टम को अब ramdisk.img
में शामिल नहीं किया गया है. इसके बजाय, इसे system.img
में मर्ज कर दिया गया है. इसका मतलब है कि system.img
हमेशा वैसे ही बनता है जैसे BOARD_BUILD_SYSTEM_ROOT_IMAGE
सेट होने पर बनता है. Android 10 के साथ लॉन्च होने वाले डिवाइस:
- सिस्टम-as-root पार्टीशन लेआउट का इस्तेमाल करें. इसे बिल्ड अपने-आप लागू करता है और इसके व्यवहार में बदलाव करने का कोई विकल्प नहीं होता.
- रैमडिस्क का इस्तेमाल करना ज़रूरी है, जो 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 के सिस्टम-as-रूट कॉन्फ़िगरेशन में, बिल्ड हमेशा $TARGET_SYSTEM_OUT
और $TARGET_ROOT_OUT
को system.img
में मर्ज करता है. यह कॉन्फ़िगरेशन, Android 10 पर चलने वाले सभी डिवाइसों के लिए डिफ़ॉल्ट तौर पर काम करता है.
Android 10 में, डाइनैमिक पार्टीशन के साथ काम करने के लिए और बदलाव किए गए हैं. यह एक यूज़रस्पेस पार्टीशन सिस्टम है, जो ओवर-द-एयर (ओटीए) अपडेट की मदद से, पार्टीशन बनाने, उनका साइज़ बदलने या उन्हें मिटाने की सुविधा देता है. इस बदलाव के तहत, Linux kernel अब Android 10 पर चलने वाले डिवाइसों पर लॉजिकल सिस्टम पार्टीशन को माउंट नहीं कर सकता. इसलिए, यह कार्रवाई पहले चरण के init से मैनेज की जाती है.
नीचे दिए गए सेक्शन में, सिर्फ़ सिस्टम के लिए उपलब्ध ओटीए के लिए, सिस्टम को रूट के तौर पर इस्तेमाल करने की ज़रूरी शर्तों के बारे में बताया गया है. साथ ही, डिवाइसों को सिस्टम को रूट के तौर पर इस्तेमाल करने के लिए अपडेट करने के बारे में दिशा-निर्देश दिए गए हैं. इनमें, पार्टीशन लेआउट में हुए बदलाव और dm-verity कर्नेल की ज़रूरी शर्तें शामिल हैं. रैमडिस में हुए बदलावों के बारे में जानकारी पाने के लिए, रैमडिस के सेगमेंट देखें.
सिर्फ़ सिस्टम के लिए उपलब्ध OTA के बारे में जानकारी
सिर्फ़ सिस्टम के लिए उपलब्ध ओटीए के लिए, सिस्टम के तौर पर रूट सेक्शन का लेआउट ज़रूरी होता है. इससे Android रिलीज़, दूसरे सेक्शन में बदलाव किए बिना system.img
और product.img
को अपडेट कर पाती हैं. Android 10 पर काम करने वाले सभी डिवाइसों को, सिर्फ़ सिस्टम के लिए ओटीए चालू करने के लिए, सिस्टम के तौर पर रूट पार्टीशन लेआउट का इस्तेमाल करना होगा.
system
पार्टीशन को rootfs के तौर पर माउंट करने वाले A/B डिवाइस, पहले से ही सिस्टम-as-root का इस्तेमाल करते हैं. साथ ही, सिस्टम के ओटीए के साथ काम करने के लिए, इनमें बदलाव करने की ज़रूरत नहीं होती.- ऐसे नॉन-A/B डिवाइसों को अपडेट करना ज़रूरी है, ताकि वे सिस्टम के तौर पर रूट वाले पार्टिशन लेआउट का इस्तेमाल कर सकें. इससे, सिस्टम के लिए ओटीए अपडेट काम कर पाएंगे.
system
/system
A/B और A/B के अलावा अन्य डिवाइसों के बारे में जानकारी के लिए, A/B (सीमलेस) सिस्टम अपडेट देखें.
वेंडर ओवरले का इस्तेमाल करना (<=AOSP 14)
वेंडर ओवरले की मदद से, डिवाइस के बूट होने के समय vendor
partition में बदलाव किए जा सकते हैं. वेंडर ओवरले, product
partition में मौजूद वेंडर मॉड्यूल का एक सेट होता है. डिवाइस के बूट होने पर, यह vendor
partition पर ओवरले हो जाता है. साथ ही, यह मौजूदा मॉड्यूल को बदल देता है और उनमें नए मॉड्यूल जोड़ देता है.
डिवाइस के बूट होने पर, 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
कॉन्टेक्स्ट होता है. अगर वेंडर की ओवरले फ़ाइलों और उन फ़ाइलों के बीच फ़ाइल कॉन्टेक्स्ट मेल नहीं खाते जिनकी जगह वे लेती हैं, तो डिवाइस के हिसाब से बनी सुरक्षा नीति में इसकी जानकारी दें. फ़ाइल का कॉन्टेक्स्ट, डायरेक्ट्री लेवल पर सेट किया जाता है. अगर किसी वेंडर ओवरले डायरेक्ट्री का फ़ाइल कॉन्टेक्स्ट, टारगेट डायरेक्ट्री से मेल नहीं खाता और डिवाइस के हिसाब से बनी सुरक्षा नीति में सही फ़ाइल कॉन्टेक्स्ट नहीं बताया गया है, तो उस वेंडर ओवरले डायरेक्ट्री को टारगेट डायरेक्ट्री पर ओवरले नहीं किया जाता.
वेंडर ओवरले का इस्तेमाल करने के लिए, कर्नेल को 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_file
के लिए नीति के बारे में नहीं बताया गया है.device/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
'सिस्टम के तौर पर रूट' पर अपडेट करना
A/B फ़ॉर्मैट वाले डिवाइसों के बजाय, अन्य डिवाइसों पर सिस्टम को रूट के तौर पर इस्तेमाल करने के लिए, आपको 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 डिवाइसों के मुकाबले, अन्य डिवाइसों के लिए इमेज के बंटवारे के अंतर की जानकारी दी गई है.
इमेज | Ramdisk (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) ... |
हालांकि, पार्टीशन में कोई बदलाव नहीं होता. रामडिस्क और सिस्टम-ऐज़-रूट, दोनों ही इस पैटर्न का इस्तेमाल करते हैं:
/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 पैरामीटर में बदलना होगा. इसके लिए, इन कर्नेल पैच की ज़रूरत होगी.
यहां दिए गए उदाहरण में, kernel कमांड लाइन में, सिस्टम-as-root के लिए 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/
- kernel 4.4 पैच, kernel 4.9 पैच वगैरह.
यहां दिए गए उदाहरण में, kernel कमांड लाइन में, सिस्टम-as-root के लिए 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"
डिवाइस के हिसाब से रूट फ़ोल्डर का इस्तेमाल करना
डिवाइस पर सामान्य सिस्टम इमेज (जीएसआई) फ़्लैश करने के बाद (और वेंडर टेस्ट सुइट टेस्ट चलाने से पहले), BOARD_ROOT_EXTRA_FOLDERS
के साथ जोड़े गए डिवाइस के हिसाब से बने रूट फ़ोल्डर हट जाते हैं. ऐसा इसलिए होता है, क्योंकि पूरी रूट डायरेक्ट्री के कॉन्टेंट को, सिस्टम के तौर पर रूट जीएसआई से बदल दिया जाता है. अगर डिवाइस के लिए खास तौर पर बनाए गए रूट फ़ोल्डर पर डिवाइस का निर्भर रहना ज़रूरी है, तो इन फ़ोल्डर को हटाने पर डिवाइस को बूट नहीं किया जा सकता. उदाहरण के लिए, इनका इस्तेमाल माउंट पॉइंट के तौर पर किया जाता है.
इस समस्या से बचने के लिए, डिवाइस के हिसाब से रूट फ़ोल्डर जोड़ने के लिए BOARD_ROOT_EXTRA_FOLDERS
का इस्तेमाल न करें. अगर आपको डिवाइस के हिसाब से माउंट
पॉइंट की जानकारी देनी है, तो /mnt/vendor/<mount point>
का इस्तेमाल करें. इसे इन
बदलाव सूचियों में जोड़ा गया है. वेंडर के हिसाब से ये माउंट पॉइंट, fstab
डिवाइस ट्री (पहले चरण के माउंट के लिए) और /vendor/etc/fstab.{ro.hardware}
फ़ाइल, दोनों में सीधे तौर पर तय किए जा सकते हैं. इसके लिए, किसी अतिरिक्त सेटअप की ज़रूरत नहीं होती, क्योंकि fs_mgr
उन्हें /mnt/vendor/*
में अपने-आप बनाता है.