2011-08-06 14 views
10

के साथ आवंटित एक कर्नेल बफर जो उपयोगकर्ता स्थान प्रक्रिया में मैपॉलोक के साथ आवंटित बफर का सही तरीका है? हो सकता है कि मुझे स्मृति मैपिंग अभी तक समझ में नहीं आया ... मैं एक कर्नेल मॉड्यूल लिखता हूं जो इस बफर को आवंटित करता है (उदाहरण के लिए 120 बाइट्स) और मैं इसे उपयोगकर्ता-स्पेस प्रक्रिया में पढ़ और लिखूंगा। जाहिर है मैंने एक चार डिवाइस बनाया और file_operations संरचना में mmap विधि लागू की। मेरे विधि है:mmap: उपयोगकर्ता स्थान में मैपिंग kmalloc

static int my_mmap(struct file *filp, struct vm_area_struct *vma) 
{ 
    //printk(KERN_INFO "Allocated virtual memory length = %d", vma->vm_end - vma->vm_start); 

    long unsigned int size = vma->vm_end - vma->vm_start; 

    if (remap_pfn_range(vma, vma->vm_start, 
         __pa(mem_area) >> PAGE_SHIFT, //what about vma->vm_pgoff? 
         size, 
         vma->vm_page_prot) < 0) 
    return -EAGAIN; 

    vma->vm_flags |= VM_LOCKED; 
    vma->vm_ops = &vmops; 
    vma->vm_flags |= VM_RESERVED; 

    my_vm_open(vma); 

    return 0; 
} 

जहां एक स्मृति क्षेत्र में mem_area अंक मॉड्यूल init पर kmalloc साथ आवंटित। क्षेत्र एक ही मूल्य से भरा है (उदाहरण के लिए 0x10)। सभी काम करता है लेकिन मुझे लगता है कि वहाँ कुछ इस कोड में गलत है:

  1. kmalloc एक सूचक है कि पेज मेल नहीं किया गया लौट सकता है और उस मामले, मुझे नहीं लगता है में, सही है तीसरे पैरामीटर का मान remap_pfn_range वास्तव में उपयोगकर्ता स्थान में मैंने गलत मान पढ़ा है। इसके बजाय यदि मैं __get_free_page का उपयोग करता हूं तो सभी काम करता है (क्योंकि फ़ंक्शन हमेशा एक संकेतक देता है जो पेज गठबंधन होता है) या जब kmalloc पृष्ठ को गठबंधन पॉइंटर देता है। मेमोरी मैपिंग मेमोरी क्षेत्रों के साथ काम करती है जो PAGE_SIZE के बहुगुणित हैं, तो क्या मुझे kmalloc का उपयोग करने के बजाय एक संपूर्ण पृष्ठ आवंटित करना चाहिए?

  2. जब my_mmap कहा जाता है, तो कर्नेल ने अभी तक कुछ पेज आवंटित किए हैं? मैं यह पूछता हूं क्योंकि मुझे कस्टम mmap विधि के कुछ कार्यान्वयन मिले हैं जो remap_pfn_range को vma->vm_pgoff के साथ तीसरे पैरामीटर के रूप में कॉल करते हैं ... यह कैसे उपयोगी हो सकता है? क्या यह पहले नए आवंटित पृष्ठ का पृष्ठ फ्रेम है? यदि मैं तीसरे पैरामीटर के रूप में पास करता हूं तो पेज फ्रेम जैसे मैं my_mmap में करता हूं, तो मुझे vma->vm_pgoff में पृष्ठ से शुरू होने वाले पेजों को मुक्त करना चाहिए?

  3. हालांकि मुझे mmap विधि का कार्यान्वयन मिला जो kmalloc के साथ आवंटित बफर को मानचित्रित करता है। बफर को सही ढंग से मैप करने के लिए एक ऑपरेशन (जिसे मैं अब के लिए अंडेस्टैंड नहीं करता) remap_pfn_range से पहले किया जाता है। मान लीजिए कि mem सूचक kmalloc द्वारा दिया, mem_area इस तरह से आरंभ नहीं हो जाता है:

    mem_area=(int *)(((unsigned long)mem + PAGE_SIZE - 1) & PAGE_MASK); 
    

तो mem_area की mem केवल mem अगर पेज गठबंधन है अन्यथा एक ही मान है शुरुआत में सूचक को शामिल करना चाहिए अगले पृष्ठ का। हालांकि, इस ऑपरेशन के साथ यदि मैं remap_pfn_range के तीसरे पैरा के रूप में पास करता हूं तो मूल्य __pa(mem_area) >> PAGE_SHIFT मैपिंग अच्छी तरह से काम करता है। क्यूं कर?

सभी को धन्यवाद!

+0

मेरे पास एक समान प्रश्न है लेकिन बूट पैरामीटर 'mmap' का उपयोग करने के साथ: http://stackoverflow.com/q/12790382/143897? क्या आप अपने कुछ निष्कर्ष प्रदान कर सकते हैं? धन्यवाद। –

+0

क्या आपको vm_operations_struct.fault के लिए यहां पेज गलती हैंडलर की आवश्यकता नहीं है? –

+0

न्यूनतम रननेबल उदाहरण: https://stackoverflow.com/questions/10760479/how-to-mmap-a-linux- कर्नेल- बफर-to-user-space/45645732#45645732 –

उत्तर

6
  1. हां, आपको पृष्ठों की पूरी संख्या आवंटित करनी चाहिए।

  2. नहीं, कर्नेल ने किसी भी पेज को आवंटित नहीं किया है। vm->vm_pgoff मैप किए जा रहे डिवाइस के भीतर अनुरोधित ऑफ़सेट है - यह उपयोगकर्ता स्पेस mmap() कॉल का अंतिम पैरामीटर है, बाइट्स से पृष्ठों तक अनुवादित है। आप शायद mem या kmem मिमीैप कार्यान्वयन देख रहे हैं, इस स्थिति में ऑफ़सेट भौतिक या रैखिक पृष्ठ का प्रतिनिधित्व करता है जो उपयोगकर्ता स्थान मानचित्र बनाना चाहता है।

  3. यह kmalloc() आवंटित बफर के भीतर केवल पृष्ठ-संरेखित बफर आवंटित कर रहा है।__get_free_pages() का उपयोग करके आप बेहतर हैं क्योंकि आप पहले से ही अनुमान लगा चुके हैं, मध्य-व्यक्ति को काट रहे हैं।

आप परीक्षण किया जाना चाहिए कि आकार मैप किए जा रहे अपने बफर से अधिक नहीं है।

+0

धन्यवाद आप के लिए कैफ धन्यवाद! मुझे अभी भी बिंदु संख्या 2 नहीं समझ रहा है ... मैंने 'mem' या' kmem' कार्यान्वयन को नहीं देखा है, लेकिन मुझे इसे लिनक्स डिवाइस ड्राइवर पुस्तक में मिला ... अब मुझे पता है कि 'vma-> vm_pgoff' है मैप किए जा रहे डिवाइस के भीतर ऑफसेट लेकिन अगर मैं 'remap_pfn_range' को तीसरे पैरामीटर 'vma-> vm_pgoff' के रूप में पास करता हूं, तो डिवाइस में कौन सी मेमोरी मैपिंग कर रहा हूं? – MirkoBanchi

+0

@caf मेरे पास एक समान प्रश्न है लेकिन बूट परम mmap का उपयोग करने के साथ: stackoverflow.com/q/12790382/143897? क्या आप अपने कुछ निष्कर्ष प्रदान कर सकते हैं? धन्यवाद। –

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