免费注册 查看新帖 |

Chinaunix

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

linux 驱动mmap操作 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-20 19:09 |只看该作者 |倒序浏览
一、自己画了个图,不知正确? 这是我的理解
注意
     1.所有的物理内存要使用都要映射到内核空间
     2.物理内存划分为页
     3.页扩展机制,支持大于4G的物理内存,这时要用到三级分页(pgd 页全局目录Page Global Directory,pmd页中间目录 (Page Middle Directory),pte页表条目 (Page Table Entry)),不
需支持时,只需将 pmd 定义成“1”,返回两级分页机制
     4.PAGE_OFFSET宏代表3G PAGE_SHIFT、PMD_SHIFT、PGD_SHIFT分别对应pte、pmd、pgd右移的位数
     





二、驱动分配内存

1.概念:1.内核逻辑地址:内核直接映射的地址,物理上连续
       2.内核虚拟地址:包括内核逻辑地址在内,但物理上不一定连续
2.函数讲解
       #include  
void *kmalloc(size_t size, int flags);
void kfree(void *obj);

get_zeroed_page(unsigned int flags);
//返回一个指向新页的指针并且用零填充了该页.
__get_free_page(unsigned int flags);
//类似于 get_zeroed_page, 但是没有清零该页.
__get_free_pages(unsigned int flags, unsigned int order);
void free_page(unsigned long addr);
void free_pages(unsigned long addr, unsigned long order);
void __free_page(struct page *page);
void __free_pages(struct page *page, unsigned int order);


#include  
void *vmalloc(unsigned long size);
void vfree(void * addr);
void *ioremap(unsigned long offset, unsigned long size);
void iounmap(void * addr);


三、VMA和PAGE结构 和mmap函数

1.page  主要成员
   atomic_t count;
//这个页的引用数. 当这个 count 掉到 0, 这页被返回给空闲列表.
void *virtual;
//如果页被映射,则表示这页的内核虚拟地址; 否则, NULL.
unsigned long flags;
//描述页状态的一套位标志. 这些包括 PG_locked, 它指示该页在内存中已被加锁, 以及 PG_reserved,
//它防止内存管理系统使用该页

2.vm_area_struct  主要成员
unsigned long vm_start;//VMA 开始于
unsigned long vm_end; //VMA 结束
struct file *vm_file;
//指向和这个区(如果有一个)关联的 struct file 结构的指针.
unsigned long vm_pgoff;
//文件中区的偏移, 以页计. 当一个文件和设备被映射, 这是映射在这个区的第一页的文件位置.?????
unsigned long vm_flags;
// 设备驱动常用的标志是 VM_IO 和 VM_RESERVUED.
//VM_IO 标志一个 VMA 作为内存映射的 I/O 区,阻止这个区被包含在进程核转储???中.
//VM_RESERVED 告知内存管理系统不要试图交换出这个 VMA;
struct vm_operations_struct *vm_ops;
//操作
//void (*open)(struct vm_area_struct *vma);  VMA刚刚产生时,此函数被调用来初始化VMA
//void (*close)(struct vm_area_struct *vma);  当一个区被销毁, 内核调用它的关闭操作
//struct page *(*nopage)(struct vm_area_struct *vma, unsigned long address, int *type);
//如果 nopage 方法没有定义,内核分配一个空页.进程存取不在内存中有效 VMA 的页时,nopage 方法被调用(如果它被定义)
//int (*populate)(struct vm_area_struct *vm, unsigned long address, unsigned long len, pgprot_t prot, unsigned long pgoff, int
nonblock);
//在它们被用户空间存取之前,允许内核"预错"页到内存. 驱动通常没有必要实现这个填充方法
void *vm_private_data;
//驱动可以用来存储它的自身信息的成员.

3.mmap用户空间调用与内核空间调用
void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offset);
//start 指向欲对应的内存起始地址,通常设为NULL,代表让系统自动选定地址,对应成功后该地址会返回
//参数length代表将文件中多大的部分对应到内存。
//参数prot代表映射区域的保护方式
//fd文件描述符
//参数offset为文件映射的偏移量,通常设置为0,代表从文件最前方开始对应,offset必须是分页大小
//的整数倍,映射文件的起动位移量受系统虚存页长度的限制,那么如果映射区的长度不是页长度的整数
//倍时,将如何呢?假定文件长12字节,系统页长为512字节,则系统通常提供512字节的映射区,其中
//后500字节被设为0。可以修改这500字节,但任何变动都不会在文件中反映出来
//若映射成功则返回映射区的内存起始地址,否则返回MAP_FAILED(-1)

内核空间调用
int (*mmap) (struct file *filp, struct vm_area_struct *vma);

4.mmap执行的顺序
      a.在用户进程创建一个vma区域
      b.驱动程序获得页
      c.将获得的页分配给vma区域
四、如何给VMA分配页
    1.一次完成全部
int remap_pfn_range(struct vm_area_struct *vma, unsigned long virt_addr, unsigned long pfn, unsigned long size, pgprot_t prot);
//vma 用户进程创建一个vma区域
//virt_addr 重新映射应当开始的用户虚拟地址. 这个函数建立页表为这个虚拟地址范围从 virt_addr 到 virt_addr_size.
//pfn 页帧号, 对应虚拟地址应当被映射的物理地址. 这个页帧号简单地是物理地址右移 PAGE_SHIFT 位. 对大部分使用, VMA 结构的 vm_paoff 成员正好包含你需要的值. 这个函数影响物理地址从 (pfnvm_page_prot 中找到的值.
//返回的值常常是 0 或者一个负的错误值
int io_remap_page_range(struct vm_area_struct *vma, unsigned long virt_addr, unsigned long phys_addr, unsigned long size, pgprot_t prot);
//当用在 phys_addr 指向 I/O 内存时返回的值常常是 0 或者一个负的错误值???
    2.一页一页的分配
struct page *(*nopage)(struct vm_area_struct *vma, unsigned long address, int *type);//返回一个有效映射页
    3.限制:
remap_pfn_range不能映射常规内存,只存取保留页和在物理内存顶之上的物理地址。因为保留页和在物理
内存顶之上的物理地址内存管理系统的各个子模块管理不到。640 KB 和 1MB 是保留页可能映射,设备I/O
内存也可以映射如果想把kmalloc()申请的内存映射到用户空间,则可以通过mem_map_reserve()把相应
的内存设置为保留后就可以。
五、实例分析
      例1 kmalloc分配1页,用nopage映射

文件:km2.rar大小:0KB下载:
下载
         


例 2 kmalloc 分配1页,用remap_pfn_range映射

文件:km1.rar大小:0KB下载:
下载

          

例3 vmalloc 分配,用nopage映射
      
测试程序

文件:test.rar大小:0KB下载:
下载









本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/86768/showart_1731168.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP