内存映射与DMA,内存映射DMA
内存映射与DMA,内存映射DMA
1、mmap系统调用的实现过程,该系统调用直接将设备内存映射到用户进程的地址空间。
2、用户空间内存如何映射到内核中(get_user_pages)。
3、直接内存访问(DMA),他使得外设具有直接访问系统内存的能力。
linux中地址类型:用户虚拟地址、内核虚拟地址、内核逻辑地址(与物理地址是线性关系)、物理地址
用户空间与内核空间:内核将4G的虚拟地址空间分割为用户空间与内核空间;在二者的上下文中使用同样的映射。内核无法操作没有映射到内核地址空间的内存。在内核地址中有一块地址空间专门用于用户空间到内核的虚拟映射。
低端内存:存在于内核空间上的逻辑内存地址。
高端内存:是指那些不存在逻辑地址的内存。
内核中处理内存的函数趋向使用指向page结构的指针,该数据结构用来保存内核需要的所有物理内存的信息
页表:处理器使用页表将虚拟地址转换为相应的物理地址。
虚拟内存区(VMA):用于管理进程地址空间中不同区域的内核数据结构。每个进程在编译、链接后形成的映象文件有一个代码段、数据段、还有堆栈段(如下图1所示),所有一个内存映射(至少)包含下面这些区域:
1)程序的可执行代码区域
2)多个数据区,其中包括初始化数据区、非初始化数据区及程序堆栈。
3)与每个活动的内存映射对应的区域
图1(进程虚拟空间的划分)
通常,进程所使用到的虚存空间不连续,且各部分虚存空间的访问属性也可能不同。所以一个进程的虚存空间需要多个vm_area_struct结构来描述。
在vm_area_struct结构的数目较少的时候,各个vm_area_struct按照升序排序,以单链表的形式组织数据(通过vm_next指针指向下一个vm_area_struct结构)。但是当vm_area_struct结构的数据较多的时候,仍然采用链表组织的化,势必会影响到它的搜索速度。针对这个问题,vm_area_struct还添加了vm_avl_hight(树高)、vm_avl_left(左子节点)、vm_avl_right(右子节点)三个成员来实现AVL树,以提高vm_area_struct的搜索速度。
假如该vm_area_struct描述的是一个文件映射的虚存空间,成员vm_file便指向被映射的文件的file结构,vm_pgoff是该虚存空间起始地址在vm_file文件里面的文件偏移,单位为物理页面。
图2 进程虚拟地址示意图
mmap系统调用所完成的工作就是准备这样一段虚存空间,并建立vm_area_struct结构体,将其传给具体的设备驱动程序,这些都是由内核完成。
用户空间进程调用mmap将设备内存映射到他的地址空间时,系统通过创建一个表示该映射的新VMA作为响应,支持mmap的驱动程序,需要帮助进程完成VMA的初始化。
你要先找到瓶颈在哪里?
1)设备dma速率。 不要映射,直接在内核memcpy 设备DMA数据,看速率
2)mmap效率。 不要用DMA的内存做映射,用内核申请的内存做映射,然后在用户控件memcpy,看速率
3)用户memcpy效率。这个你已经测试过了,不是问题
前者理解正确。
“CPU的单一物理地址空间”就是指RAM,前文有描述"有些体系结构的CPU(如,PowerPC、m68k等)通常只实现一个物理地址空间(RAM)"。也就是说,这类结构(内存映射方式)的CPU只对RAM编址,其他对象如I/O,ROM等都要映射到RAM中才能被CPU访问。
"而另外一些体系结构的CPU(典型地如X86)则为外设专门实现了一个单独地地址空间",这类(I/O映射方式)CPU就是我们现在用的PC中的CPU,这类CPU的寻址空间不是分为常规内存/保留内存/扩展内存吗?其中的保留内存就是用来对I/O,ROM等的直接编址。但由于参与直接编址的I/O,ROM等的读的速度没有RAM快,所以主板提供了映射功能,映射后参与保留内存编址的实际也是物理RAM,这种情形下就跟内存映射方式类似了。
评论暂时关闭