मैं लिनक्स कर्नेल से मेमोरी का एक ब्लॉक कैसे आरक्षित कर सकता हूं?


25

मेरे पास एक उपकरण है जिसे मेमोरी के एक ब्लॉक की आवश्यकता है जो ओएस हस्तक्षेप के बिना पूरी तरह से इसके लिए आरक्षित है। क्या BIOS या ओएस को बताने का कोई तरीका है कि मेमोरी का एक ब्लॉक आरक्षित है, और इसका उपयोग नहीं करना चाहिए?

मैं एक खुले मशीन पर इस उपकरण का उपयोग कर रहा हूँ।

जवाबों:


23

आप जो मांग रहे हैं उसे डीएमए कहा जाता है। इस मेमोरी को आरक्षित करने के लिए आपको एक ड्राइवर लिखना होगा।

हां, मुझे लगता है कि आपने कहा था कि आप ओएस को हस्तक्षेप नहीं करना चाहते हैं, और एक ड्राइवर ओएस का हिस्सा बन जाता है, लेकिन ड्राइवर के आरक्षण के अभाव में, कर्नेल का मानना ​​है कि यह सभी मेमोरी से संबंधित है। (जब तक आप कर्नेल को मेमोरी ब्लॉक को अनदेखा करने के लिए नहीं कहते हैं, हारून के जवाब के अनुसार, वह है)।

रुबिनी, कोरबेट और क्रोहा-हार्टमैन द्वारा " लिनक्स डिवाइस ड्राइवर्स, 3 / ई " के अध्याय 15 (पीडीएफ) में डीएमए और संबंधित विषय शामिल हैं।

यदि आप इसका HTML संस्करण चाहते हैं, तो मुझे अध्याय का दूसरा-संस्करण संस्करण कहीं और ऑनलाइन मिला। खबरदार है कि 2 संस्करण अब एक दशक से अधिक पुराना है, जब कर्नेल 2.4 नया था तब बाहर आया था। उन दिनों से कर्नेल की मेमोरी प्रबंधन सबसिस्टम पर बहुत काम किया गया है, इसलिए यह बहुत अच्छी तरह से लागू नहीं हो सकता है।


डीएमए के साथ मैं यह चुन सकता हूं कि किस भौतिक पते का उपयोग करना है? क्या कर्नेल मुझे स्मृति का एक सन्निहित ब्लॉक देगा? क्या यह हमेशा उपलब्ध रहने की गारंटी है?
नाथन फेलमैन

1
आपके प्रश्नों का उत्तर पीडीएफ के पृष्ठ ४४२ पर दिया जा रहा है जो मैंने आपको बताया है।
वॉरेन यंग

24

यदि आप चाहते हैं कि OS इसे पूरी तरह से अनदेखा कर दे, तो आपको "" का उपयोग करके एक मेमोरी होल बनाने की आवश्यकता है memmapइस संदर्भ को देखें । उदाहरण के लिए, यदि आप 2GB बैरियर पर 512M चाहते हैं, तो आप memmap=512M$2Gअपनी कर्नेल कमांड लाइन पर रख सकते हैं ।

आपको dmesgचोरी करने के लिए एक सन्निहित छेद खोजने के लिए अपनी जांच करने की आवश्यकता होगी ताकि आप किसी भी उपकरण पर स्टंप न करें; यह आपके मदरबोर्ड + कार्ड के लिए विशिष्ट है।

यह वह जगह है नहीं कैसे ठीक ऐसा करने के लिए वॉरेन युवा के जवाब (कर्नेल ड्राइवरों + डीएमए) देखते हैं - काम करने के लिए सिफारिश की तरह से। मैं आपके द्वारा पूछे गए सटीक प्रश्न का उत्तर दे रहा हूं। यदि आप अंतिम उपयोगकर्ताओं के लिए इसे बनाने की योजना बनाते हैं, तो वे आपसे घृणा करेंगे यदि आप उनके साथ ऐसा करते हैं ... मेरा विश्वास करो, यही एकमात्र कारण है जो मुझे यह उत्तर पता था।


संपादित करें: यदि आप grub2 w / grubby (जैसे CentOS 7) का उपयोग कर रहे हैं, तो आपको $ बचने के लिए सुनिश्चित करने की आवश्यकता है । \पहले एक सिंगल होना चाहिए $। उदाहरण:

$ sudo -v
$ sudo grubby --update-kernel=ALL --args=memmap='128M\\$0x57EF0000'
$ sudo grubby --info $(sudo grubby --default-kernel) | grep memmap
args="ro crashkernel=auto ... memmap=128M\$0x57EF0000"

1
जबकि आपका जवाब सीधे मेरे सवाल का जवाब देता है, वारेन का जवाब इसके बारे में जाने का बेहतर तरीका लगता है। :-)
नाथन फ़ेलमैन

