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