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

原文地址:https://www.cnblogs.com/kekukele/p/3703399.html