يتم تنفيذ التقسيم الديناميكي باستخدام وحدة dm-linear الخاصة بأداة ربط الأجهزة
في نواة Linux. يحتوي القسم super على بيانات وصفية تسرد أسماء ونطاقات الحظر لكل قسم ديناميكي ضمن super. أثناء المرحلة الأولى init، يتم تحليل هذه البيانات الوصفية والتحقّق من صحتها، ويتم إنشاء أجهزة تخزين بالكتل الافتراضية لتمثيل كل قسم ديناميكي.
عند تطبيق تحديث عبر الأثير (OTA)، يتم تلقائيًا إنشاء أقسام ديناميكية أو تغيير حجمها أو حذفها حسب الحاجة. بالنسبة إلى الأجهزة التي تستخدم نظام التشغيل A/B، تتوفّر نسختان من البيانات الوصفية، ويتم تطبيق التغييرات على النسخة التي تمثّل الخانة المستهدَفة فقط.
بما أنّ الأقسام الديناميكية يتم تنفيذها في مساحة المستخدم، لا يمكن إنشاء أقسام ديناميكية يحتاجها برنامج الإقلاع. على سبيل المثال، يقرأ برنامج الإقلاع boot وdtbo وvbmeta، لذا يجب أن تظل هذه الأقسام أقسامًا فعلية.
يمكن أن ينتمي كل قسم ديناميكي إلى مجموعة تحديث. تحدّد هذه المجموعات الحد الأقصى للمساحة التي يمكن أن تستهلكها الأقسام في تلك المجموعة.
على سبيل المثال، يمكن أن ينتمي system وvendor إلى مجموعة تفرض قيودًا على الحجم الإجمالي لكل من system وvendor.
تنفيذ الأقسام الديناميكية على الأجهزة الجديدة
يوضّح هذا القسم بالتفصيل كيفية تنفيذ الأقسام الديناميكية على الأجهزة الجديدة التي تعمل بالإصدار 10 من نظام التشغيل Android والإصدارات الأحدث. لتحديث الأجهزة الحالية، يُرجى الاطّلاع على مقالة ترقية أجهزة Android.
تغييرات الأقسام
بالنسبة إلى الأجهزة التي تعمل بنظام التشغيل Android 10، أنشئ قسمًا باسم super. يتعامل القسم super مع خانات A/B داخليًا، لذا لا تحتاج أجهزة A/B إلى قسمَين منفصلَين super_a وsuper_b.
يجب أن تكون جميع أقسام مشروع Android المفتوح المصدر (AOSP) للقراءة فقط التي لا يستخدمها برنامج إقلاع ديناميكية، ويجب إزالتها من جدول التقسيم ذو المعرفات الفريدة عالميًا (GPT).
لا يجب أن تكون الأقسام الخاصة بالمورّدين ديناميكية، ويمكن وضعها في GPT.
لتقدير حجم super، أضِف أحجام الأقسام التي يتم حذفها من GPT. بالنسبة إلى أجهزة A/B، يجب أن يشمل ذلك حجم كلا الفتحتين. يعرض الشكل 1 مثالاً على جدول أقسام قبل وبعد التحويل إلى أقسام ديناميكية.
في ما يلي الأقسام الديناميكية المتوافقة:
- النظام
- المورّد
- المنتج
- System Ext
- ODM
بالنسبة إلى الأجهزة التي تعمل بنظام التشغيل Android 10، يجب أن يكون خيار سطر أوامر kernel androidboot.super_partition فارغًا حتى يكون الأمر sysprop ro.boot.super_partition فارغًا.
محاذاة الأقسام
قد يعمل وحدة device-mapper بكفاءة أقل إذا لم تتم محاذاة القسم super بشكل صحيح. يجب أن يكون قسم super متوافقًا مع الحد الأدنى لحجم طلب الإدخال/الإخراج الذي تحدّده طبقة الحظر. بشكل تلقائي، يفترض نظام التصميم (من خلال 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
تغييرات في إعدادات لوحة Jamboard
يجب ضبط حجم القسم 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 - overhead -
بالنسبة إلى الأجهزة غير المتوافقة مع تحديثات 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 ميغابايت.
التغييرات على نظام التشغيل كجذر
يجب ألا تستخدم الأجهزة التي تعمل بالإصدار 10 من نظام التشغيل Android نظام التشغيل كجذر.
يجب ألا تستخدم الأجهزة التي تتضمّن أقسامًا ديناميكية (سواء تم إطلاقها مع أقسام ديناميكية أو تم تعديلها لتتضمّن أقسامًا ديناميكية) نظام التشغيل كجذر. لا يمكن لنواة Linux تفسير القسم super، وبالتالي لا يمكنها تثبيت system. يتم الآن تركيب system بواسطة init في المرحلة الأولى، والذي يقع في ramdisk.
عدم ضبط BOARD_BUILD_SYSTEM_ROOT_IMAGE في نظام التشغيل Android 10، لا يتم استخدام العلامة BOARD_BUILD_SYSTEM_ROOT_IMAGE إلا للتمييز بين ما إذا كان النظام مثبّتًا بواسطة النواة أو بواسطة init في المرحلة الأولى في ramdisk.
يؤدي ضبط BOARD_BUILD_SYSTEM_ROOT_IMAGE على true إلى حدوث خطأ في الإنشاء عندما تكون قيمة PRODUCT_USE_DYNAMIC_PARTITIONS هي true أيضًا.
عند ضبط BOARD_USES_RECOVERY_AS_BOOT على "صحيح"، يتم إنشاء صورة استرداد الإعدادات الأصلية كملف boot.img يحتوي على ملف ramdisk الخاص بالاسترداد. في السابق، كان برنامج Bootloader يستخدم مَعلمة سطر الأوامر skip_initramfs الخاصة بالنواة لتحديد الوضع الذي سيتم التشغيل فيه. في أجهزة Android 10، يجب ألا يمرّر برنامج الإقلاع skip_initramfs إلى سطر أوامر النواة. بدلاً من ذلك، يجب أن يمرِّر برنامج إقلاع androidboot.force_normal_boot=1 لتخطّي وضع الاسترداد وتشغيل نظام Android العادي. يجب أن تستخدم الأجهزة التي تعمل بالإصدار 12 من نظام التشغيل Android أو الإصدارات الأحدث bootconfig لتمرير androidboot.force_normal_boot=1.
تغييرات إعدادات AVB
عند استخدام التشغيل المتحقّق منه 2.0 على Android، إذا كان الجهاز لا يستخدم واصفات الأقسام المتسلسلة، فلن يكون من الضروري إجراء أي تغيير. في حال استخدام أقسام مرتبطة، وكان أحد الأقسام التي تم التحقّق منها ديناميكيًا، يجب إجراء تغييرات.
في ما يلي مثال على إعدادات جهاز يربط بين
vbmeta لقسمَي system وvendor.
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
باستخدام هذا الإعداد، يتوقّع برنامج الإقلاع العثور على تذييل vbmeta في نهاية القسمَين system وvendor. وبما أنّ هذه الأقسام لم تعُد مرئية لبرنامج التحميل (لأنّها تقع في 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
قد يستخدم الجهاز أحد هذين القسمَين أو كليهما أو لا يستخدم أيًا منهما. لا يلزم إجراء تغييرات إلا عند الربط بقسم منطقي.
تغييرات برنامج إقلاع AVB
إذا كان برنامج الإقلاع يتضمّن 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.
يجب أن تستخدم الأجهزة التي تعمل بالإصدار 12 من نظام التشغيل Android أو الإصدارات الأحدث bootconfig لتمرير 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التي تم طرحها في نظام التشغيل 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 إلى ramdisk في المرحلة الأولى.
تغييرات SELinux
يجب وضع التصنيف super_block_device على جهاز حظر التقسيم الفائق. على سبيل المثال، إذا كان رابط super partition by-name الرمزي هو
/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
لا يفهم برنامج الإقلاع (أو أي أداة تثبيت ذاكرة ROM غير خاصة بمساحة المستخدمين) الأقسام الديناميكية، لذا لا يمكنه تثبيت ذاكرة ROM عليها. ولحلّ هذه المشكلة، يجب أن تستخدم الأجهزة تنفيذًا لمساحة المستخدمين لبروتوكول fastboot، يُعرف باسم fastbootd.
لمزيد من المعلومات حول كيفية تنفيذ fastbootd، يُرجى الاطّلاع على نقل Fastboot إلى مساحة المستخدم.
adb remount
بالنسبة إلى المطوّرين الذين يستخدمون إصدارات eng أو userdebug، يكون adb remount
مفيدًا للغاية للتكرار السريع. تسبّب الأقسام الديناميكية مشكلة في adb remount لأنّه لم تعُد هناك مساحة خالية ضمن كل نظام ملفات. لحلّ هذه المشكلة، يمكن للأجهزة تفعيل overlayfs. طالما توجد مساحة خالية ضمن القسم الفائق، ينشئ adb remount تلقائيًا قسمًا ديناميكيًا مؤقتًا ويستخدم overlayfs لعمليات الكتابة. اسم القسم المؤقت هو scratch، لذا لا تستخدِم هذا الاسم لأقسام أخرى.
لمزيد من المعلومات حول كيفية تفعيل overlayfs، يُرجى الاطّلاع على ملف overlayfs README في مشروع Android مفتوح المصدر (AOSP).
ترقية أجهزة Android
إذا تمت ترقية جهاز إلى Android 10 وأردت تضمين إمكانية استخدام الأقسام الديناميكية في التحديث عبر الأثير، لن تحتاج إلى تغيير جدول الأقسام المضمّن. يجب إجراء بعض عمليات الضبط الإضافية.
التغييرات في إعدادات الجهاز
لإعادة تصميم التقسيم الديناميكي، أضِف العلامات التالية في
device.mk:
PRODUCT_USE_DYNAMIC_PARTITIONS := true PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true
تغييرات في إعدادات لوحة Jamboard
عليك ضبط متغيّرات اللوحة التالية:
- اضبط
BOARD_SUPER_PARTITION_BLOCK_DEVICESعلى قائمة أجهزة التخزين بالكتل المستخدَمة لتخزين مدى الأقسام الديناميكية. هذه هي قائمة بأسماء الأقسام المادية الحالية على الجهاز. - اضبط
BOARD_SUPER_PARTITION_partition_DEVICE_SIZEعلى أحجام كل جهاز تخزين بالكتل فيBOARD_SUPER_PARTITION_BLOCK_DEVICES، على التوالي. هذه هي قائمة بأحجام الأقسام الفعلية الحالية على الجهاز. ويحدث ذلك عادةًBOARD_partitionIMAGE_PARTITION_SIZEفي إعدادات اللوحة الحالية. - إلغاء ضبط
BOARD_partitionIMAGE_PARTITION_SIZEالحالي لجميع الأقسام فيBOARD_SUPER_PARTITION_BLOCK_DEVICES - اضبط
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;
للاطّلاع على عمليات الضبط الأخرى، يُرجى الرجوع إلى تنفيذ الأقسام الديناميكية على الأجهزة الجديدة.
لمزيد من المعلومات حول تحديثات التوافق مع الإصدارات القديمة، يُرجى الاطّلاع على التحديث عبر الهواء (OTA) للأجهزة التي تستخدم بنية أ/ب بدون أقسام ديناميكية.
صور برامج الجهة المصنِّعة
بالنسبة إلى جهاز يتم إطلاقه مع إتاحة الأقسام الديناميكية، تجنَّب استخدام fastboot في مساحة المستخدم لتثبيت صور المصنع، لأنّ عملية الإقلاع إلى مساحة المستخدم تستغرق وقتًا أطول من طرق التثبيت الأخرى.
لحلّ هذه المشكلة، ينشئ make dist الآن صورة إضافية super.img يمكن نقلها مباشرةً إلى قسم super. ويجمع تلقائيًا محتويات الأقسام المنطقية، ما يعني أنّه يحتوي على system.img وvendor.img وما إلى ذلك، بالإضافة إلى البيانات الوصفية الخاصة بالقسم super. يمكن نقل هذه الصورة مباشرةً إلى القسم super بدون أي أدوات إضافية أو استخدام fastbootd. بعد اكتمال عملية الإنشاء، يتم وضع super.img في ${ANDROID_PRODUCT_OUT}.
بالنسبة إلى أجهزة A/B التي يتم تشغيلها باستخدام أقسام ديناميكية، يحتوي super.img على صور في الفتحة A. بعد نقل صورة super مباشرةً، ضَع علامة على الفتحة A باعتبارها قابلة للتشغيل قبل إعادة تشغيل الجهاز.
بالنسبة إلى الأجهزة التي يمكن تعديلها، ينشئ make dist مجموعة من صور super_*.img التي يمكن نقلها مباشرةً إلى الأقسام المادية المقابلة. على سبيل المثال، تنشئ make dist
super_system.img وsuper_vendor.img
عندما تكون BOARD_SUPER_PARTITION_BLOCK_DEVICES هي مورّد النظام. يتم وضع هذه الصور في مجلد OTA في
target_files.zip.
ضبط جهاز التخزين في أداة Device Mapper
تستوعب عملية التقسيم الديناميكي عددًا من عناصر device-mapper غير المحدَّدة. قد لا يتم إنشاء مثيل لجميع هذه العناصر على النحو المتوقّع، لذا عليك تتبُّع جميع عمليات الربط وتعديل خصائص 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}