mmap()第二部分

来源:互联网 发布:数据库相关职称 编辑:程序博客网 时间:2024/04/26 20:09

老谢把mmap()讲完了,但是理解的很不完全,有好几个问题。

1.他说驱动程序中的mmap()建立页表进行地址映射,那么映射的是什么?是设备的物理地址,还是SDRAM中的地址?

2.系统调用的mmap()也是负责把文件内容映射到进程的虚拟内存空间,那么这个文件是什么?是相对应的设备操作文件?

下面罗列驱动中mmap()。

一般情况下,用户空间是不可能直接访问硬件设备的。但是驱动程序中的可实现mmap()函数。它将用户空间的一段内存与设备内存关联,当用户访问用户空间的这段地址范围时,实际会转化为对设备的访问。
mmap()必须以PAGE_SIZE为单位进行映射。
fd文件描述符,一般由open()函数返回。
一、虚拟内存区
虚拟内存区域是进程的虚拟地址空间中的一个同质区间,即具有同样特性的连续地址范围。一个进程的内存映象由下面几部分组成:程序代码、数据、BSS和栈区域,以及内存映射的区域。
虚拟内存区的各个参数:
start_end permoffset major:minor inode
v Start: 该区域起始虚拟地址
v End:   该区域结束虚拟地址
v Perm:  读、写和执行权限;表示对这个区域,允
许进程做什么。这个域的最后一个字符要么是p
表示私有的,要么是s表示共享的。
v Offset: 被映射部分在文件中的起始地址
v Major、minor:主次设备号
v Inode:索引结点
二、使用vm_area_struct这个结构体来描述上述各个参数
Linux内核使用结构vm_area_struct(<linux/mm_types.h>)来描述虚拟内存区域。
主要成员如下:
v unsignedlong vm_start
虚拟内存区域起始地址
v unsignedlong vm_end
虚拟内存区域结束地址
unsignedlong vm_flags
该区域的标记。如:VM_IO和VM_RESERVED。VM_IO 将该 VMA 标记 为 内 存 映射 的 IO 区域 ,VM_IO会阻止系统将该区域包含在进程的存放转存(core  dump)中,VM_RESERVED标志内存区域不能被换出。
三、内核空间的mmap()操作
映射一个设备是指把用户空间的一段地址关联到设备内存上。当程序读写这段用户空间的地址时,它实际上是在访问设备。
mmap()函数完成的东西:
mmap方法是file_oprations结构的成员,在mmap系统调用发出时被调用。在此之前,内核已经完成了很多工作。mmap设备方法所需要做的就是建立虚拟地址到物理地址的页表。
内核空间的mmap()操作函数原型:
int (*mmap) (struct file *, struct vm_area_struct *)

完成虚拟地址到物理地址的映射需要建立页表。
建立页表的函数如下:
int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,unsigned long pfn, unsignedlong size, pgprot_t prot)
函数的参数如下:
vma:
虚拟内存区域指针
virt_addr:
虚拟地址的起始值
pfn:
要映射的物理地址所在的物理页帧号,可将物理地址
>>PAGE_SHIFT得到。
size:
要映射的区域的大小。
prot:
VMA的保护属性。
mmap设备操作的历程:

static int memdev_mmap(struct file*filp, struct vm_area_struct *vma){      struct mem_dev *dev = filp->private_data; /*获得设备结构体指针*/            vma->vm_flags |= VM_IO;      vma->vm_flags |= VM_RESERVED;           if (remap_pfn_range(vma,vma->vm_start,virt_to_phys(dev->data)>>PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot))          return  -EAGAIN;                      return 0;}
原创粉丝点击