يتم تنفيذ التقسيم الديناميكي باستخدام وحدة 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 مثالاً على جدول أقسام قبل وبعد تحويله إلى أقسام
ديناميكية.
التقسيمات الديناميكية المتوافقة هي:
- النظام
- المورّد
- المنتَج
- ملحقات النظام
- 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
.
بالنسبة إلى أجهزة 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
-
بالنسبة إلى أجهزة إطلاق ميزة "التجربة المتوفّرة على الأجهزة الافتراضية"، يجب ألا يتجاوز مجموع الحد الأقصى لحجم كل المجموعات:
BOARD_SUPER_PARTITION_SIZE
- الحد الأقصى لحجم المساحة المتوفّرة
راجِع مقالة تنفيذ ميزة "التجربة المتوفّرة على الأجهزة الافتراضية". -
بالنسبة إلى أجهزة إطلاق اختبار أ/ب، يجب أن يكون مجموع الحد الأقصى لحجم جميع المجموعات
هو:
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 الخاص بعملية الاسترداد. في السابق، كان برنامج الإقلاع يستخدم مَعلمة سطر الأوامر kernel skip_initramfs
لتحديد الوضع الذي تريد بدء تشغيله. بالنسبة إلى
أجهزة Android 10، يجب ألا ينقل مشغّل الإقلاع
skip_initramfs
إلى سطر أوامر النواة. بدلاً من ذلك، يجب أن يمر bootloader
باختبار 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: لا تُجري طلب بحث إلا عن معرّفات GUID الخاصة بالقسم عندما تحتاج إليها سطر الأوامر ".
- 5abd6bc2578968d24406d834471adfd995a0c2e9 — "السماح بغياب قسم النظام"
- 9ba3b6613b4e5130fa01a11d984c6b5f0eb3af05 — "Fix AvbSlotVerifyData->cmdline might be NULL"
في حال استخدام أقسام متسلسلة، يجب تضمين تصحيح إضافي:
- 49936b4c0109411fdd38bd4ba3a32a01c40439a9 — "libavb: دعم vbmeta blobs في بداية التقسيم".
التغييرات على سطر أوامر النواة
يجب إضافة مَعلمة جديدة، 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
اللتين تم تقديمهما في 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 إلى ذاكرة الوصول العشوائي (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 التي لا تحتوي على أقسام ديناميكية.
صور المصنع
في حال تشغيل جهاز متوافق مع الأقسام الديناميكية، تجنَّب استخدام userspace Fastboot لتثقيف الصور الأصلية، لأنّ التشغيل على مساحة المستخدم أبطأ من الطرق الأخرى الوامضة.
لحلّ هذه المشكلة، ينشئ make dist
الآن صورة
super.img
إضافية يمكن إرفاقها مباشرةً في القسم
الفائق. ويجمع القسم تلقائيًا محتويات القسمين
المنطقيَين، ما يعني أنّه يحتوي على 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}