//remap_pfn_range()函数的原型:
int remap_pfn_range(struct vm_area_struct *vma,
unsigned long virt_addr,
unsigned long pfn,
unsigned long size,
pgprot_t prot);
//该函数的功能是创建页表.
//其中参数vma是内核根据用户的请求自己填写的,而参数addr表示内存映射开始处的虚拟地址.
//因此,该函数为[addr,addr+size]之间的虚拟地址[构造页表].
//另外,pfn(Page Fram Number)是虚拟地址应该映射到的物理地址的页面号,实际上就是物理地址右移PAGE_SHIFT位.
//如果PAGE_SIZE为4kB,则PAGE_SHIFT为12,因为PAGE_SIZE等于1<<PAGE_SHIFT.
//最后一个参数prot是新页所要求的保护属性.
//在驱动程序中,一般能使用remap_pfn_range()映射[内存中的保留页](如X86系统中的640KB~1MB区域)和[设备I/O内存].
//因此,如果想把kmalloc()申请的内存[映射到用户空间],则可以先通过mem_map_reserve() 或 SetPageReserved()[把相应的内存设置为保留],
//然后 remap_pfn_range()就可以.
因此,综上得到remap_pfn_range()常用的三种用途:
(1)映射[内存中的保留页]
(2)映射[设备I/O内存]
(3)将[kmalloc()申请的内存]映射到用户空间