डाइनैमिक पार्टिशनिंग को Linux कर्नल में dm-linear डिवाइस-मैपर मॉड्यूल का इस्तेमाल करके लागू किया जाता है. super
पार्टीशन में, super
के अंदर मौजूद हर डाइनैमिक पार्टीशन के नाम और ब्लॉक रेंज की जानकारी देने वाला मेटाडेटा होता है. पहले चरण की init
के दौरान, इस मेटाडेटा को पार्स और पुष्टि की जाती है. साथ ही, हर डाइनैमिक पार्टीशन को दिखाने के लिए वर्चुअल ब्लॉक डिवाइस बनाए जाते हैं.
ओटीए लागू करने पर, डाइनैमिक पार्टिशन अपने-आप बन जाते हैं. साथ ही, ज़रूरत के मुताबिक उनका साइज़ बदल जाता है या वे मिट जाते हैं. A/B डिवाइसों के लिए, मेटाडेटा की दो कॉपी होती हैं. बदलाव सिर्फ़ उस कॉपी पर लागू होते हैं जो टारगेट स्लॉट को दिखाती है.
डाइनैमिक पार्टिशन को यूज़रस्पेस में लागू किया जाता है. इसलिए, बूटलोडर के लिए ज़रूरी पार्टिशन को डाइनैमिक नहीं बनाया जा सकता. उदाहरण के लिए, boot
, dtbo
, और vbmeta
को बूटलोडर पढ़ता है. इसलिए, इन्हें फ़िज़िकल पार्टीशन के तौर पर ही रहना चाहिए.
हर डाइनैमिक पार्टीशन, अपडेट ग्रुप से जुड़ा हो सकता है. ये ग्रुप, उस ग्रुप में मौजूद पार्टीशन के लिए ज़्यादा से ज़्यादा जगह तय करते हैं.
उदाहरण के लिए, system
और vendor
, ऐसे ग्रुप से जुड़े हो सकते हैं जो system
और vendor
के कुल साइज़ को सीमित करता है.
नए डिवाइसों पर डाइनैमिक पार्टिशन लागू करना
इस सेक्शन में, Android 10 और इसके बाद के वर्शन के साथ लॉन्च होने वाले नए डिवाइसों पर डाइनैमिक पार्टिशन लागू करने के तरीके के बारे में बताया गया है. मौजूदा डिवाइसों को अपडेट करने के लिए, Android डिवाइसों को अपग्रेड करना लेख पढ़ें.
पार्टिशन में हुए बदलाव
Android 10 के साथ लॉन्च होने वाले डिवाइसों के लिए, super
नाम का एक पार्टिशन बनाएं. super
पार्टिशन, A/B स्लॉट को अंदरूनी तौर पर मैनेज करता है. इसलिए, A/B डिवाइसों को अलग-अलग super_a
और super_b
पार्टिशन की ज़रूरत नहीं होती.
रीड-ओनली वाले सभी एओएसपी पार्टिशन, बूटलोडर के लिए इस्तेमाल नहीं किए जाते. इसलिए, इन्हें डाइनैमिक होना चाहिए. साथ ही, इन्हें GUID पार्टिशन टेबल (GPT) से हटा दिया जाना चाहिए.
वेंडर के हिसाब से बनाए गए पार्टिशन का डाइनैमिक होना ज़रूरी नहीं है. इन्हें GPT में रखा जा सकता है.
super
के साइज़ का अनुमान लगाने के लिए, GPT से मिटाए जा रहे
पार्टिशन के साइज़ जोड़ें. A/B डिवाइसों के लिए, इसमें दोनों स्लॉट का साइज़ शामिल होना चाहिए. पहली इमेज में, डाइनैमिक पार्टीशन में बदलने से पहले और बाद में, पार्टीशन टेबल का उदाहरण दिखाया गया है.

डाइनैमिक पार्टिशन के लिए, इन कॉलम का इस्तेमाल किया जा सकता है:
- सिस्टम
- वेंडर
- प्रॉडक्ट
- सिस्टम एक्सटेंशन
- ओडीएम
Android 10 के साथ लॉन्च होने वाले डिवाइसों के लिए, कर्नेल कमांड लाइन विकल्प androidboot.super_partition
खाली होना चाहिए, ताकि कमांड sysprop ro.boot.super_partition
खाली हो.
सेगमेंट का अलाइनमेंट
अगर super
पार्टीशन सही तरीके से अलाइन नहीं किया गया है, तो हो सकता है कि डिवाइस-मैपर मॉड्यूल ठीक से काम न करे. super
पार्टीशन को ब्लॉक लेयर के हिसाब से तय किए गए कम से कम I/O अनुरोध के साइज़ के साथ अलाइन किया जाना चाहिए. डिफ़ॉल्ट रूप से, बिल्ड सिस्टम (lpmake
के ज़रिए, जो super
पार्टीशन इमेज जनरेट करता है) यह मानता है कि हर डाइनैमिक पार्टीशन के लिए 1 MiB अलाइनमेंट काफ़ी है. हालांकि, वेंडर को यह पक्का करना चाहिए कि super
पार्टीशन सही तरीके से अलाइन किया गया हो.
sysfs
की जांच करके, ब्लॉक डिवाइस के लिए अनुरोध किए जा सकने वाले कम से कम साइज़ का पता लगाया जा सकता है. उदाहरण के लिए:
# ls -l /dev/block/by-name/super lrwxrwxrwx 1 root root 16 1970-04-05 01:41 /dev/block/by-name/super -> /dev/block/sda17 # cat /sys/block/sda/queue/minimum_io_size 786432
इसी तरह, super
पार्टीशन के अलाइनमेंट की पुष्टि की जा सकती है:
# cat /sys/block/sda/sda17/alignment_offset
अलाइनमेंट ऑफ़सेट की वैल्यू 0 होनी चाहिए.
डिवाइस के कॉन्फ़िगरेशन में बदलाव
डाइनैमिक पार्टिशनिंग की सुविधा चालू करने के लिए, device.mk
में यह फ़्लैग जोड़ें:
PRODUCT_USE_DYNAMIC_PARTITIONS := true
बोर्ड के कॉन्फ़िगरेशन में बदलाव
आपको super
पार्टिशन का साइज़ सेट करना होगा:
BOARD_SUPER_PARTITION_SIZE := <size-in-bytes>
A/B डिवाइसों पर, अगर डाइनैमिक पार्टीशन इमेज का कुल साइज़, super
पार्टीशन के साइज़ के आधे से ज़्यादा है, तो बिल्ड सिस्टम एक गड़बड़ी दिखाता है.
डाइनैमिक पार्टीशन की सूची को इस तरह कॉन्फ़िगर किया जा सकता है. अपडेट ग्रुप का इस्तेमाल करने वाले डिवाइसों के लिए, BOARD_SUPER_PARTITION_GROUPS
वैरिएबल में ग्रुप की सूची बनाएं. इसके बाद, हर ग्रुप के नाम में BOARD_group_SIZE
और BOARD_group_PARTITION_LIST
वैरिएबल होता है.
A/B डिवाइसों के लिए, ग्रुप का ज़्यादा से ज़्यादा साइज़ सिर्फ़ एक स्लॉट का होना चाहिए. ऐसा इसलिए, क्योंकि ग्रुप के नामों में स्लॉट का सफ़िक्स अंदरूनी तौर पर जोड़ा जाता है.
यहां एक ऐसे डिवाइस का उदाहरण दिया गया है जो सभी पार्टीशन को example_dynamic_partitions
नाम के ग्रुप में रखता है:
BOARD_SUPER_PARTITION_GROUPS := example_dynamic_partitions BOARD_EXAMPLE_DYNAMIC_PARTITIONS_SIZE := 6442450944 BOARD_EXAMPLE_DYNAMIC_PARTITIONS_PARTITION_LIST := system vendor product
यहां एक ऐसे डिवाइस का उदाहरण दिया गया है जो सिस्टम और प्रॉडक्ट सेवाओं को group_foo
और vendor
, product
, और odm
को group_bar
में रखता है:
BOARD_SUPER_PARTITION_GROUPS := group_foo group_bar BOARD_GROUP_FOO_SIZE := 4831838208 BOARD_GROUP_FOO_PARTITION_LIST := system product_services BOARD_GROUP_BAR_SIZE := 1610612736 BOARD_GROUP_BAR_PARTITION_LIST := vendor product odm
-
वर्चुअल A/B लॉन्च करने वाले डिवाइसों के लिए, सभी ग्रुप के ज़्यादा से ज़्यादा साइज़ का योग, ज़्यादा से ज़्यादा इतना होना चाहिए:
BOARD_SUPER_PARTITION_SIZE
- ओवरहेड
वर्चुअल A/B लागू करना लेख पढ़ें. -
A/B लॉन्च डिवाइसों के लिए, सभी ग्रुप के ज़्यादा से ज़्यादा साइज़ का योग यह होना चाहिए:
BOARD_SUPER_PARTITION_SIZE
/ 2 - ओवरहेड -
नॉन-A/B डिवाइसों और रेट्रोफ़िट A/B डिवाइसों के लिए, सभी ग्रुप के ज़्यादा से ज़्यादा साइज़ का योग यह होना चाहिए:
BOARD_SUPER_PARTITION_SIZE
- ओवरहेड - बिल्ड टाइम पर, अपडेट ग्रुप में मौजूद हर पार्टीशन की इमेज के साइज़ का योग, ग्रुप के ज़्यादा से ज़्यादा साइज़ से ज़्यादा नहीं होना चाहिए.
- मेटाडेटा, अलाइनमेंट वगैरह का हिसाब लगाने के लिए, कैलकुलेशन में ओवरहेड की ज़रूरत होती है. 4 MiB का ओवरहेड सही होता है. हालांकि, डिवाइस की ज़रूरत के हिसाब से इससे ज़्यादा ओवरहेड चुना जा सकता है.
डाइनैमिक पार्टिशन का साइज़
डाइनैमिक पार्टिशन से पहले, पार्टिशन के साइज़ को ज़्यादा जगह दी जाती थी, ताकि आने वाले समय में अपडेट के लिए उनके पास काफ़ी जगह हो. असल साइज़ को वैसे ही लिया गया था और ज़्यादातर रीड-ओनली पार्टीशन के फ़ाइल सिस्टम में कुछ जगह खाली थी. डाइनैमिक पार्टिशन में, उस खाली जगह का इस्तेमाल नहीं किया जा सकता. हालांकि, इसका इस्तेमाल ओटीए के दौरान पार्टिशन को बढ़ाने के लिए किया जा सकता है. यह पक्का करना ज़रूरी है कि पार्टीशन से जगह बर्बाद न हो और उन्हें कम से कम जगह में बांटा गया हो.
सिर्फ़ पढ़ने के लिए उपलब्ध ext4 इमेज के लिए, बिल्ड सिस्टम अपने-आप कम से कम साइज़ असाइन करता है. ऐसा तब होता है, जब हार्डकोड किए गए पार्टिशन का साइज़ नहीं दिया जाता. बिल्ड सिस्टम, इमेज को इस तरह से फ़िट करता है कि फ़ाइल सिस्टम में कम से कम जगह खाली रहे. इससे यह पक्का होता है कि डिवाइस, ऐसी जगह को बर्बाद न करे जिसका इस्तेमाल ओटीए के लिए किया जा सकता है.
इसके अलावा, ब्लॉक-लेवल डिडुप्लीकेशन की सुविधा चालू करके, ext4 इमेज को और कंप्रेस किया जा सकता है. इसे चालू करने के लिए, इस कॉन्फ़िगरेशन का इस्तेमाल करें:
BOARD_EXT4_SHARE_DUP_BLOCKS := true
अगर आपको पार्टीशन के कम से कम साइज़ को अपने-आप असाइन होने से रोकना है, तो पार्टीशन के साइज़ को कंट्रोल करने के दो तरीके हैं. BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE
एट्रिब्यूट का इस्तेमाल करके, कम से कम खाली जगह की जानकारी दी जा सकती है. इसके अलावा, BOARD_partitionIMAGE_PARTITION_SIZE
एट्रिब्यूट का इस्तेमाल करके, डाइनैमिक पार्टीशन को किसी खास साइज़ में फ़ोर्स किया जा सकता है. हम इनमें से किसी भी तरीके का सुझाव तब तक नहीं देते, जब तक कि ऐसा करना ज़रूरी न हो.
उदाहरण के लिए:
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
इससे product.img
में फ़ाइल सिस्टम को 50 MiB का इस्तेमाल न किया गया स्पेस उपलब्ध कराने के लिए मजबूर किया जाता है.
सिस्टम-ऐज़-रूट में हुए बदलाव
Android 10 के साथ लॉन्च होने वाले डिवाइसों में, सिस्टम-ऐज़-रूट का इस्तेमाल नहीं किया जाना चाहिए.
डाइनैमिक पार्टिशन वाले डिवाइसों को सिस्टम-ऐज़-रूट का इस्तेमाल नहीं करना चाहिए. भले ही, डिवाइस डाइनैमिक पार्टिशन के साथ लॉन्च हुआ हो या उसमें डाइनैमिक पार्टिशन बाद में जोड़ा गया हो. Linux कर्नल, super
पार्टीशन को नहीं समझ सकता. इसलिए, वह super
को माउंट नहीं कर सकता.system
system
अब पहले चरण के init
से माउंट किया गया है. यह रैमडिस्क में मौजूद होता है.
BOARD_BUILD_SYSTEM_ROOT_IMAGE
को सेट न करें. Android 10 में, BOARD_BUILD_SYSTEM_ROOT_IMAGE
फ़्लैग का इस्तेमाल सिर्फ़ यह पता लगाने के लिए किया जाता है कि सिस्टम को कर्नल ने माउंट किया है या ramdisk में मौजूद पहले चरण के init
ने.
BOARD_BUILD_SYSTEM_ROOT_IMAGE
को true
पर सेट करने से, बिल्ड से जुड़ी गड़बड़ी होती है. ऐसा तब होता है, जब PRODUCT_USE_DYNAMIC_PARTITIONS
भी true
पर सेट हो.
BOARD_USES_RECOVERY_AS_BOOT
को सही पर सेट करने पर, रिकवरी इमेज को boot.img के तौर पर बनाया जाता है. इसमें रिकवरी का रैमडिस्क शामिल होता है. इससे पहले, बूटलोडर skip_initramfs
kernel
कमांड लाइन पैरामीटर का इस्तेमाल करके यह तय करता था कि किस मोड में बूट करना है. Android 10 वाले डिवाइसों के लिए, बूटलोडर को कर्नेल कमांड-लाइन में skip_initramfs
पास नहीं करना चाहिए. इसके बजाय, बूटलोडर को androidboot.force_normal_boot=1
पास करना चाहिए, ताकि रिकवरी को स्किप किया जा सके और सामान्य Android बूट हो सके. Android 12 या इसके बाद के वर्शन के साथ लॉन्च किए गए डिवाइसों को androidboot.force_normal_boot=1
पास करने के लिए, bootconfig का इस्तेमाल करना होगा.
AVB कॉन्फ़िगरेशन में बदलाव
Android Verified Boot 2.0 का इस्तेमाल करते समय, अगर डिवाइस चेन किए गए पार्टीशन डिस्क्रिप्टर का इस्तेमाल नहीं कर रहा है, तो कोई बदलाव करने की ज़रूरत नहीं है. हालांकि, अगर चेन किए गए पार्टीशन का इस्तेमाल किया जा रहा है और पुष्टि किए गए पार्टीशन में से कोई एक डाइनैमिक है, तो बदलाव करना ज़रूरी है.
यहां एक ऐसे डिवाइस के लिए कॉन्फ़िगरेशन का उदाहरण दिया गया है जो system
और vendor
पार्टीशन के लिए, vbmeta
को चेन करता है.
BOARD_AVB_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048 BOARD_AVB_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION := 1 BOARD_AVB_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_VENDOR_ALGORITHM := SHA256_RSA2048 BOARD_AVB_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_VENDOR_ROLLBACK_INDEX_LOCATION := 1
इस कॉन्फ़िगरेशन के साथ, बूटलोडर को system
और vendor
पार्टीशन के आखिर में vbmeta फ़ुटर मिलने की उम्मीद होती है. ये पार्टिशन अब बूटलोडर को नहीं दिखते (ये super
में मौजूद हैं). इसलिए, दो बदलाव करने होंगे.
-
डिवाइस की पार्टीशन टेबल में
vbmeta_system
औरvbmeta_vendor
पार्टिशन जोड़ें. A/B डिवाइसों के लिए,vbmeta_system_a
,vbmeta_system_b
,vbmeta_vendor_a
, औरvbmeta_vendor_b
जोड़ें. अगर इनमें से एक या उससे ज़्यादा पार्टीशन जोड़े जाते हैं, तो उनका साइज़vbmeta
पार्टीशन के साइज़ के बराबर होना चाहिए. -
कॉन्फ़िगरेशन फ़्लैग का नाम बदलें. इसके लिए,
VBMETA_
जोड़ें. साथ ही, यह बताएं कि चेनिंग किन पार्टीशन तक फैली हुई है:BOARD_AVB_VBMETA_SYSTEM := system BOARD_AVB_VBMETA_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_VBMETA_SYSTEM_ALGORITHM := SHA256_RSA2048 BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 1 BOARD_AVB_VBMETA_VENDOR := vendor BOARD_AVB_VBMETA_VENDOR_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_VBMETA_VENDOR_ALGORITHM := SHA256_RSA2048 BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_VBMETA_VENDOR_ROLLBACK_INDEX_LOCATION := 1
कोई डिवाइस इनमें से एक, दोनों या किसी भी पार्टीशन का इस्तेमाल नहीं कर सकता. बदलाव सिर्फ़ तब ज़रूरी होते हैं, जब लॉजिकल पार्टीशन से चेन किया जा रहा हो.
एवीबी बूटलोडर में बदलाव
अगर बूटलोडर में libavb एम्बेड किया गया है, तो ये पैच शामिल करें:
- 818cf56740775446285466eda984acedd4baeac0 — "libavb: Only query partition GUIDs when the cmdline needs them."
- 5abd6bc2578968d24406d834471adfd995a0c2e9 — "Allow system partition to be absent"
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 — "Fix AvbSlotVerifyData->cmdline might be NULL"
चेन किए गए पार्टिशन का इस्तेमाल करने पर, एक और पैच शामिल करें:
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: Support vbmeta blobs in beginning of partition."
कर्नेल कमांड लाइन में बदलाव
कर्नेल कमांड लाइन में एक नया पैरामीटर, androidboot.boot_devices
, जोड़ा जाना चाहिए. init
इस कुकी का इस्तेमाल, /dev/block/by-name
सिंबल लिंक चालू करने के लिए करता है. यह ueventd
की ओर से बनाए गए, नाम के हिसाब से सिंबल वाले लिंक का डिवाइस पाथ कॉम्पोनेंट होना चाहिए. जैसे, /dev/block/platform/device-path/by-name/partition-name
.
Android 12 या इसके बाद के वर्शन के साथ लॉन्च किए गए डिवाइसों को, androidboot.boot_devices
को init
तक पहुंचाने के लिए, बूट कॉन्फ़िगरेशन का इस्तेमाल करना होगा.
उदाहरण के लिए, अगर सुपर पार्टीशन का नाम वाला सिंबॉलिक लिंक /dev/block/platform/soc/100000.ufshc/by-name/super
है, तो BoardConfig.mk फ़ाइल में कमांड लाइन पैरामीटर को इस तरह जोड़ा जा सकता है:
BOARD_KERNEL_CMDLINE += androidboot.boot_devices=soc/100000.ufshc
BOARD_BOOTCONFIG += androidboot.boot_devices=soc/100000.ufshc
fstab में हुए बदलाव
डिवाइस ट्री और डिवाइस ट्री ओवरले में fstab की एंट्री नहीं होनी चाहिए. ऐसी fstab फ़ाइल का इस्तेमाल करें जो ramdisk का हिस्सा होगी.
लॉजिकल पार्टीशन के लिए, fstab फ़ाइल में ये बदलाव किए जाने चाहिए:
-
fs_mgr फ़्लैग फ़ील्ड में
logical
फ़्लैग औरfirst_stage_mount
फ़्लैग शामिल होना चाहिए.first_stage_mount
फ़्लैग को Android 10 में पेश किया गया था. यह फ़्लैग बताता है कि किसी पार्टीशन को पहले चरण में माउंट किया जाना है. -
कोई पार्टिशन,
avb=vbmeta partition name
कोfs_mgr
फ़्लैग के तौर पर तय कर सकता है. इसके बाद, तय किए गएvbmeta
पार्टिशन को पहले चरण केinit
से शुरू किया जाता है. ऐसा किसी भी डिवाइस को माउंट करने से पहले किया जाता है. -
dev
फ़ील्ड, पार्टीशन का नाम होना चाहिए.
यहां दी गई fstab एंट्री, ऊपर दिए गए नियमों के मुताबिक सिस्टम, वेंडर, और प्रॉडक्ट को लॉजिकल पार्टिशन के तौर पर सेट करती हैं.
#<dev> <mnt_point> <type> <mnt_flags options> <fs_mgr_flags> system /system ext4 ro,barrier=1 wait,slotselect,avb=vbmeta,logical,first_stage_mount vendor /vendor ext4 ro,barrier=1 wait,slotselect,avb,logical,first_stage_mount product /product ext4 ro,barrier=1 wait,slotselect,avb,logical,first_stage_mount
fstab फ़ाइल को पहले चरण के रैमडिस्क में कॉपी करें.
SELinux में किए गए बदलाव
सुपर पार्टीशन ब्लॉक डिवाइस को super_block_device
लेबल के साथ मार्क किया जाना चाहिए. उदाहरण के लिए, अगर नाम के हिसाब से सुपर पार्टीशन का सिंबॉलिक लिंक यह है:
/dev/block/platform/soc/100000.ufshc/by-name/super
,
तो file_contexts
में यह लाइन जोड़ें:
/dev/block/platform/soc/10000\.ufshc/by-name/super u:object_r:super_block_device:s0
fastbootd
बूटलोडर (या नॉन-यूज़रस्पेस फ़्लैशिंग टूल) को डाइनैमिक पार्टीशन के बारे में जानकारी नहीं होती. इसलिए, वह उन्हें फ़्लैश नहीं कर सकता. इस समस्या को हल करने के लिए, डिवाइसों को फ़ास्टबूट प्रोटोकॉल के उपयोगकर्ता-स्पेस वर्शन का इस्तेमाल करना होगा. इसे fastbootd कहा जाता है.
fastbootd को लागू करने के तरीके के बारे में ज़्यादा जानने के लिए, Fastboot को उपयोगकर्ता स्पेस में ले जाना लेख पढ़ें.
adb remount
eng या userdebug बिल्ड का इस्तेमाल करने वाले डेवलपर के लिए, adb remount
तेज़ इटरेशन के लिए बेहद मददगार है. डाइनैमिक पार्टिशन की वजह से, adb remount
को समस्या आ सकती है. ऐसा इसलिए, क्योंकि अब हर फ़ाइल सिस्टम में खाली जगह नहीं है. इस समस्या को ठीक करने के लिए, डिवाइसों पर overlayfs चालू किया जा सकता है. जब तक सुपर पार्टीशन में खाली जगह होती है, तब तक adb remount
अपने-आप एक अस्थायी डाइनैमिक पार्टीशन बनाता है और लिखने के लिए overlayfs का इस्तेमाल करता है. अस्थायी पार्टीशन का नाम scratch
है. इसलिए, इस नाम का इस्तेमाल अन्य पार्टीशन के लिए न करें.
overlayfs को चालू करने के तरीके के बारे में ज़्यादा जानने के लिए, AOSP में overlayfs README देखें.
Android डिवाइसों को अपग्रेड करना
अगर आपने किसी डिवाइस को Android 10 पर अपग्रेड किया है और आपको ओटीए में डाइनैमिक पार्टिशन की सुविधा शामिल करनी है, तो आपको पहले से मौजूद पार्टिशन टेबल में बदलाव करने की ज़रूरत नहीं है. इसके लिए, कुछ अतिरिक्त कॉन्फ़िगरेशन की ज़रूरत होती है.
डिवाइस के कॉन्फ़िगरेशन में बदलाव
डाइनैमिक पार्टिशनिंग को फिर से लागू करने के लिए, device.mk
में ये फ़्लैग जोड़ें:
PRODUCT_USE_DYNAMIC_PARTITIONS := true PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true
बोर्ड के कॉन्फ़िगरेशन में बदलाव
आपको बोर्ड के ये वैरिएबल सेट करने होंगे:
BOARD_SUPER_PARTITION_BLOCK_DEVICES
को ब्लॉक किए गए उन डिवाइसों की सूची पर सेट करें जिनका इस्तेमाल, डाइनैमिक पार्टीशन के एक्सटेंट को सेव करने के लिए किया जाता है. यह डिवाइस पर मौजूद फ़िज़िकल पार्टीशन के नामों की सूची है.BOARD_SUPER_PARTITION_partition_DEVICE_SIZE
कोBOARD_SUPER_PARTITION_BLOCK_DEVICES
में मौजूद हर ब्लॉक डिवाइस के साइज़ के हिसाब से सेट करें. यह डिवाइस पर मौजूद फ़िज़िकल पार्टीशन के साइज़ की सूची है. आम तौर पर, यह मौजूदा बोर्ड कॉन्फ़िगरेशन मेंBOARD_partitionIMAGE_PARTITION_SIZE
होता है.BOARD_SUPER_PARTITION_BLOCK_DEVICES
में मौजूद सभी पार्टीशन के लिए, मौजूदाBOARD_partitionIMAGE_PARTITION_SIZE
को अनसेट करें.BOARD_SUPER_PARTITION_SIZE
कोBOARD_SUPER_PARTITION_partition_DEVICE_SIZE
के योग पर सेट करें.BOARD_SUPER_PARTITION_METADATA_DEVICE
को उस डिवाइस पर सेट करें जहां डाइनैमिक पार्टीशन का मेटाडेटा सेव किया जाता है. यह वैल्यूBOARD_SUPER_PARTITION_BLOCK_DEVICES
में से कोई एक होनी चाहिए. आम तौर पर, यहsystem
पर सेट होता है.BOARD_SUPER_PARTITION_GROUPS
,BOARD_group_SIZE
, औरBOARD_group_PARTITION_LIST
को सेट करें. ज़्यादा जानकारी के लिए, नए डिवाइसों पर बोर्ड के कॉन्फ़िगरेशन में बदलाव लेख पढ़ें.
उदाहरण के लिए, अगर डिवाइस में पहले से ही सिस्टम और वेंडर पार्टिशन मौजूद हैं और आपको उन्हें डाइनैमिक पार्टिशन में बदलना है. साथ ही, अपडेट के दौरान एक नया प्रॉडक्ट पार्टिशन जोड़ना है, तो इस बोर्ड कॉन्फ़िगरेशन को सेट करें:
BOARD_SUPER_PARTITION_BLOCK_DEVICES := system vendor BOARD_SUPER_PARTITION_METADATA_DEVICE := system # Rename BOARD_SYSTEMIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE. BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE := <size-in-bytes> # Rename BOARD_VENDORIMAGE_PARTITION_SIZE to BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE := <size-in-bytes> # This is BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE + BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE BOARD_SUPER_PARTITION_SIZE := <size-in-bytes> # Configuration for dynamic partitions. For example: BOARD_SUPER_PARTITION_GROUPS := group_foo BOARD_GROUP_FOO_SIZE := <size-in-bytes> BOARD_GROUP_FOO_PARTITION_LIST := system vendor product
SELinux में किए गए बदलाव
सुपर पार्टीशन ब्लॉक डिवाइसों को super_block_device_type
एट्रिब्यूट के साथ मार्क किया जाना चाहिए. उदाहरण के लिए, अगर डिवाइस में पहले से ही system
और vendor
पार्टीशन हैं, तो आपको उनका इस्तेमाल ब्लॉक डिवाइसों के तौर पर करना है, ताकि डाइनैमिक पार्टीशन के एक्सटेंट सेव किए जा सकें. साथ ही, उनके नाम के हिसाब से सिंबल लिंक को system_block_device
के तौर पर मार्क किया गया है:
/dev/block/platform/soc/10000\.ufshc/by-name/system u:object_r:system_block_device:s0 /dev/block/platform/soc/10000\.ufshc/by-name/vendor u:object_r:system_block_device:s0
इसके बाद, device.te
में यह लाइन जोड़ें:
typeattribute system_block_device super_block_device_type;
अन्य कॉन्फ़िगरेशन के लिए, नए डिवाइसों पर डाइनैमिक पार्टीशन लागू करना लेख पढ़ें.
रेट्रोफ़िट अपडेट के बारे में ज़्यादा जानने के लिए, डाइनैमिक पार्टीशन के बिना A/B डिवाइसों के लिए OTA देखें.
फ़ैक्ट्री इमेज
डाइनैमिक पार्टिशन की सुविधा के साथ लॉन्च होने वाले डिवाइस के लिए, फ़ैक्ट्री इमेज फ़्लैश करने के लिए userspace fastboot का इस्तेमाल न करें. ऐसा इसलिए, क्योंकि userspace में बूट करना, फ़्लैश करने के अन्य तरीकों की तुलना में धीमा होता है.
इस समस्या को हल करने के लिए, make dist
अब एक अतिरिक्त super.img
इमेज बनाता है. इसे सीधे तौर पर सुपर पार्टीशन में फ़्लैश किया जा सकता है. यह लॉजिकल पार्टीशन के कॉन्टेंट को अपने-आप बंडल कर देता है. इसका मतलब है कि इसमें system.img
, vendor.img
वगैरह के साथ-साथ super
पार्टीशन का मेटाडेटा भी शामिल होता है. इस इमेज को सीधे super
पार्टीशन में फ़्लैश किया जा सकता है. इसके लिए, किसी अन्य टूल की ज़रूरत नहीं होती. साथ ही, फ़ास्टबूटडी का इस्तेमाल भी नहीं करना पड़ता. बिल्ड के बाद, super.img
को ${ANDROID_PRODUCT_OUT}
में रखा जाता है.
डाइनैमिक पार्टिशन के साथ लॉन्च होने वाले A/B डिवाइसों के लिए,
super.img
में A स्लॉट में मौजूद इमेज होती हैं. सुपर इमेज को सीधे तौर पर फ़्लैश करने के बाद, डिवाइस को रीबूट करने से पहले स्लॉट A को बूट करने लायक के तौर पर मार्क करें.
रेट्रोफ़िट डिवाइसों के लिए, make dist
, super_*.img
इमेज का एक सेट बनाता है. इन्हें सीधे तौर पर, उनसे जुड़े फ़िज़िकल पार्टीशन में फ़्लैश किया जा सकता है. उदाहरण के लिए, make dist
, BOARD_SUPER_PARTITION_BLOCK_DEVICES
के सिस्टम वेंडर होने पर super_system.img
और super_vendor.img
बनाता है. ये इमेज, target_files.zip
में मौजूद OTA फ़ोल्डर में रखी जाती हैं.
डिवाइस मैपर स्टोरेज-डिवाइस ट्यूनिंग
डाइनैमिक पार्टिशनिंग में, डिवाइस-मैपर के कई नॉनडिटरमिनिस्टिक ऑब्जेक्ट शामिल होते हैं. ऐसा हो सकता है कि ये सभी उम्मीद के मुताबिक इंस्टैंशिएट न हों. इसलिए, आपको सभी माउंट ट्रैक करने होंगे. साथ ही, उनसे जुड़ी सभी पार्टीशन की Android प्रॉपर्टी को उनके स्टोरेज डिवाइसों के साथ अपडेट करना होगा.
init
में मौजूद एक सिस्टम, माउंट को ट्रैक करता है और Android प्रॉपर्टी को एसिंक्रोनस तरीके से अपडेट करता है. इस प्रोसेस में कितना समय लगेगा, इसकी कोई गारंटी नहीं है. इसलिए, आपको सभी on property
ट्रिगर को काम करने के लिए ज़रूरी समय देना होगा. प्रॉपर्टी dev.mnt.blk.<partition>
है, जहां <partition>
, root
, system
, data
या vendor
है. उदाहरण के लिए. हर प्रॉपर्टी, स्टोरेज डिवाइस के नाम से जुड़ी होती है. जैसा कि इन उदाहरणों में दिखाया गया है:
taimen:/ % getprop | grep dev.mnt.blk [dev.mnt.blk.data]: [sda] [dev.mnt.blk.firmware]: [sde] [dev.mnt.blk.metadata]: [sde] [dev.mnt.blk.persist]: [sda] [dev.mnt.blk.root]: [dm-0] [dev.mnt.blk.vendor]: [dm-1] blueline:/ $ getprop | grep dev.mnt.blk [dev.mnt.blk.data]: [dm-4] [dev.mnt.blk.metadata]: [sda] [dev.mnt.blk.mnt.scratch]: [sda] [dev.mnt.blk.mnt.vendor.persist]: [sdf] [dev.mnt.blk.product]: [dm-2] [dev.mnt.blk.root]: [dm-0] [dev.mnt.blk.system_ext]: [dm-3] [dev.mnt.blk.vendor]: [dm-1] [dev.mnt.blk.vendor.firmware_mnt]: [sda]
init.rc
भाषा की मदद से, Android प्रॉपर्टी को नियमों के तहत बढ़ाया जा सकता है. साथ ही, स्टोरेज डिवाइसों को प्लैटफ़ॉर्म से ज़रूरत के हिसाब से ट्यून किया जा सकता है. इसके लिए, इस तरह के निर्देश इस्तेमाल किए जा सकते हैं:
write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb 128 write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb 128
दूसरे चरण init
में कमांड प्रोसेस होने के बाद, epoll loop
चालू हो जाता है और वैल्यू अपडेट होने लगती हैं. हालांकि, प्रॉपर्टी ट्रिगर init
के आखिर तक चालू नहीं होते. इसलिए, इनका इस्तेमाल बूटिंग के शुरुआती चरणों में root
, system
या vendor
को मैनेज करने के लिए नहीं किया जा सकता. आपको लग सकता है कि कर्नल का डिफ़ॉल्ट read_ahead_kb
तब तक काफ़ी है, जब तक कि init.rc
स्क्रिप्ट early-fs
में इसे बदल नहीं सकतीं. ऐसा तब होता है, जब अलग-अलग डेमॉन और सुविधाएं शुरू होती हैं. इसलिए, Google का सुझाव है कि आप on property
सुविधा का इस्तेमाल करें. साथ ही, init.rc
कंट्रोल की गई प्रॉपर्टी, जैसे कि sys.read_ahead_kb
का इस्तेमाल करें. इससे आपको ऑपरेशन के समय को मैनेज करने और रेस की स्थितियों को रोकने में मदद मिलेगी. जैसे, इन उदाहरणों में दिखाया गया है:
on property:dev.mnt.blk.root=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.root}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.system=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.system}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.vendor=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.vendor}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.product=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.system_ext}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.oem=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.oem}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on property:dev.mnt.blk.data=* && property:sys.read_ahead_kb=* write /sys/block/${dev.mnt.blk.data}/queue/read_ahead_kb ${sys.read_ahead_kb:-2048} on early-fs: setprop sys.read_ahead_kb ${ro.read_ahead_kb.boot:-2048} on property:sys.boot_completed=1 setprop sys.read_ahead_kb ${ro.read_ahead_kb.bootcomplete:-128}