يتم تنفيذ التقسيم الديناميكي باستخدام وحدة dm-linear device-mapper
في نواة Linux. يحتوي قسم super
على
بيانات وصفية تسرد أسماء نطاقات كل قسم ديناميكي ونطاقاته
ضمن super
. خلال المرحلة الأولى init
، تتم معالجة هذه
العناصر الوصفية والتحقّق منها، ويتم إنشاء أجهزة تخزين افتراضية بالكتل لتمثل
كل قسم ديناميكي.
عند تطبيق تحديث OTA، يتم إنشاء الأقسام الديناميكية تلقائيًا أو تغيير حجمها أو حذفها حسب الحاجة. بالنسبة إلى الأجهزة التي تستخدم اختبار أ/ب، تتوفّر نسختان من البيانات الوصفية، ولا يتم تطبيق التغييرات إلا على النسخة التي تمثّل الخانة المستهدَفة.
بما أنّ الأقسام الديناميكية يتم تنفيذها في مساحة المستخدم، لا يمكن جعل الأقسام التي يحتاج إليها bootloader ديناميكية. على سبيل المثال، يقرأ برنامج الإقلاع القسمَين boot
وdtbo
وvbmeta
، وبالتالي يجب أن يظلا قسمَين فعليَّين.
يمكن أن ينتمي كل قسم ديناميكي إلى مجموعة تعديل. تحدّ هذه
المجموعات من الحد الأقصى للمساحة التي يمكن أن تستهلكها الأقسام في تلك المجموعة.
على سبيل المثال، يمكن أن ينتمي system
وvendor
إلى
مجموعة تحدّ من الحجم الإجمالي لsystem
vendor
.
تنفيذ الأقسام الديناميكية على الأجهزة الجديدة
يوضّح هذا القسم بالتفصيل كيفية تنفيذ الأقسام الديناميكية على الأجهزة الجديدة التي تعمل بالإصدار 10 من نظام التشغيل Android والإصدارات الأحدث. لتحديث الأجهزة الحالية، يُرجى الاطّلاع على مقالة ترقية أجهزة Android.
تغييرات التقسيم
بالنسبة إلى الأجهزة التي تعمل بنظام التشغيل Android 10، أنشئ
قسمًا باسم super
. يعالج قسم super
خانات A/B داخليًا، لذا لا تحتاج أجهزة A/B إلى
قسمَي super_a
وsuper_b
منفصلَين.
يجب أن تكون جميع أقسام AOSP للقراءة فقط التي لا يستخدمها أداة تحميل البرامج التمهيدية
ديناميكية ويجب إزالتها من جدول تقسيم GUID (GPT).
لا يجب أن تكون الأقسام الخاصة بالمورّد ديناميكية، ويمكن وضعها
في GPT.
لتقدير حجم super
، أضِف أحجام ال partitions
التي يتم حذفها من GPT. بالنسبة إلى الأجهزة التي تتضمّن علامتَي A/B، يجب أن يشمل ذلك
حجم كلتا الفتحتَين. يعرض الشكل 1 مثالاً على جدول أقسام قبل وبعد تحويله إلى أقسام
ديناميكية.

