16 केबी वाला पेज साइज़

पेज का साइज़, वह ग्रेन्यूलैरिटी होती है जिस पर ओएस, मेमोरी को मैनेज करता है. आजकल ज़्यादातर सीपीयू, 4 केबी वाले पेज साइज़ के साथ काम करते हैं. इसलिए, Android OS और ऐप्लिकेशन को 4 केबी वाले पेज साइज़ के साथ काम करने के लिए बनाया और ऑप्टिमाइज़ किया गया है. ARM सीपीयू, 16 केबी के बड़े पेज साइज़ के साथ काम करते हैं. साथ ही, Android 15 से AOSP में, 16 केबी के पेज साइज़ के साथ Android बनाने की सुविधा भी उपलब्ध है. इस विकल्प में ज़्यादा मेमोरी का इस्तेमाल होता है, लेकिन इससे सिस्टम की परफ़ॉर्मेंस बेहतर होती है. Android 15 में, यह विकल्प डिफ़ॉल्ट रूप से चालू नहीं होता. हालांकि, यह डेवलपर मोड या ओईएम और ऐप्लिकेशन डेवलपर के लिए डेवलपर विकल्प के तौर पर उपलब्ध है. इससे वे आने वाले समय में, हर जगह 16 केबी मोड पर स्विच करने की तैयारी कर सकते हैं.

Android 15 और इसके बाद के वर्शन में, 16 केबी के ईएलएफ़ अलाइनमेंट के साथ Android बनाने की सुविधा उपलब्ध है. यह 4 केबी और 16 केबी वाले कर्नेल के साथ काम करती है. यह सुविधा android14-6.1 से शुरू होती है. 16 केबी कर्नेल के साथ इस्तेमाल करने पर, इस कॉन्फ़िगरेशन में ज़्यादा मेमोरी का इस्तेमाल होता है. हालांकि, इससे सिस्टम की परफ़ॉर्मेंस बेहतर होती है.

Android को 16 केबी पर सेट करना

16 केबी वाले पेज, सिर्फ़ उन arm64 टारगेट पर काम करते हैं जिनमें 16 केबी वाले कर्नेल होते हैं. हालांकि, Cuttlefish के लिए x86_64 पर 16 केबी यूज़रस्पेस को सिम्युलेट करने का विकल्प भी है.

कर्नेल स्पेस

अगर arm64 टारगेट के लिए, कर्नेल बनाने के लिए Kleaf का इस्तेमाल किया जाता है, तो --page_size=16k कर्नेल को 16 केबी मोड में बनाता है. अगर Linux कर्नल कॉन्फ़िगरेशन का सीधे तौर पर इस्तेमाल किया जा रहा है, तो CONFIG_ARM64_4K_PAGES के बजाय CONFIG_ARM64_16K_PAGES सेट करके, 16 केबी वाले पेज चुने जा सकते हैं.

उपयोगकर्ता स्पेस

Android के उपयोगकर्ता स्पेस में 16 केबी पेज साइज़ की सुविधा चालू करने के लिए, अपने प्रॉडक्ट पर ये बिल्ड विकल्प सेट करें:

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true, PAGE_SIZE define को हटा देता है. साथ ही, कॉम्पोनेंट को रनटाइम के दौरान पेज का साइज़ तय करने की अनुमति देता है.
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384 इससे यह पक्का किया जाता है कि प्लैटफ़ॉर्म की ईएलएफ़ फ़ाइलें, 16 केबी अलाइनमेंट के साथ बनाई गई हैं. यह साइज़, ज़रूरत से ज़्यादा है. ऐसा इसलिए है, ताकि आने वाले समय में यह फ़ाइल काम कर सके. 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 डिवाइस पर मौजूद ज़्यादातर कोड, सीधे तौर पर पेज के साइज़ से नहीं जुड़े होते. हालांकि, पेजों से जुड़े कोड के लिए, कर्नल की मेमोरी के बंटवारे का तरीका बदल जाता है. आपको इस बात का ध्यान रखना होगा, ताकि ऐसा कोड लिखा जा सके जो न सिर्फ़ काम करे, बल्कि ज़्यादा से ज़्यादा परफ़ॉर्म करे और कम से कम संसाधनों का इस्तेमाल करे.

अगर 4 केबी सिस्टम पर 1 केबी, 2 केबी या 4 केबी तक के क्षेत्र पर mmap कॉल किया जाता है, तो सिस्टम इसे लागू करने के लिए 4 केबी रिज़र्व करता है. दूसरे शब्दों में कहें, तो कर्नल से मेमोरी का अनुरोध करते समय, कर्नल को हमेशा अनुरोध की गई मेमोरी को पेज के साइज़ के हिसाब से राउंड अप करना चाहिए. उदाहरण के लिए, अगर 4 केबी के क्षेत्र पर 5 केबी का क्षेत्र असाइन किया जाता है, तो कर्नेल 8 केबी असाइन करता है.

