免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2664 | 回复: 1
打印 上一主题 下一主题

内存mmap相关nopage问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-08-08 13:57 |只看该作者 |倒序浏览
本帖最后由 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,相关部分也作了修改。

论坛徽章:
0
2 [报告]
发表于 2010-08-09 09:37 |只看该作者
是不是还得有setpagereserved 这个东东?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP