mapping ram memory to user space

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; }

Reply to
mcharon
Loading thread data ...

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.