16 केबी कर्नेल पर, पेजों के ये अतिरिक्त "टेल एंड" बड़े होते हैं. उदाहरण के लिए, 1 केबी से लेकर 5 केबी तक के सभी असाइनमेंट, 16 केबी कर्नेल के साथ इस्तेमाल किए जाने पर 16 केबी असाइन करेंगे. अगर आपने 17 केबी का अनुरोध किया है, तो 32 केबी मेमोरी असाइन की जाएगी.

उदाहरण के लिए, 4 केबी वाले सिस्टम पर, दो 4 केबी वाले रीड-राइट ऐनॉनमस रीजन को असाइन किया जा सकता है. हालांकि, 16 केबी कर्नेल पर, इससे दो पेज या 32 केबी मेमोरी असाइन होगी. अगर हो सके, तो 16 केबी कर्नेल पर इन क्षेत्रों को एक ही पेज में जोड़ा जा सकता है. इससे सिर्फ़ 16 केबी का इस्तेमाल होगा. हालांकि, 4 केबी कर्नेल के मुकाबले 8 केबी बर्बाद हो जाएंगे. मेमोरी के इस्तेमाल को और कम करने के लिए, ज़्यादा पेजों को एक साथ जोड़ा जा सकता है. दरअसल, ज़्यादा से ज़्यादा ऑप्टिमाइज़ किए गए 16 केबी सिस्टम पर, 16 केबी पेजों के लिए 4 केबी सिस्टम की तुलना में कम मेमोरी की ज़रूरत होती है. ऐसा इसलिए, क्योंकि पेज टेबल का साइज़, एक ही मेमोरी के लिए एक चौथाई होता है.

mmap का इस्तेमाल करते समय, पक्का करें कि आपने अनुरोध किए गए साइज़ को पेज के सबसे नज़दीकी साइज़ तक राउंड अप किया हो. इससे यह पक्का किया जा सकेगा कि कर्नल की ओर से मेमोरी का पूरा हिस्सा, रनटाइम वैल्यू में सीधे तौर पर उपयोगकर्ताओं को दिखे. इसके बजाय, यह हिस्सा सीधे तौर पर अनुरोध किया गया हो और सीधे तौर पर या गलती से ऐक्सेस किया जा सकता हो.

16 केबी ईएलएफ़ अलाइनमेंट के साथ शेयर की गई लाइब्रेरी बनाना

Android प्रोजेक्ट का हिस्सा बनने वाली शेयर की गई लाइब्रेरी बनाने के लिए, 16 केबी पेज साइज़ चालू करें में दी गई पिछली सेटिंग काफ़ी हैं:

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384

Android प्रोजेक्ट का हिस्सा न होने वाली शेयर की गई लाइब्रेरी बनाने के लिए, आपको इस लिंकर फ़्लैग को पास करना होगा:

-Wl,-z,max-page-size=16384

16 केबी ईएलएफ़ अलाइनमेंट के लिए, बाइनरी और प्रीबिल्ट की पुष्टि करना

अलाइनमेंट और रनटाइम के व्यवहार की पुष्टि करने का सबसे अच्छा तरीका यह है कि 16 केबी के कंपाइल किए गए कर्नेल पर टेस्ट किया जाए और उसे चलाया जाए. हालांकि, कुछ समस्याओं का पता पहले ही लगाने के लिए:

  • Android 16 से, PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := true को बिल्ड टाइम पर सेट किया जा सकता है. कुछ समय के लिए इन समस्याओं को अनदेखा करने के लिए, Android.bp में ignore_max_page_size: true और Android.mk में LOCAL_IGNORE_MAX_PAGE_SIZE := true का इस्तेमाल करें. इन सेटिंग की मदद से, सभी प्रीबिल्ट की पुष्टि की जाती है. साथ ही, यह पता लगाया जा सकता है कि कोई प्रीबिल्ट अपडेट किया गया है, लेकिन वह 16 केबी के हिसाब से नहीं है.

  • atest elf_alignment_test को चलाया जा सकता है. यह Android 15 और उसके बाद के वर्शन के साथ लॉन्च होने वाले डिवाइसों पर, डिवाइस पर मौजूद ईएलएफ़ फ़ाइलों के अलाइनमेंट की पुष्टि करता है.