分类:
2010-06-29 14:02:28
建立新页来映射物理地址的工作由 remap_pfn_range 和 io_remap_page_range 来处理, 它们有下面的原型:
int remap_pfn_range(struct vm_area_struct *vma, unsigned long virt_addr, unsigned long pfn, unsigned long size, pgprot_t prot);
int io_remap_page_range(struct vm_area_struct *vma, unsigned long virt_addr, unsigned long phys_addr, unsigned long size, pgprot_t prot);
由这个函数返回的值常常是 0 或者一个负的错误值. 让我们看看这些函数参数的确切含义:
vma
页范围被映射到的虚拟内存区
virt_addr
重新映射应当开始的用户虚拟地址. 这个函数建立页表为这个虚拟地址范围从 virt_addr 到 virt_addr_size.
pfn
页帧号, 对应虚拟地址应当被映射的物理地址. 这个页帧号简单地是物理地址右移 PAGE_SHIFT 位. 对大部分使用, VMA 结构的
vm_paoff 成员正好包含你需要的值. 这个函数影响物理地址从 (pfn< size 正在被重新映射的区的大小,
以字节. prot 给新 VMA 要求的"protection". 驱动可(并且应当)使用在
vma->vm_page_prot 中找到的值. 给 remap_fpn_range 的参数是相当直接的, 并且它们大部分是已经在 VMA 中提供给你,
当你的 mmap 方法被调用时. 你可能好奇为什么有
2 个函数, 但是. 第一个
(remap_pfn_range)意图用在 pfn 指向实际的系统 RAM 的情况下, 而
io_remap_page_range 应当用在
phys_addr 指向 I/O 内存时. 实际上,
这 2 个函数在每个体系上是一致的, 除了
SPARC, 并且你在大部分情况下被使用看到 remap_pfn_range
. 为编写可移植的驱动, 但是, 你应当使用
remap_pfn_range 的适合你的特殊情况的变体.