डाइनैमिक पार्टिशनिंग को लागू करने के लिए, Linux kernel में 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
पार्टीशन की ज़रूरत नहीं होती.
रीड-ओनली AOSP वाले सभी ऐसे पार्टीशन जो बूटलोडर का इस्तेमाल नहीं करते, उन्हें डाइनैमिक होना चाहिए. साथ ही, उन्हें GUID पार्टीशन टेबल (GPT) से हटा दिया जाना चाहिए.
वेंडर के हिसाब से बने पार्टीशन, डाइनैमिक होने ज़रूरी नहीं हैं. साथ ही, इन्हें जीपीटी में रखा जा सकता है.
super
के साइज़ का अनुमान लगाने के लिए, GPT से मिटाए जा रहे
पार्टीशन के साइज़ जोड़ें. A/B डिवाइसों के लिए, इसमें दोनों स्लॉट का साइज़ शामिल होना चाहिए. पहली इमेज में, डाइनैमिक सेगमेंट में बदलने से पहले और बाद की,
सेगमेंट टेबल का उदाहरण दिखाया गया है.

ये डाइनैमिक पार्टीशन काम करते हैं:
- सिस्टम
- वेंडर
- प्रॉडक्ट
- सिस्टम एक्सटेंशन
- ODM
Android 10 के साथ लॉन्च होने वाले डिवाइसों के लिए,
कर्नल कमांड लाइन का विकल्प androidboot.super_partition
खाली होना चाहिए, ताकि कमांड sysprop
ro.boot.super_partition
खाली हो.
सेगमेंट का अलाइनमेंट
अगर super
पार्टीशन को सही तरीके से अलाइन नहीं किया गया है, तो हो सकता है कि डिवाइस-मैपर मॉड्यूल कम असरदार तरीके से काम करे. super
partition को कम से कम I/O अनुरोध के साइज़ के हिसाब से अलाइन करना ज़रूरी है. यह साइज़, ब्लॉक लेयर तय करती है. डिफ़ॉल्ट रूप से,
बिल्ड सिस्टम (lpmake
के ज़रिए, जो super
partition इमेज जनरेट करता है) यह मानता है कि हर डाइनैमिक partition के लिए 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 एमबी होता है. हालांकि, डिवाइस के हिसाब से ज़्यादा ओवरहेड भी चुना जा सकता है.
डाइनैमिक पार्टीशन का साइज़
डाइनैमिक पार्टीशन की सुविधा से पहले, पार्टीशन के साइज़ को ज़्यादा सेट किया जाता था, ताकि आने वाले समय में अपडेट करने के लिए ज़रूरत के मुताबिक जगह हो. असल साइज़ को वैसे ही लिया गया था और ज़्यादातर सिर्फ़ पढ़ने के लिए बने partition के फ़ाइल सिस्टम में कुछ जगह खाली थी. डाइनैमिक पार्टीशन में, उस खाली जगह का इस्तेमाल नहीं किया जा सकता. हालांकि, ओटीए (ओवर-द-एयर) के दौरान, पार्टीशन को बड़ा करने के लिए इसका इस्तेमाल किया जा सकता है. यह पक्का करना ज़रूरी है कि पार्टीशन में जगह बर्बाद न हो रही हो और उन्हें कम से कम साइज़ में ऐलोकेट किया गया हो.
अगर पार्टिशन का साइज़ हार्डकोड नहीं किया गया है, तो सिर्फ़ पढ़ने के लिए उपलब्ध 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 एमबी का खाली स्टोरेज स्पेस बन जाता है.
सिस्टम के तौर पर रूट के लेवल पर किए गए बदलाव
Android 10 के साथ लॉन्च होने वाले डिवाइसों को, system-as-root का इस्तेमाल नहीं करना चाहिए.
डाइनैमिक पार्टीशन वाले डिवाइसों को, सिस्टम-as-root का इस्तेमाल नहीं करना चाहिए. भले ही, वे डाइनैमिक पार्टीशन के साथ लॉन्च हों या फिर बाद में उनमें डाइनैमिक पार्टीशन जोड़े गए हों. Linux kernel, super
partition को समझ नहीं सकता. इसलिए, वह system
को खुद माउंट नहीं कर सकता. system
को अब पहले चरण के init
से माउंट किया जाता है, जो कि रैमडिस्क में मौजूद होता है.
BOARD_BUILD_SYSTEM_ROOT_IMAGE
सेट न करें. Android 10 में,
BOARD_BUILD_SYSTEM_ROOT_IMAGE
फ़्लैग का इस्तेमाल सिर्फ़ इस बात के लिए किया जाता है कि सिस्टम को,
कर्नेल या रामडिस्क में पहले चरण के 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
को kernel command-line पर पास नहीं करना चाहिए. इसके बजाय, रिकवरी को छोड़ने और सामान्य Android को बूट करने के लिए, बूटलोडर को androidboot.force_normal_boot=1
पास करना चाहिए. Android 12 या उसके बाद के वर्शन वाले डिवाइसों को androidboot.force_normal_boot=1
को पास करने के लिए, bootconfig का इस्तेमाल करना होगा.
एवीबी कॉन्फ़िगरेशन में बदलाव
अगर 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
फ़ुटर मिलना चाहिए. ये पार्टीशन, अब bootloader को नहीं दिखते (ये 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 — "सिस्टम पार्टीशन न होने की अनुमति दें"
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 — "Fix AvbSlotVerifyData->cmdline might be NULL"
अगर चेन किए गए पार्टीशन का इस्तेमाल किया जा रहा है, तो एक और पैच शामिल करें:
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: Support vbmeta blobs in beginning of partition."
कर्नेल कमांड लाइन में हुए बदलाव
kernel कमांड लाइन में एक नया पैरामीटर, androidboot.boot_devices
जोड़ना ज़रूरी है. इसका इस्तेमाल init
,
/dev/block/by-name
सिमलिंक चालू करने के लिए करता है. यह नाम के हिसाब से बनाए गए उस लिंक के डिवाइस पाथ कॉम्पोनेंट के तौर पर होना चाहिए जिसे
ueventd
ने बनाया है. इसका मतलब है कि यह
/dev/block/platform/device-path/by-name/partition-name
होना चाहिए.
Android 12 या उसके बाद के वर्शन वाले डिवाइसों को androidboot.boot_devices
को init
पर भेजने के लिए,
bootconfig का इस्तेमाल करना होगा.
उदाहरण के लिए, अगर नाम के हिसाब से सुपर पार्टीशन का लिंक /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 फ़ाइल का इस्तेमाल करें जो रैमडस्क का हिस्सा होगी.
लॉजिकल पार्टीशन के लिए, fstab फ़ाइल में बदलाव करना ज़रूरी है:
-
fs_mgr flags फ़ील्ड में
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 को लागू करने के तरीके के बारे में ज़्यादा जानने के लिए, Fastboot को उपयोगकर्ता स्पेस में ले जाना लेख पढ़ें.
adb remount
eng या userdebug बिल्ड का इस्तेमाल करने वाले डेवलपर के लिए, adb remount
तेज़ी से बदलाव करने के लिए काफ़ी मददगार है. डाइनैमिक पार्टिशन, adb remount
के लिए एक समस्या है, क्योंकि अब हर फ़ाइल सिस्टम में खाली जगह नहीं है. इसे ठीक करने के लिए, डिवाइसों पर
overlayfs चालू किया जा सकता है. जब तक सुपर पार्टीशन में खाली जगह है, तब तक
adb remount
अपने-आप एक अस्थायी डाइनैमिक
पार्टीशन बनाता है और डेटा लिखने के लिए, overlayfs का इस्तेमाल करता है. अस्थायी सेगमेंट का नाम scratch
होता है. इसलिए, इस नाम का इस्तेमाल किसी दूसरे सेगमेंट के लिए न करें.
overlayfs को चालू करने के तरीके के बारे में ज़्यादा जानने के लिए, AOSP में overlayfs के लिए रीडमाइड देखें.
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 डिवाइसों के लिए ओटीए देखें.
फ़ैक्ट्री इमेज
डाइनैमिक पार्टिशन की सुविधा के साथ लॉन्च होने वाले डिवाइस के लिए, फ़ैक्ट्री इमेज को फ़्लैश करने के लिए, यूज़रस्पेस फ़ास्टबूट का इस्तेमाल करने से बचें. ऐसा इसलिए, क्योंकि यूज़रस्पेस में बूट करना, फ़्लैश करने के अन्य तरीकों के मुकाबले धीमा होता है.
इस समस्या को हल करने के लिए, make dist
अब एक और
super.img
इमेज बनाता है. इसे सीधे सुपर
पार्टीशन में फ़्लैश किया जा सकता है. यह लॉजिकल
पार्टीशन के कॉन्टेंट को अपने-आप बंडल करता है. इसका मतलब है कि इसमें super
पार्टीशन मेटाडेटा के साथ-साथ system.img
,
vendor.img
वगैरह शामिल होते हैं. इस इमेज को सीधे super
partition में, किसी अन्य टूल या
fastbootd का इस्तेमाल किए बिना फ़्लैश किया जा सकता है. बिल्ड होने के बाद, super.img
को
${ANDROID_PRODUCT_OUT}
में रखा जाता है.
डाइनैमिक पार्टिशन के साथ लॉन्च होने वाले A/B डिवाइसों के लिए,
super.img
में A स्लॉट में इमेज होती हैं. सुपर इमेज को सीधे फ़्लैश करने के बाद, डिवाइस को रीबूट करने से पहले स्लॉट A को बूट करने लायक के तौर पर मार्क करें.
पहले से मौजूद डिवाइसों के लिए, make dist
super_*.img
इमेज का एक सेट बनाता है. इन्हें सीधे तौर पर, संबंधित फ़िज़िकल पार्टीशन में फ़्लैश किया जा सकता है. उदाहरण के लिए, BOARD_SUPER_PARTITION_BLOCK_DEVICES
के सिस्टम वेंडर होने पर, make dist
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
को मैनेज करने के लिए, उन्हें बूट के शुरुआती चरणों में इस्तेमाल नहीं किया जा सकता. जब तक init.rc
स्क्रिप्ट early-fs
में बदलाव नहीं कर सकतीं, तब तक आपको उम्मीद करनी चाहिए कि कोर के डिफ़ॉल्ट read_ahead_kb
काफ़ी होंगे. early-fs
में बदलाव तब होता है, जब अलग-अलग डेमन और सुविधाएं शुरू होती हैं. इसलिए, Google का सुझाव है कि आप on property
सुविधा का इस्तेमाल करें. साथ ही, ऑपरेशन के समय को मैनेज करने और रेस कंडीशन से बचने के लिए, sys.read_ahead_kb
जैसी init.rc
से कंट्रोल की जाने वाली प्रॉपर्टी का इस्तेमाल करें. इन उदाहरणों में इस बारे में बताया गया है:
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}