Linux设备驱动之内存映射


1. 内存映射

所谓的内存映射就是把物理内存映射到进程的地址空间之内,这些应用程序就可以直接使用输入输出的地址空间,从而提高读写的效率。Linux提供了mmap()函数,用来映射物理内存。

在驱动程序中,应用程序以设备文件为对象,调用mmap()函数,内核进行内存映射的准备工作,生成vm_area_struct结构体,然后调用设备驱动程序中定义的mmap函数。

2. 映射的种类

把同一个物理地址映射为虚拟地址有两种方法,第一种是mmap()函数将物理地址映射到进程的虚拟地址空间中去,第二种方法为ioremap()函数映射到内核虚拟地址上的方法。

mmap映射的方法:

有两种方法建立页表,一次性建立页表,可以调用函数remap_pfn_range和每次建立一个页的页表,调用函数nopage。

remap_pfn_range:

这个函数的功能是一次性建立新的页表去映射物理地址。

int remap_pfn_range(struct vma_area_struct* vma,unsigned long virt_addr,unsigned long pfn,unsigned long size,pgprot_t prot);

返回值:映射成功时返回0,否则返回一个错误的负数代码。

vma 物理地址被映射到的虚拟内存区域

virt_addr 被映射到用户空间的起始虚拟地址。页表建立的范围在virt_addr到virt_addr+size

pfn 对应物理地址的页框号,一般是vma->vm_pgoff域。

size 被映射区域的字节大小

prot  vma->vm_page_prot

nopage:

struct page *(*nopage) (struct vm_area_struct *vma,unsigned long address,int *type);

vm_area_struct:虚拟内存区域

address:发生page fault的进程空间的虚拟地址

type 返回page fault可处理类型的地址

get_page(struct page* pageptr);

增加被映射页的引用次数。

相关内容