حجم الصفحة هو مستوى التفاصيل الذي يدير نظام التشغيل الذاكرة عنده. تتوافق معظم وحدات المعالجة المركزية الحالية مع حجم صفحة يبلغ 4 كيلوبايت، لذا تم تصميم نظام التشغيل Android والتطبيقات وتحسينها على مرّ السنين لتعمل مع حجم صفحة يبلغ 4 كيلوبايت. تتيح وحدات المعالجة المركزية (CPU) المستندة إلى بنية ARM استخدام حجم الصفحة الأكبر البالغ 16 كيلوبايت، وبدءًا من الإصدار 15 من نظام التشغيل Android، يتيح مشروع Android مفتوح المصدر (AOSP) إنشاء إصدارات Android بحجم صفحة يبلغ 16 كيلوبايت أيضًا. يستخدم هذا الخيار ذاكرة إضافية، ولكنّه يحسّن أداء النظام. اعتبارًا من نظام التشغيل Android 15، لن يكون هذا الخيار مفعَّلاً تلقائيًا، ولكن سيتوفّر كوضع مطوّرين أو خيار مطوّرين لمصنّعي المعدات الأصلية ومطوّري التطبيقات للاستعداد للتبديل إلى الوضع الذي يستخدم صفحات بحجم 16 كيلوبايت في كل مكان في المستقبل.
يتيح الإصدار 15 من نظام التشغيل Android والإصدارات الأحدث إنشاء Android بمحاذاة ELF بحجم 16 كيلوبايت، ما يتوافق مع نواة بحجم 4 كيلوبايت و16 كيلوبايت بدءًا من android14-6.1
.
عند استخدامها مع نواة بحجم 16 كيلوبايت، يستخدم هذا الإعداد ذاكرة إضافية، ولكنّه يحسّن أداء النظام.
ضبط Android على 16 كيلوبايت
لا تتوافق صفحات الذاكرة بحجم 16 كيلوبايت إلا مع أهداف arm64
التي تتضمّن نِوى بحجم 16 كيلوبايت.
ومع ذلك، يتوفّر أيضًا خيار محاكاة مساحة مستخدم تبلغ 16 كيلوبايت على x86_64
لجهاز Cuttlefish.
مساحة النواة
بالنسبة إلى أهداف arm64
، إذا كنت تستخدم
Kleaf
لإنشاء النواة، تنشئ --page_size=16k
النواة في وضع 16 كيلوبايت.
إذا كنت تستخدم إعدادات نواة Linux مباشرةً، يمكنك اختيار صفحات بحجم 16 كيلوبايت من خلال ضبط CONFIG_ARM64_16K_PAGES
بدلاً من CONFIG_ARM64_4K_PAGES
.
مساحة المستخدم
لتفعيل إمكانية استخدام صفحات بحجم 16 كيلوبايت في مساحة المستخدم على Android، اضبط خيارات الإنشاء التالية على منتجك:
- تزيل
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
تعريفPAGE_SIZE
، وتجعل المكوّنات تحدّد حجم الصفحة في وقت التشغيل. PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
ما يضمن إنشاء ملفات ELF للمنصة بمحاذاة 16 كيلوبايت. هذا الحجم الأكبر من اللازم مخصّص للتوافق مع الإصدارات المستقبلية. باستخدام محاذاة ELF بحجم 16 كيلوبايت، يمكن للنواة دعم أحجام الصفحات 4 كيلوبايت/16 كيلوبايت.
التحقّق من علامات الإنشاء
بعد اختيار هدف lunch
، تأكَّد من إعداد علامات الإنشاء بشكل صحيح في البيئة:
$ source build/envsetup.sh
$ lunch target
$ get_build_var TARGET_MAX_PAGE_SIZE_SUPPORTED
16384
$ get_build_var TARGET_NO_BIONIC_PAGE_SIZE_MACRO
true
إذا عرض الأمران السابقان 16384
وtrue
على التوالي، يعني ذلك أنّه تم إعداد علامات الإنشاء بشكل صحيح للعمل مع نواة بحجم 16 كيلوبايت. ومع ذلك، حتى إذا اجتازت عملية الإنشاء الاختبار، قد تظل هناك مشاكل في وقت التشغيل بسبب الاختلافات في بيئة تبلغ سعتها 16 كيلوبايت.
برمجة النظام بحجم صفحة يبلغ 16 كيلوبايت
إنّ الغالبية العظمى من الرموز البرمجية على أي جهاز يعمل بنظام التشغيل Android لا تتعامل بشكل مباشر مع حجم الصفحة. ومع ذلك، بالنسبة إلى الرمز الذي يتعامل مع الصفحات، يتغيّر سلوك تخصيص الذاكرة في النواة، وعليك مراعاة ذلك لكتابة رمز برمجي ليس متوافقًا فحسب، بل أيضًا بأعلى أداء وأقل استهلاكًا للموارد.
إذا طلبت mmap
في منطقة تبلغ سعتها 1 كيلوبايت أو 2 كيلوبايت أو ما يصل إلى 4 كيلوبايت على نظام 4 كيلوبايت، سيحجز النظام 4 كيلوبايت لتنفيذ ذلك. بعبارة أخرى، عند طلب ذاكرة من النواة، يجب أن تقرّب النواة دائمًا حجم الذاكرة المطلوبة إلى أقرب حجم صفحة. على سبيل المثال، إذا خصّصت منطقة بحجم 5 كيلوبايت في منطقة بحجم 4 كيلوبايت، ستخصّص النواة 8 كيلوبايت.
في نواة بحجم 16 كيلوبايت، تكون "الأجزاء الأخيرة" الإضافية من الصفحات أكبر. على سبيل المثال، سيتم تخصيص 16 كيلوبايت عند استخدام جميع عمليات التخصيص هذه، بدءًا من 1 كيلوبايت إلى 5 كيلوبايت، مع نواة 16 كيلوبايت. إذا طلبت 17 كيلوبايت، سيتم تخصيص 32 كيلوبايت.
على سبيل المثال، في نظام 4 كيلوبايت، لا بأس من تخصيص منطقتَين مجهولتين للقراءة والكتابة بحجم 4 كيلوبايت. في المقابل، عند استخدام نواة بحجم 16 كيلوبايت، سيؤدي ذلك إلى تخصيص صفحتَين أو 32 كيلوبايت. في نواة بحجم 16 كيلوبايت، يمكن دمج هذه المناطق في صفحة واحدة قابلة للقراءة أو الكتابة، وبالتالي يتم استخدام 16 كيلوبايت فقط، ما يؤدي إلى إهدار 8 كيلوبايت مقارنةً بحالة النواة بحجم 4 كيلوبايت. لتقليل استخدام الذاكرة بشكل أكبر، يمكن دمج المزيد من الصفحات. في الواقع، في نظام 16 كيلوبايت تم تحسينه إلى أقصى حد، تتطلّب صفحات 16 كيلوبايت ذاكرة أقل من أنظمة 4 كيلوبايت لأنّ جدول الصفحات يبلغ ربع حجم الذاكرة نفسها.
عند استخدام mmap
، احرص على تقريب الحجم المطلوب إلى أقرب حجم صفحة. ويضمن ذلك أن يكون مقدار الذاكرة الكامل الذي يخصّصه نظام التشغيل
مرئيًا مباشرةً لمساحة المستخدم في قيم وقت التشغيل، بدلاً من أن يتم
طلبه ضمنيًا وأن يكون متاحًا ضمنيًا أو عن طريق الخطأ.
إنشاء مكتبات مشتركة مع محاذاة ELF بحجم 16 كيلوبايت
لإنشاء مكتبات مشترَكة تشكّل جزءًا من مشروع Android، تكفي الإعدادات السابقة في تفعيل حجم الصفحة البالغ 16 كيلوبايت:
PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384
لإنشاء مكتبات مشترَكة غير مضمّنة في مشروع Android، عليك تمرير علامة الرابط التالية:
-Wl,-z,max-page-size=16384
التحقّق من الثنائيات والإنشاءات المسبقة لمحاذاة ملفات ELF بحجم 16 كيلوبايت
وأفضل طريقة للتحقّق من التوافق وسلوك وقت التشغيل هي الاختبار والتشغيل على نواة مجمّعة بحجم 16 كيلوبايت. ومع ذلك، من أجل رصد بعض المشاكل في وقت مبكر، يمكنك اتّخاذ الإجراءات التالية:
بدءًا من الإصدار 16 من نظام التشغيل Android، يمكنك ضبط
PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := true
في وقت الإنشاء. استخدِمignore_max_page_size: true
فيAndroid.bp
وLOCAL_IGNORE_MAX_PAGE_SIZE := true
فيAndroid.mk
لتجاهل هذه الأخطاء مؤقتًا. تتحقّق هذه الإعدادات من صحة جميع عمليات الإنشاء المسبق وتتيح لك رصد الحالات التي يتم فيها تعديل إحدى عمليات الإنشاء المسبق ولكنها لا تتوافق مع حجم 16 كيلوبايت.يمكنك تشغيل
atest elf_alignment_test
الذي يتحقّق من محاذاة ملفات ELF على الجهاز عند تشغيل الأجهزة التي تعمل بالإصدار 15 من نظام التشغيل Android والإصدارات الأحدث.