2011-11-21 10 views
5

मैं 'mem_map' शुरू होने वाली भौतिक स्मृति को पढ़ने के लिए उपयोगकर्ता स्थान में mmap का उपयोग करने का प्रयास कर रहा हूं। यह एक सरणी है जिसमें सभी भौतिक पृष्ठ शामिल हैं। यह एक i386 मशीन 3.0 कर्नेल चल रहा है।mmap: ऑपरेशन की अनुमति नहीं है

कोड इस तरह है:

.... 

//define page size 
// 
#define PAGE_SIZE 0x1000 //4096 bytes 
#define PAGE_MASK (PAGE_SIZE - 1) 

.... 

    /* open /dev/mem file*/ 
    if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) { 
     printf("/dev/mem could not be opened.\n"); 
    perror("open"); 
     exit(1); 
    } else { 
    printf("/dev/mem opened.\n"); 
    } 

    /* Map one page */ 
    printf(" mem_map is at physical addr: 0x%x\n", mem_map_phy_addr); 

    map_base = mmap(0, PAGE_SIZE, PROT_READ, MAP_SHARED, fd, (mem_map_phy_addr & ~PAGE_MASK)); //mem_map_phy_addr is at 0x356f2000 

    if(map_base == (void *) -1) { 
    printf("Memory map failed. err num = %d\n",errno); 
    perror("mmap"); //failed here 
    } else { 
    printf("Memory mapped at address %p.\n", map_base); 
    } 

मैं एक रूट के रूप में इस भाग गया। उत्पादन होता है:

/dev/mem opened. 
mem_map is at physical addr: 0x356f2000 
Memory map failed. err num = 1 
mmap: Operation not permitted 

यह सुनिश्चित हो, मैं इस समस्या googled और मेरी /etc/sysctl.conf फ़ाइल में निम्न पंक्ति कहा:

vm.mmap_min_addr = 0 

लेकिन यह या तो काम नहीं करता।

कोई भी जानता है कि इस तरह mem_map ऑपरेशन की अनुमति क्यों नहीं है और मैं इसके आसपास कैसे हो सकता हूं?

धन्यवाद।

+2

FYI करें, यह 'x और ~ PAGE_MASK' उपयोग करने के लिए सही नहीं है। 64 बिट सिस्टम पर, यह 32 बिट्स पर पते को छोटा कर देगा। पूरक लेने से पहले आपको 'uintptr_t' या समकक्ष विस्तृत प्रकार पर डालना होगा। –

+0

क्या आपने mmap_min_addr के मान को सेट करने के लिए sysctl कमांड चलाया था या केवल conf फ़ाइल संपादित करें? आपको दोनों करना है। –

+0

हाँ, मैंने बाद में "sysctl -p" किया था। – user899159

उत्तर

8

ऐसा लगता है जैसे कर्नेल CONFIG_STRICT_DEVMEM सक्षम के साथ संकलित किया गया है। 1 एमबी (आईआईआरसी) से ऊपर उपयोगकर्ता स्थान तक पहुंच (संभावित रूप से संवेदनशील) भौतिक स्मृति को रोकने के लिए यह एक सुरक्षा सुविधा है। आप sysctl dev.mem.restricted के साथ इसे अक्षम करने में सक्षम हो सकते हैं।

+0

हां, मेरे .config में CONFIG_STRICT_DEVMEM = y है। मैं "sysctl dev.mem.restricted" का उपयोग कैसे करूं? मैंने कोशिश की और त्रुटि है:/proc/sys/dev/mem/प्रतिबंधित: ऐसी कोई फ़ाइल या निर्देशिका नहीं। – user899159

+0

मुझे लगता है कि आपको कर्नेल को अक्षम विकल्प के साथ पुन: संकलित करना होगा। –

+0

ठीक है, मैंने कर्नेल को CONFIG_STRICT_DEVMEM बंद कर दिया है। अब मुझे एक नई त्रुटि है:/dev/mem खोला गया। mem_map भौतिक योजक पर है: 0x356db000 मेमोरी मानचित्र विफल हुआ। गलती संख्या = 22 mmap: अमान्य तर्क। ऐसा नहीं होता है अगर मैंने 0 पर भौतिक पता मैप करने का प्रयास किया। कोई सुझाव? - धन्यवाद। – user899159

0

मुझे ऐसी ही समस्या थी जब मैं आर्क लिनक्स के साथ एक एपीयू 2 सी 4 बोर्ड पर फ्लैश्रॉम का उपयोग करने की कोशिश कर रहा था।

sysctl विकल्प dev.mem.restricted मेरे सिस्टम में उपलब्ध नहीं था और स्वयं संकलित कर्नेल का उपयोग करने के लिए मेरे लिए कोई विकल्प नहीं था।

# /boot/grub/grub.cfg 
linux /boot/vmlinuz-linux iomem=relaxed 
बेशक

एक रिबूट इस समाधान के लिए nessesary है:

मैं ग्रब के माध्यम से relaxed को iomem Kernelparameter की स्थापना करके समस्या को हल काम किया।

संदर्भ:
https://www.reddit.com/r/libreboot/comments/6wvyry/flashrom_failures_to_access/
https://www.flashrom.org/FAQ
https://www.kernel.org/doc/Documentation/admin-guide/kernel-parameters.txt

संबंधित मुद्दे