Re: implementing mmap

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



vinit dhatrak wrote, Tuesday 22 September 2009:
> You may want to take a look at this page,
> http://www.scs.ch/~frey/linux/memorymap.html

Already did. In fact my code was pretty similar, I took this example:
http://www.captain.at/howto-linux-device-driver-mmap.php
that refers to your link.

> If you could share exact code, that would be easy to debug the problem
> you are facing.

Right, attaching both device and test code.
( that's the version with __get_free_pages(), but it shouldn't change 
anything... )

Thanks.
-- 
-gaspa-
-----------------------------------------------
-------- https://launchpad.net/~gaspa ---------
------ HomePage: iogaspa.altervista.org -------
-Il lunedi'dell'arrampicatore: www.lunedi.org -
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define SIZE 1024

int main(void){
    int fd=0,i;
    unsigned char* mmapped_ptr=NULL;

    fd = open("/dev/skeleton",O_RDWR | O_SYNC);

    printf("opened fd: %d\n",fd);

    mmapped_ptr = mmap(NULL,SIZE,PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED ,fd,0);
    if( mmapped_ptr == MAP_FAILED ) 
        perror("BOH");

    printf("file mmap'd at %p \n",mmapped_ptr);

    for( i=0; i < SIZE; i++){
        printf(" i=%d, mmap[%d]=%d\n",i,i,mmapped_ptr[i]);
    }
    printf("all done\n");
}
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/vmalloc.h>
#include <linux/mman.h>
#include <linux/slab.h>

#define DEVICEMAJOR 240
#define DEVICENAME "mmaptest"

static unsigned long pages_area = NULL;

#define LEN (64*1024)

static int mmaptest_open (struct inode *inode, struct file *file) {
	printk("mmaptest_open\n");
	return 0;
}

static int mmaptest_release (struct inode *inode, struct file *file) {
	printk("mmaptest_release\n");
	return 0;
}

static int mmaptest_mmap(struct file * filp, struct vm_area_struct * vma) {
	int ret;
        ret = remap_pfn_range(vma, vma->vm_start,
               virt_to_phys((void*)pages_area) >> PAGE_SHIFT,
               vma->vm_end-vma->vm_start, vma->vm_page_prot);
	if(ret != 0) {
		return -EAGAIN;
	}
	return 0;
}

struct file_operations mmaptest_fops = {
	.owner	=	THIS_MODULE,
	.mmap		=	mmaptest_mmap,
	.open		=	mmaptest_open,
	.release	=	mmaptest_release,
};

// initialize module
static int __init mmaptest_init_module (void) {
	int i;
	printk("initializing module\n");
	
	i = register_chrdev (DEVICE_MAJOR, DEVICE_NAME, &mmaptest_fops);
	if (i != 0) return - EIO;
	
    pages_area = __get_free_pages( GFP_KERNEL | GFP_DMA, get_order(LEN) );
    if (pages_area){
        printk("Get_free_pages successfull: %p - %d pages.\n",pages_area,get_order(LEN));
        printk(" virt to phys addr. -> %p \n", virt_to_phys(pages_area) );
    }
    else{
	    unregister_chrdev (DEVICE_MAJOR, DEVICE_NAME);
        printk("ERROR on getting pages\n");
        return -ENOMEM;
    }

	// fill allocated memory with chars
	for( i = 0; i < LEN; i++) {
		((unsigned char*)pages_area)[i] = (unsigned char)i;
	}
    printk("TEST: ");
	for( i = 0; i < 20; i++) {
		printk(" %d ",( (unsigned char*)pages_area)[i]);
	}
    printk("\n");

	return 0;
}

// close and cleanup module
static void __exit mmaptest_cleanup_module (void) {
	printk("cleaning up module\n");
    __free_pages(pages_area,get_order(LEN));
	unregister_chrdev (DEVICE_MAJOR, DEVICE_NAME);
}

module_init(mmaptest_init_module);
module_exit(mmaptest_cleanup_module);
MODULE_AUTHOR("Gaspa");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MMap test");

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux