mapping ram memory to user space

Apr 19, 2006 0 Replies

hi, my system is powerpc. i am attempting to map logical address returned by kmalloc to the user program. the code below doesn't accomplish that task. please let me know what i am doing wrong...thank you in advance.



here's the driver:


#include #include #include #include



#include /* printk() */ #include /* kmalloc() */ #include /* everything... */ #include /* error codes */ #include /* size_t */ #include #include #include #include



#include #include static unsigned char *buffer; static int simple_major = 0; module_param(simple_major, int, 0); MODULE_AUTHOR("Jonathan Corbet"); MODULE_LICENSE("Dual BSD/GPL");



/* * Open the device; in fact, there's nothing to do here. */ static int simple_open (struct inode *inode, struct file *filp) { return 0; }


/* * Closing is just as simpler. */ static int simple_release(struct inode *inode, struct file *filp) { return 0; }


/* * Common VMA ops. */



void simple_vma_open(struct vm_area_struct *vma) { printk(KERN_NOTICE "Simple VMA open, virt %lx, phys %lx\n", vma->vm_start, vma->vm_pgoff vm_start, virt_to_phys((unsigned long)(buffer)) >>



PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN;



/* if (io_remap_page_range(vma, vma->vm_start, virt_to_phys((unsigned int)buffer), vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; */



/* if (remap_pfn_range(vma, vma->vm_start, ((int)(buffer)) >> PAGE_SHIFT,



vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN;



*/ vma->vm_ops = &simple_remap_vm_ops; simple_vma_open(vma); return 0; }


/* * Our various sub-devices. */ /* Device 0 uses remap_pfn_range */ static struct file_operations simple_remap_ops = { .owner = THIS_MODULE, .open = simple_open, .release = simple_release, .mmap = simple_remap_mmap, };


/* * We export two simple devices. There's no need for us to maintain any * special housekeeping info, so we just deal with raw cdevs. */ static struct cdev SimpleDevs;



/* * Module housekeeping. */ static int simple_init(void) { int result; dev_t dev = MKDEV(simple_major, 0); int err, devno;



/* Figure out our device number. */ result = alloc_chrdev_region(&dev, 0, 2, "simple"); simple_major = MAJOR(dev);



if (result < 0) { printk(KERN_WARNING "unable to get major %d\n", simple_major); return result; } simple_major = result;



printk(KERN_WARNING "simple: major %d\n", simple_major);



devno = MKDEV(simple_major, 0);



cdev_init(&SimpleDevs, &simple_remap_ops); SimpleDevs.owner = THIS_MODULE; SimpleDevs.ops = &simple_remap_ops; err = cdev_add (&SimpleDevs, devno, 1); /* Fail gracefully if need be */ if (err) printk (KERN_NOTICE "Error %d adding", err);


buffer = kmalloc(4096, GFP_KERNEL); if (!buffer) { printk(KERN_ALERT "kmalloc failed \n"); return -1; } *buffer = '\0';



return 0; }


static void simple_cleanup(void) { cdev_del(&SimpleDevs); unregister_chrdev_region(MKDEV(simple_major, 0), 1); if (buffer) kfree(buffer); }


module_init(simple_init); module_exit(simple_cleanup);



--------------------------------------------------------------------


my make file:



# Comment/uncomment the following line to disable/enable debugging #DEBUG = y # Add your debugging flag (or not) to CFLAGS ifeq ($(DEBUG),y) DEBFLAGS = -O -g # "-O" is needed to expand inlines else DEBFLAGS = -O2 endif



CFLAGS += $(DEBFLAGS) -I$(LDDINCDIR)



ifneq ($(KERNELRELEASE),) # call from kernel build system



obj-m := simple.o



else



KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd)



default: $(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINCDIR=$(PWD)/../include modules



endif



clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions



depend .depend dep: $(CC) $(CFLAGS) -M *.c > .depend


ifeq (.depend,$(wildcard .depend)) include .depend endif


----------------------------------------------------------------------------------------



my test program:


#include #include #include #include #include #include #include



int main (int argc, char *argv[]) { char *str; int fd;


fd = open("/dev/simple", O_RDWR);



str = (char *)mmap(NULL,getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED,fd,0);



if (str==MAP_FAILED) { perror("mmaptest user "); return 1; };



/* there you go */ printf("\n!!!!!!!!!!!!%s\n\n", str);



munmap(str, 4096); close(fd);



return 0; }



Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required