接下来就是建立物理页与虚拟页之间的关系,即采用函数remap_pfn_range(),具体的参数如下:
int remap_pfn_range(structvm_area_struct *vma, unsigned long addr,unsigned long pfn, unsigned long size, pgprot_t prot)
1、struct vm_area_struct是一个虚拟内存区域结构体,表示虚拟存储器中的一个内存区域。其中的元素vm_start是指虚拟存储器中的起始地址。
2、addr也就是虚拟存储器中的起始地址,通常可以选择addr = vma->vm_start。
3、pfn是指物理存储器的具体页号,通常通过物理地址得到对应的物理页号,具体采用virt_to_phys(dev->data)>>PAGE_SHIFT.首先将虚拟内存转换到物理内存,然后得到页号。>>PAGE_SHIFT通常为12,这是因为每一页的大小刚好是4K,这样右移12相当于除以4096,得到页号。
4、size区域大小
5、区域保护机制。
返回值,如果成功返回0,否则正数。
测试代码可以直接通过对虚拟内存区域操作,实现不同的操作,如下:
- #include<fcntl.h>
- #include<unistd.h>
- #include<stdio.h>
- #include<stdlib.h>
- #include<sys/types.h>
- #include<sys/stat.h>
- #include<sys/mman.h>
- #include<string.h>
- int main()
- {
- int fd;
- char *start;
-
- char buf[2048];
- strcpy(buf,"This is a test!!!!");
- fd = open("/dev/memdev0",O_RDWR);
-
- if(fd == -1)
- {
- printf("Error!!\n");
- exit(-1);
- }
- /*创建映射*/
- start = mmap(NULL,2048,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
- /*必须检测是否成功*/
- if(start == -1)
- {
- printf("mmap error!!!\n");
- exit(-1);
- }
- strcpy(start,buf);
- printf("start = %s,buf = %s\n",start,buf);
- strcpy(start,"Test is Test!!!\n");
- printf("start = %s,buf = %s\n",start,buf);
- /**/
- strcpy(buf,start);
-
- printf("start = %s,buf=%s\n",start,buf);
- /*取消映射关系*/
- munmap(start,2048);
- /*关闭文件*/
- close(fd);
- exit(0);
- }
经过测试,成功得到了驱动。