您的位置 首页 应用

gdb+gdbserver调试arm-linux程序

mmap作为structfile_operations的重要一个元素,mmap主要是实现物理内存到虚拟内存的映射关系,这样可以实现直接访问虚拟内存,而不用使

mmap作为struct file_operations的重要一个元素,mmap首要是完结物理内存到虚拟内存的映射联系,这样能够完结直接拜访虚拟内存,而不必运用设备相关的read、write操作,mmap的根本进程是将文件映射到虚拟内存中。在之前的一篇博客中谈到了mmap完结文件仿制的操作。

关于linux中的mmap调用如下,最好的办法检查指令,man mmap:
必要的头文件
#include
函数声明
void * mmap(void *addr,size_t length,int prot,
int flags,int fd,off_t offset);
关于各个参数的含义如下:
1、回来值是一个通用型指针,这样就确保了各种类型的请求办法。
2、void *addr 是程序员所期望的虚拟地址作为开端映射地址,一般为NULL,内核主动分配。
3、size_t length当然是指需求映射的区域巨细。
4、int flags是指对这段区域的维护办法。详细的能够参看内核源码的linux/mm.h。常用的是PROT_EXEC,PROT_READ,PROT_WRITE,PROT_NONE。
5、int flags首要是指对这段区域的映射办法,首要分为两种办法MAP_SHARE,MAP_PRIVATE.其间的MAP_SHARE是指对映射区域的写操作会更新到文件中,这样就相当于直接操作文件。而MAP_PRIVATE一般选用一种称为”写时维护的机制”完结映射,对映射区的写操作不会更新到文件中,完结办法是将需求被写操作的页仿制到重新分配的新页中,然后再对新的页进行写操作。本来的映射并没有改动,可是读操作并不会重新分配物理内存空间。详细的参阅深化了解计算机体系。
6、int fd是指将被映射的文件描述符,映射需求确保文件描述符的正确性。
7、off_t offset是指从文件的详细位置开端映射,一般情况下能够设置为0,即从最初映射。
根本的映射联系如下图:
设备驱动的mmap完结首要是将一个物理设备的可操作区域(设备空间)映射到一个进程的虚拟地址空间。这样就能够直接选用指针的办法像拜访内存的办法拜访设备。在驱动中的mmap完结首要是完结一件事,便是实践物理设备的操作区域到进程虚拟空间地址的映射进程。一起也需求确保这段映射的虚拟存储器区域不会被进程作为一般的空间运用,因而需求增加一系列的维护办法。
详细的完结进程如下:
/*首要是树立虚拟地址到物理地址的页表联系,其他的进程又内核自己完结*/
static int mem_mmap(struct file* filp,struct vm_area_struct *vma)
{
/*直接的操控设备*/
struct mem_dev *dev = filp->private_data;
/*符号这段虚拟内存映射为IO区域,并阻挠体系将该区域包含在进程的寄存转存中*/
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, /*物理存储区的物理页号*/
dev->size, /*映射区域巨细*/
vma->vm_page_prot /*虚拟区域维护特点*/
))
return -EAGAIN;
return 0;
}
详细的完结剖析如下:
vma->vm_flags |= VM_IO;
vma->vm_flags |= VM_RESERVED;
上面的两个维护机制就说明晰被映射的这段区域具有映射IO的相似性,一起确保这段区域不能随意的换出。便是树立一个物理页与虚拟页之间的相关性。详细原理是虚拟页和物理页之间是以页表的办法相关起来,虚拟内存一般大于物理内存,在运用进程中虚拟页通过页表相关全部对应的物理页,当物理页不行时,会挑选性的献身一些页,也便是将物理页与虚拟页之间堵截,重现相关其他的虚拟页,确保物理内存够用。在设备驱动中应该详细的虚拟页和物理页之间的联系应该是长时间的,应该维护起来,不能随意被其他虚拟页所替换。详细也可参看关于虚拟存储器的文章。
接下来便是树立物理页与虚拟页之间的联系,即选用函数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
#include
#include
#include
#include
#include
#include
#include
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!!”);
exit(-1);
}
/*创立映射*/
start = mmap(NULL,2048,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
/*有必要检测是否成功*/
if(start == -1)
{
printf(“mmap error!!!”);
exit(-1);
}
strcpy(start,buf);
printf(“start = %s,buf = %s”,start,buf);
strcpy(start,”Test is Test!!!”);
printf(“start = %s,buf = %s”,start,buf);
/**/
strcpy(buf,start);
printf(“start = %s,buf=%s”,start,buf);
/*撤销映射联系*/
munmap(start,2048);
/*封闭文件*/
close(fd);
exit(0);
}
通过测验,成功得到了驱动。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/317791.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部