内存映射与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的初始化。


linux下,设备DMA数据至0xF0000000,使用mmap映射,然后memcpy,效率相当低,16M需要400ms,有办法提高?

你要先找到瓶颈在哪里?
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,这种情形下就跟内存映射方式类似了。
 

相关内容

    暂无相关文章