linux mmap 驱动内核共享内存

#include 	<linux/kernel.h>
#include	<linux/module.h>
#include	<linux/init.h>
#include	<linux/fs.h>
#include	<linux/mm.h>
#include	<linux/cdev.h>
#include	<linux/errno.h>
#include	<linux/types.h>
#include	<linux/interrupt.h>
#include	<linux/delay.h>
#include        <linux/errno.h>
#include        <linux/sched.h>
#include        <asm/semaphore.h>
#include        <asm/system.h>
#include	<asm/uaccess.h>
#include	<asm/arch/irqs.h>
#include 	<asm/io.h>
#include 	<linux/version.h>
#include        <asm/hardware.h>
#include        <linux/delay.h>

#include        <asm/arch/sep4020_hal.h>

#define	DRIVE_MAJOR				165
#define	DRIVE_NAME				"Test drv"
typedef	struct
{
	dev_t			dev_num ;
	struct	cdev	cdev ;	
			
}code_dev ;
static code_dev	test_dev ;
unsigned char data_source;
unsigned char *testmap;
unsigned char *kmalloc_area;
unsigned long  msize;
static int	test_open(struct inode *inode , struct file *filp)
{
	return 0 ;
}
static int	test_close(struct inode *inode , struct file *filp)
{
	return 0 ;
}

static ssize_t test_write(struct file *filp, const char __user *buf,size_t count, loff_t *ppos)
{
        if(copy_from_user(&data_source,buf,sizeof(data_source)))
          {
          printk("write error!\n");
          }
	return(sizeof(data_source));
}

static ssize_t test_read(struct file *filp, char __user *buf,size_t count,loff_t *ppos)
{
        if(copy_to_user(buf,&data_source,sizeof(data_source)))
          {
          printk("read error!\n");
          } 
	return(sizeof(data_source));
}
static int test_mmap(struct file *file,struct vm_area_struct *vma)
{
        int ret;
        ret=remap_pfn_range(vma,vma->vm_start,virt_to_phys((void *)((unsigned long)kmalloc_area))>>PAGE_SHIFT,vma->vm_end-vma->vm_start,PAGE_SHARED);
        if(ret!=0)
         {
          return -EAGAIN;
         } 
        return ret;
}  
static int test_ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg)
{
  int result;
  int i;
	switch(cmd) 
	{	
	case 0:
	  {	
	  	result=0;
	  }			
	  break;
	case 1:
	  {	
	  	result=1;
	  }	
	break ;
	case 2:
	  {
           for(i=0;i<20;i++)
              {
              printk("i=%d  %c\n",i,*(testmap+i)); 
              }	
	  	result=2;
	  }
        break;	
	default:
		return -ENOTTY;			
	}
	return(result);
}	
static struct file_operations test_fs = {
	
				.owner 		= THIS_MODULE ,
				.open 		= test_open ,
				.release 	= test_close ,
				.read		= test_read ,
				.write		= test_write ,
				.mmap           = test_mmap,
                                .ioctl		= test_ioctl
						};
static int	__init test_init(void)
{
	unsigned int 	ret ;
	unsigned char *virt_addr;
        memset(&test_dev , 0 ,sizeof(test_dev)) ;
	test_dev.dev_num = MKDEV(DRIVE_MAJOR , 0) ;
	ret = register_chrdev_region(test_dev.dev_num , 1 ,DRIVE_NAME) ;
	if(ret < 0)
	{
		return(ret) ;
	}

	cdev_init(&test_dev.cdev , &test_fs) ;
	test_dev.cdev.owner = THIS_MODULE ;
	test_dev.cdev.ops = &test_fs ;
	
	printk("\nInit drv \n") ;
		
	ret = cdev_add(&test_dev.cdev , test_dev.dev_num , 1) ;
	if(ret < 0)
	{
		printk("cdev add error !\n") ;
		return(ret) ;
	}

        testmap=kmalloc(4096,GFP_KERNEL);
        kmalloc_area=(int *)(((unsigned long)testmap +PAGE_SIZE-1)&PAGE_MASK);
        if(testmap==NULL)
        {
         printk("Kernel mem get pages error\n");
        } 
        for(virt_addr=(unsigned long)kmalloc_area;virt_addr<(unsigned long)kmalloc_area+4096;virt_addr+=PAGE_SIZE)
           {
           SetPageReserved(virt_to_page(virt_addr)); 
           }
        memset(testmap,'q',100); 
	printk("Test drv reg success !\n") ;
	return 0 ;
}
	

static void __exit test_exit(void)
{
	printk("Test drv  exit\n") ;
	cdev_del(&test_dev.cdev) ;
	unregister_chrdev_region(test_dev.dev_num , 1) ;
}
	
MODULE_LICENSE("GPL") ;
	
module_init(test_init) ;
module_exit(test_exit)	;

 

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#define  max_num  4096 
int main(int argc,char *argv[])
{
    int fd;
    int ret;
    unsigned char *rwc,*rrc;
    unsigned int *map;
    unsigned char ** newmap;
    rwc=malloc(sizeof(unsigned char));
    rrc=malloc(sizeof(unsigned char));
    *rwc=50;
    *rrc=30;
    fd=open("/dev/drvio1",O_RDWR);
    if(fd<0)
    	{
    		printf("open file error!\n");
    		return -1;
    	} 
    ret=write(fd,rwc,sizeof(rwc));
    ret=read(fd,rrc,sizeof(rrc));
    printf("rwc =%d\nrrc =%d\n",*rwc,*rrc);
    *rwc=10;
    ret=write(fd,rwc,sizeof(rwc));
    ret=read(fd,rrc,sizeof(rrc));
    printf("rwc =%d\nrrc =%d\n",*rwc,*rrc);
    ioctl(fd,2,0);
    if((map=(unsigned int *)mmap(NULL,max_num,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0))==MAP_FAILED)
       {
        printf("mmap error!\n"); 
       }
    memset(map,'c',max_num);
    strcpy(map,"Welcome");
    ioctl(fd,2,0);
    munmap(map,4096);
    map=NULL;
    close(fd);
    return 0;
}

 

 

 

AR = ar
ARCH = arm
CC = arm-linux-gcc

#ifneq ($(KERNELRELEASE))
	obj-m:= drv.o
#else
	KDIR = /decard_dev/linux-v3.4.4 
	PWD:=$(shell pwd)
default:
	$(MAKE) -C $(KDIR) M=$(PWD) modules
	arm-linux-gcc tdrv.c -o tdrv
	arm-linux-gcc tdrv1.c -o tdrv1
	rm -rf *.mod.c  *.mod.o  *.o
	rm -rf .*.ko.cmd  .*.mod.o.cmd  .*.o.cmd  .tmp_versions
clean:
	rm -rf *.o *.ko *.mod.c tdrv tdrv1 
	rm -rf .*.ko.cmd  .*.mod.o.cmd  .*.o.cmd  .tmp_versions
#endif	

 

 

 

mknod /dev/drvio1 c 165 0

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值