- 论坛徽章:
- 0
|
本帖最后由 whoisliang 于 2010-08-08 14:02 编辑
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/page.h>
#include <linux/mm.h>
#define MMAPNOPAGE_DEV_NAME "mmapnopage"
#define MMAPNOPAGE_DEV_MAJOR 240
#define SHARE_MEM_PAGE_COUNT 4
#define SHARE_MEM_SIZE (PAGE_SIZE*SHARE_MEM_PAGE_COUNT)
char *share_memory=NULL;
struct page *mmapnopage_vm_nopage(struct vm_area_struct *vma,unsigned long addr,int *type)
{
struct page *page;
unsigned long offset;
void *page_ptr;
printk("CALL NOPAGE %08x\n",addr);
page=NOPAGE_SIGBUS;
page_ptr=NULL;
if((NULL==vma)||(share_memory==NULL))
return NOPAGE_SIGBUS;
offset=addr-vma->vm_start;
if(offset>=SHARE_MEM_SIZE) return NOPAGE_SIGBUS;
page_ptr=share_memory+offset;
page=virt_to_page(page_ptr);
get_page(page);
if(type) *type=VM_FAULT_MINOR;
return page;
}
struct vm_operations_struct mmapnopage_vm_ops=
{
.nopage=mmapnopage_vm_nopage,
};
int mmapnopage_mmap(struct file *filp,struct vm_area_struct *vma)
{
vma->vm_flags|=VM_RESERVED;
vma->vm_ops=&mmapnopage_vm_ops;
return 0;
}
struct file_operations mmapnopage_fops=
{
.owner=THIS_MODULE,
.mmap=mmapnopage_mmap,
};
int mmapnopage_init(void)
{
int lp;
int result;
result=register_chrdev(MMAPNOPAGE_DEV_MAJOR,MMAPNOPAGE_DEV_NAME,&mmapnopage_fops);
if(result<0) return result;
share_memory=__get_free_pages(GFP_ATOMIC,4); //total get 16 pages,only SHARE_MEM_PAGE_COUNT pages "TEST%d"
if(!share_memory){printk("NOMEM\n"); return -ENOMEM;}
for(lp=0;lp<SHARE_MEM_PAGE_COUNT;lp++)
{
sprintf(share_memory+PAGE_SIZE*lp,"TEST %d",lp);
}
return 0;
}
void mmapnopage_exit(void)
{
if(share_memory!=NULL) free_pages((unsigned long)share_memory,4);
unregister_chrdev(MMAPNOPAGE_DEV_MAJOR,MMAPNOPAGE_DEV_NAME);
}
module_init(mmapnopage_init);
module_exit(mmapnopage_exit);
MODULE_LICENSE("Dual BSD/GPL");
Makefile文件内容如下:
obj-m:=mmapnopage_dev.o
KDIR:=/lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.ko
rm -rf *.mod.*
rm -rf .*.cmd
rm -rf *.o
在shell中:mknod /dev/mmapnopage c 240 0
另外,应用层程序如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#define DEVICE_FILENAME "/dev/mmapnopage"
#define SHARE_MEM_PAGE_COUNT 4
#define SHARE_MEM_SIZE (4096*SHARE_MEM_PAGE_COUNT)
int main()
{
int dev,loop;
char *ptrdata;
dev=open(DEVICE_FILENAME,O_RDWR|O_NDELAY);
if(dev>=0)
{
ptrdata=(char*)mmap(0,SHARE_MEM_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,dev,0);
printf("ptrdata =%08x\n",ptrdata);
for(loop=0;loop<SHARE_MEM_PAGE_COUNT;loop++)
{
printf("[%s]\n",ptrdata+4096*loop);
}
munmap(ptrdata,SHARE_MEM_SIZE);
close(dev);
}
return 0;
}
执行完应用程序之后,系统总是不正常,不知为何?此驱动程序主要是参考了(韩)俞永昌《Linux设备驱动开发技术及应用》中相关程序,只是将vmalloc改为了__get_free_pages,相关部分也作了修改。 |
|