1
@WarrenYoung मुझे नहीं पता कि आप इसके साथ क्या करने वाले हैं। मैं uint8_t *ptr = 0x8000000अपने उदाहरण के साथ " " अनुमान लगाऊंगा? या कि segfault हो सकता है ... हुह, मैं वास्तव में नहीं जानता। फिर से, मुझे जवाब पता था क्योंकि मैं एक खराब डिज़ाइन किए गए पीसीआई कार्ड का एक अंतिम उपयोगकर्ता था, जहां मुझे 4 जी मार्क के नीचे मैन्युअल रूप से एक बफर आवंटित करना था और फिर एक ड्राइवर को बताना चाहिए कि वह स्थान कहां था; यह उपयोगकर्ता क्षेत्र से संभव नहीं हो सकता है।
आरोन डी। मरास्को

2
सिर्फ अनाज के लिए, मैं इस में थोड़ा गहरा लग रहा था, और ऐसा लगता है कि आप की जरूरत है MMAP_FIXED | MMAP_ANON। कस्टम डीएमए डिवाइस के बिना यहां खेलने के लिए, मैं यह नहीं कह सकता कि क्या यह वास्तव में ओपी चाहता था, लेकिन मेरे सेंटोस बॉक्स ने खुशी से मुझे 512 एमबी में 8 एमबी ब्लॉक दिया, जब मैंने memmap=8M$512MGRUB में कहा था। इसे रूट एक्सेस की भी आवश्यकता नहीं है, क्योंकि मुझे डर था कि यह हो सकता है। लेकिन यहां तक ​​कि अगर यह सही काम करता है, मुझे अभी भी लगता है कि आपको शायद एक ड्राइवर की आवश्यकता होगी जो बाधित और इस तरह से संभाल सके।
वॉरेन यंग

3
@ AaronD.Marasco: नहीं, mmap()'उपयोगकर्ता पृष्ठों को देखने से पहले डी पृष्ठों को शून्य कर दिया जाता है। यह सुरक्षा के लिए किया गया है, ताकि डेटा एक प्रक्रिया से अगली प्रक्रिया तक लीक न हो। ड्राइवर का उपयोग करने का एक और कारण, क्योंकि आपको ड्राइवर लोड समय पर डीएमए बफर की सामग्री को संरक्षित करने की आवश्यकता हो सकती है। ओह और वैसे, मनमाने ढंग से स्थित mmap()कॉल memmapकर्नेल बूट विकल्प के बिना भी सफल होता है , कम से कम जब तक कोई भी पहले से ही मेमोरी का उपयोग नहीं कर रहा है जहां आपने पूछा था। बूट विकल्प नि: संदेह सफलता की संभावना को बढ़ाता है, लेकिन यह कड़ाई से आवश्यक नहीं है।
वॉरेन यंग

1
@ आरोनड.मार्सको हम्म, ठीक है। दिलचस्प। उस लिंक के लिए धन्यवाद, यह एक अच्छा पढ़ा है।
वुडरो बारलो

5

एआरएम आधारित लिनक्स में कर्नेल से मेमोरी का एक ब्लॉक आरक्षित करने के लिए, आप reserved-memoryअपने डिवाइस ट्री (डीटीएस) फ़ाइल में नोड का उपयोग कर सकते हैं । कर्नेल प्रलेखन में ( यहाँ देखें ), एक उदाहरण है:

memory {
    reg = <0x40000000 0x40000000>;
};

reserved-memory {
    #address-cells = <1>;
    #size-cells = <1>;
    ranges;

    /* global autoconfigured region for contiguous allocations */
    linux,cma {
        compatible = "shared-dma-pool";
        reusable;
        size = <0x4000000>;
        alignment = <0x2000>;
        linux,cma-default;
    };

    display_reserved: framebuffer@78000000 {
        reg = <0x78000000 0x800000>;
    };

    multimedia_reserved: multimedia@77000000 {
        compatible = "acme,multimedia-memory";
        reg = <0x77000000 0x4000000>;
    };
};

0

अपनी वर्तमान सेटिंग की जाँच करने के लिए पहले इस कमांड को दर्ज करें:

sysctl vm.min_free_kbytes

सेट मान बदलने के लिए, संपादित करें /etc/sysctl.conf। लाइन के लिए देखो:

vm.min_free_kbytes=12888

यदि यह मौजूद नहीं है, तो इसे बनाएं (अपने इच्छित मूल्य के साथ)। निम्नलिखित मान स्वीकार्य हैं:

8192
12288
16384
20480

8M बेहद रूढ़िवादी है; यह आराम से 16M पर बैठ सकता है। एक बार जब आप मान बदलते हैं, तो इसे चलाएं और रिबूट की आवश्यकता नहीं है:

sudo sysctl -p

2
कृपया अपनी पोस्ट खाली न करें; या तो इसे हटा दें या इसे आपके लिए निकालने के लिए मॉडरेटर के लिए ध्वजांकित करें।
जसोनव्रीयन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.