التقسيمات الديناميكية المتوافقة هي:
- النظام
- المورّد
- المنتَج
- System Ext
- ODM
بالنسبة إلى الأجهزة التي تعمل بنظام التشغيل Android 10، يجب أن يكون خيار سطر الأوامر لنظام التشغيل androidboot.super_partition
فارغًا حتى يكون الأمر sysprop
ro.boot.super_partition
فارغًا.
محاذاة الأقسام
قد تعمل وحدة "محاكي الجهاز" بكفاءة أقل في حال عدم محاذاة قسم
super
بشكل صحيح. يجب أن يكون تنسيق ملف super
متوافقًا مع الحد الأدنى لحجم طلب الإدخال/الإخراج الذي تحدّده طبقة الكتل. يفترض
نظام الإنشاء (من خلال lpmake
الذي ينشئ
super
صورة القسم) تلقائيًا أنّ محاذاة 1 ميغابايت
كافية لكل قسم ديناميكي. ومع ذلك، على المورّدين
التأكّد من محاذاة قسم 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
.
بالنسبة إلى الأجهزة التي تستخدم اختبار أ/ب، يجب ألا يتجاوز الحد الأقصى لحجم المجموعة
خانة واحدة، لأنّ أسماء المجموعات تنتهي بلاحقة خانة داخليًا.
في ما يلي مثال على جهاز يضع جميع الأقسام في مجموعة
باسم 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 الافتراضي. -
بالنسبة إلى أجهزة إطلاق اختبار أ/ب، يجب أن يكون مجموع الحد الأقصى لحجم كل المجموعات
هو:
BOARD_SUPER_PARTITION_SIZE
/ 2 - النفقات العامة -
بالنسبة إلى الأجهزة غير المزوّدة بميزة A/B والأجهزة المزوّدة بميزة A/B التي تم تركيبها لاحقًا، يجب أن يكون مجموع الحد الأقصى
لحجم جميع المجموعات على النحو التالي:
BOARD_SUPER_PARTITION_SIZE
- مساحة التخزين الاحتياطية - في وقت الإنشاء، يجب ألا يتجاوز مجموع أحجام صور كل قسم في مجموعة التحديث الحد الأقصى لحجم المجموعة.
- يجب تضمين الوقت المستغرَق في العمليات غير الأساسية في عملية الحساب لمراعاة البيانات الوصفية، والمواضع، وما إلى ذلك. إنّ الحدّ الأدنى المعقول للمساحة المخصّصة للعمليات غير الأساسية هو 4 ميغابايت، ولكن يمكنك اختيار مساحة أكبر حسب الحاجة.
حجم الأقسام الديناميكية
قبل الأقسام الديناميكية، كان يتم تخصيص أحجام أكبر من اللازم للأقسام لأجل التأكّد من توفّر مساحة كافية للتحديثات المستقبلية. تم أخذ الحجم الفعلي كما هو، وكان لدى معظم الأقسام المخصّصة للقراءة فقط قدر من المساحة الفارغة في نظام الملفات. في الأقسام الديناميكية، تكون هذه المساحة الفارغة غير قابلة للاستخدام ويمكن استخدامها لتوسيع الأقسام أثناء عملية تحديث البرامج من خلال الهواء. من المهم التأكّد من أنّ الأقسام لا تُهدر المساحة وأنّه يتم تخصيص الحد الأدنى من الحجم الممكن لها.
بالنسبة إلى صور ext4 للقراءة فقط، يخصّص نظام الإنشاء تلقائيًا الحد الأدنى للحجم في حال عدم تحديد حجم قسم ثابت. يلائم نظام الإنشاء الصورة بحيث يكون لدى نظام الملفات أقل مساحة غير مستخدَمة ممكنة. ويضمن ذلك عدم إهدار الجهاز للمساحة التي يمكن استخدامها لتحديثات البرامج التلقائية.
بالإضافة إلى ذلك، يمكن ضغط صور ext4 بشكل أكبر من خلال تفعيل ميزة إزالة تكرار البيانات على مستوى الكتل. لتفعيل هذا الخيار، استخدِم الإعدادات التالية:
BOARD_EXT4_SHARE_DUP_BLOCKS := true
إذا لم تكن عملية تخصيص الحد الأدنى لحجم القسم تلقائية،
هناك طريقتان للتحكّم في حجم القسم. يمكنك تحديد
الحد الأدنى للمساحة الفارغة باستخدام
BOARD_partitionIMAGE_PARTITION_RESERVED_SIZE
،
أو يمكنك تحديد
BOARD_partitionIMAGE_PARTITION_SIZE
لفرض
حجم معيّن على الأقسام الديناميكية. لا يُنصح باستخدام أي من هذين الخيارَين
إلا عند الضرورة.
مثلاً:
BOARD_PRODUCTIMAGE_PARTITION_RESERVED_SIZE := 52428800
يؤدي ذلك إلى فرض مساحة غير مستخدَمة تبلغ
50 ميغابايت على نظام الملفات في product.img
.
التغييرات في وضع "النظام بصفتها الجذر"
يجب ألا تستخدم الأجهزة التي تعمل بالإصدار 10 من نظام التشغيل Android إذن الوصول إلى الجذر.
يجب ألا تستخدم الأجهزة التي تتضمّن أقسامًا ديناميكية (سواء كانت تعمل باستخدام أقسام ديناميكية أو تم تركيبها بعد الشراء) ميزة "النظام بصفتها الجذر". لا يمكن لنظام التشغيل Linux
تفسير قسم super
، وبالتالي لا يمكنه تركيب
system
نفسه. يتم الآن تركيب system
بواسطة
المرحلة الأولى init
، التي تقع في ذاكرة الوصول العشوائي.
لا تضبط BOARD_BUILD_SYSTEM_ROOT_IMAGE
. في
الإصدار 10 من Android، لا تُستخدَم العلامة
BOARD_BUILD_SYSTEM_ROOT_IMAGE
إلا للتفريق بين ما إذا كان النظام قد تم تثبيته بواسطة النواة أو
المرحلة الأولى من init
في ذاكرة التخزين المؤقت.
يؤدي ضبط BOARD_BUILD_SYSTEM_ROOT_IMAGE
على true
إلى حدوث خطأ في الإنشاء عندما يكون
PRODUCT_USE_DYNAMIC_PARTITIONS
هو true
أيضًا.
عند ضبط BOARD_USES_RECOVERY_AS_BOOT
على true، يتم إنشاء
صورة الاسترداد كملف boot.img يحتوي على
ملف ramdisk الخاص بعملية الاسترداد. في السابق، كان مُشغِّل الإقلاع يستخدِم وسيطة سطر الأوامر skip_initramfs
kernel
لتحديد الوضع الذي سيتم التمهيد إليه. بالنسبة إلى
أجهزة Android 10، يجب ألا ينقل مشغّل الإقلاع
skip_initramfs
إلى سطر أوامر النواة. بدلاً من ذلك، يجب أن يمر bootloader
باختبار androidboot.force_normal_boot=1
لتخطّي وضع الاسترداد
وتشغيل نظام Android العادي. يجب أن تستخدم الأجهزة التي تعمل بالإصدار 12 من نظام التشغيل Android
أو الإصدارات الأحدث bootconfig لاجتياز androidboot.force_normal_boot=1
.
تغييرات في إعدادات بروتوكول AVB
عند استخدام Android Verified Boot 2.0، إذا لم يكن الجهاز يستخدم وصفات القسم chained، ليس من الضروري إجراء أي تغيير. في حال استخدام أقسام متسلسلة وكان أحد الأقسام التي تم إثبات ملكيتها ديناميكيًا، تكون التغييرات ضرورية.
في ما يلي مثال على الإعداد لجهاز يربط
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: لا تبحث إلا عن معرّفات GUID الخاصة بالأقسام عندما تحتاج إليها سطر الأوامر ".
- 5abd6bc2578968d24406d834471adfd995a0c2e9 — "السماح بعدم توفّر قسم النظام"
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 — "Fix AvbSlotVerifyData->cmdline might be NULL"
في حال استخدام أقسام متسلسلة، يجب تضمين تصحيح إضافي:
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: تتيح استخدام ملفات vbmeta في بداية القسم".
التغييرات في سطر أوامر النواة
يجب إضافة مَعلمة جديدة، androidboot.boot_devices
،
إلى سطر أوامر kernel. يستخدم 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
، التي تمّ طرحها في الإصدار 10 من Android، والتي تشير إلى أنّه يجب تركيب قسم في المرحلة الأولى. -
قد يحدّد أحد الأقسام
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 إلى ذاكرة الوصول العشوائي (RAM) في المرحلة الأولى.
تغييرات 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
لا يفهم مشغّل الإقلاع (أو أي أداة فلاش غير مخصّصة لمساحة المستخدم) الأقسام الديناميكية، لذا لا يمكنه فلاشها. لحلّ هذه المشكلة، يجب أن تستخدم الأجهزة تنفيذًا لبروتوكول fastboot في مساحة المستخدم يُسمى fastbootd.
لمزيد من المعلومات حول كيفية تنفيذ fastbootd، يُرجى الاطّلاع على مقالة نقل Fastboot إلى مساحة المستخدم.
adb remount
بالنسبة إلى المطوّرين الذين يستخدمون إصدارات eng أو userdebug، يكون adb remount
مفيدًا للغاية لإجراء عمليات تكرار سريعة. تشكل الأقسام الديناميكية
مشكلة لجهاز adb remount
لأنّه لم تعُد هناك مساحة
فارغة في كل نظام ملفات. لحلّ هذه المشكلة، يمكن للأجهزة تفعيل
overlayfs. ما دامت هناك مساحة خالية في القسم الفائق،
adb remount
ينشئ تلقائيًا قسمًا مؤقتًا ديناميكيًا
ويستخدم overlayfs للعمليات الكتابية. يتم تسمية القسم المؤقت
باسم scratch
، لذا لا تستخدِم هذا الاسم للأقسام
الأخرى.
لمزيد من المعلومات حول كيفية تفعيل overlayfs، يُرجى الاطّلاع على overlayfs README في AOSP.
ترقية أجهزة 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_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;
للاطّلاع على عمليات الضبط الأخرى، يُرجى الاطّلاع على مقالة تنفيذ الإعدادات الخاصة بالأقسام الديناميكية على الأجهزة الجديدة.
لمزيد من المعلومات عن تحديثات الأجهزة القديمة، يُرجى الاطّلاع على التحديث عبر الهواء لأجهزة A/B بدون أقسام ديناميكية.
صور المصنع
بالنسبة إلى الأجهزة التي تعمل بنظام التشغيل الذي يتيح استخدام الأقسام الديناميكية، تجنَّب استخدام أداة fastboot في مساحة المستخدم لتثبيت صور المصنع، لأنّ عملية التمهيد إلى مساحة المستخدم تتم ببطء مقارنةً بطرق تثبيت الصور الأخرى.
لحلّ هذه المشكلة، ينشئ make dist
الآن صورة إضافية
super.img
يمكن إعادة تحميلها مباشرةً إلى القسم super. ويجمع القسم تلقائيًا محتويات القسمين
المنطقيَين، ما يعني أنّه يحتوي على system.img
vendor.img
وما إلى ذلك، بالإضافة إلى البيانات الوصفية للقسم super
. يمكن إعادة تحميل هذه الصورة مباشرةً على القسم
super
بدون أي أدوات إضافية أو باستخدام
fastbootd. بعد الإنشاء، يتم وضع super.img
في
${ANDROID_PRODUCT_OUT}
.
بالنسبة إلى الأجهزة التي تعمل بنظام A/B والتي يتم تشغيلها باستخدام أقسام ديناميكية،
super.img
يحتوي على صور في خانة A. بعد فلاش
الصورة الفائقة مباشرةً، ضَع علامة على الفتحة "أ" كمكان قابل للتشغيل قبل إعادة تشغيل
الجهاز.
بالنسبة إلى الأجهزة التي تم تركيبها لاحقًا، ينشئ make dist
مجموعة من
super_*.img
الصور التي يمكن إعادة تحميلها مباشرةً إلى
الأقسام المادية المقابلة. على سبيل المثال، make dist
ينشئ super_system.img
وsuper_vendor.img
عندما يكون BOARD_SUPER_PARTITION_BLOCK_DEVICES
هو مورِّد
النظام. يتم وضع هذه الصور في مجلد OTA في
target_files.zip
.
ضبط مساحة تخزين جهاز "محاكي الأجهزة"
تتيح عملية التقسيم الديناميكي استخدام عدد من عناصر أداة ربط الأجهزة غير الحتمية. قد لا يتم إنشاء جميع هذه العناصر على النحو المتوقّع، لذا عليك تتبُّع جميع عمليات التثبيت وتعديل سمات 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
في kernel كافيًا إلى أن يتم استبداله من خلال النصوص البرمجية 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}