1.mmap
功能:内存映射,负责把文件内容映射到进程的虚拟地址空间,通过对这段内存的读取和修改,来实现对文件的读取和修改,而不需要再调用read,write等操作。
返回:起始地址
2.参数
addr:指定映射的起始地址,通常设为NULL,由系统指定
length:映射到内存的文件长度。
prot:映射区的保护方式:
PROT_EXEC:映射区可被执行
PROT_READ:映射区可被读取
PROT_WRITE:映射区可被写入
PROT_NONE:映射区不能存取
flags:映射区的特性:是否是一份拷贝,是否写回源文件
MAP_SHARED:
MAP_PRIVATE:
fd:由open返回的文件描述符,代表要映射的文件
offset:以文件开始处的偏移量,必须是分页大小的整数倍,通常是0,表示从文件头开始映射
3.取消映射
int munmap(void *start,size_t length)
功能:取消参数start所指向的映射内存,参数length表示欲取消的内存大小。
返回值:成功返回0,否则返回-1,错误原因在errno中
4.在驱动程序中实现映射
虚拟内存区域:
虚拟内存区域是进程的虚拟地址空间中的一个同质区间,即具有同样特性的连续地址范围.
一个进程的内存映象由下面几部分组成:程序代码、数据、BSS、和栈区域,以及内存映射的区域。
一个进程的内存区域可以通过查看/proc/pid/maps
linux内核使用vm_area_struct结构来描述虚拟内存区域,其中几个主要成员如下:
unsigned long vm_start:虚拟内存区域起始地址
unsigned long vm_end:虚拟内存区域结束地址
unsigned long vm_flags:该区域的标记。如:VM_IO和VM_RESERVED。
5.mmap设备操作
映射一个设备是指把用户空间的一段地址关联到设备内存上。当程序读写这段用户空间的地址时,它实际上是在访问设备。
mmap方法是file_operations结构的成员,在mmap系统调用发出时被调用。在此之前,内核已经完成了很多工作。mmap设备方法所需要做的就是建立虚拟地址到物理地址的页表。
1.找虚拟地址空间2.进行关联
虚拟地址和物理地址建立关系->建立页表
int(*mmap)(struct file*,struct vm_area_struct*)
1.mmap如何完成页表的建立
方法有二:
1.使用remap_pfn_range一次建立所有页表
2.使用nopage VMA方法每次建立一个页表
6.int remap_pfn_range(虚拟地址空间,虚拟地址,物理地址,长度,属性)
int memdev_mmap(struct file*filp, struct vm_area_struct *vma)
{
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,
size,
vma->vm_page_prot))
return -EAGAIN;
return 0;
}