`
qvb3d
  • 浏览: 171177 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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

 

分享到:
评论

相关推荐

    linux内核驱动和用户态通信代码

    这里面的代码提供了内核驱动的样例,并且提供了通过mmap,在用户态和内核态之间构建共享内存,来进行通信的方法

    linux设备驱动程序第三版

    1. Linux 设备驱动第三版 .................................................................................................................... 5 2. 第 1 章 设备驱动简介 ....................................

    linux操作系统内核技术-uestc课件

     5熟悉在x86体系结构上Linux中断和异常的处理原理,中断注册、共享、控制,和中断上下文的意义,中断和设备驱动程序的关系,以及设备驱动程序结构和用户接口。(4小时)  6中断处理程序被分解为top half和bottom ...

    Linux内核源代码情景分析 (上下册 高清非扫描 )

    6.7 共享内存 6.8 信号量 第7章基于socket的进程间通信 7.1系统调用socket() 7.2函数sys—socket()——创建插口 7.3函数sys—bind()——指定插口地址 7.4函数sys—listen()——设定server插口 7.5函数sys—...

    LINUX设备驱动第三版_588及代码.rar

    LINUX设备驱动第三版_ 前言 第一章 设备驱动程序简介 设备驱动程序的作用 内核功能划分 设备和模块的分类 安全问题 版本编号 许可证条款 加入内核开发社团 本书概要 第二章 构造和运行模块 设置测试系统 ...

    linux 内核源代码分析

    6.7 共享内存 6.8 信号量 第7章 基于socket的进程间通信 7.1 系统调用socket() 7.2 函数sys—socket()——创建插口 7.3 函数sys—bind()——指定插口地址 7.4 函数sys—listen()——设定server插口 ...

    linux内核源代码情景分析

    6.7 共享内存 6.8 信号量 第7章基于socket的进程间通信 7.1系统调用socket() 7.2函数sys—socket()——创建插口 7.3函数sys—bind()——指定插口地址 7.4函数sys—listen()——设定server插口 7.5函数sys—accept...

    Linux内核情景分析

    6.7 共享内存 6.8 信号量 《LINUX内核源代码情景分析(下册)》图书目录如下: -------------------------------------------------------------------------------- 第 7章 基于socket的进程间通信 7.1 系统...

    Linux内核情景分析(非扫描版)

    6.7 共享内存 6.8 信号量 《LINUX内核源代码情景分析(下册)》图书目录如下: -------------------------------------------------------------------------------- 第7章 基于socket的进程间通信 7.1 系统...

    Linux DeviceDrivers 3rd Edition

    Linux的内存管理 408 mmap设备操作 418 执行直接I/O访问 429 直接内存访问 435 快速参考 453 第十六章 块设备驱动程序 458 注册 459 块设备操作 464 请求处理 468 其他一些细节 484 快速参考 487 第十七...

    Android-MemorySahre:在本机中使用 ashmem ipc

    因为 struct 文件对于 linux 内核是全局的。 所以 binder 驱动程序可以通过 fget 获取文件,并使用新的 fd 将文件映射到 anthoer 进程。 API target_fd_install。 2.mmap 3.读或写共享内存4.关闭

    linux网络编程-宋敬彬-part1

    4.3.6 共享内存 121 4.3.7 信号 124 4.4 Linux下的线程 127 4.4.1 多线程编程实例 127 4.4.2 Linux下线程创建函数pthread_create() 129 4.4.3 线程的结束函数pthread_join()和pthread_exit() 129 4.4.4 ...

    V4l2视屏采集资料

    V4L2支持两种方式来采集图像:内存映射(mmap)和直接读取方式(read)。V4L2在include/linux/video.h文件下定义了一些重要的数据结构,在采集图像的过程中,就是通过对这些数据的操作来获得最终的图像数据。Linux系统V4...

Global site tag (gtag.js) - Google Analytics