LDD3 第15章 内存映射和DMA

本章内容分为三个部分:

  • 第一部分讲述了mmap系统调用的实现过程。将设备内存直接映射到用户进程的地址空间,尽管不是所有设备都需要,但是能显著的提高设备性能。
  • 如何跨越边界直接访问用户空间的内存页,一些相关的驱动程序需要这种能力。在很多情况下,内核执行了该种映射,而无需驱动程序的参与。
  • 直接内存访问(DMA)I/O操作,它使得外设具有直接访问系统内存的能力。

一、Linux的内存管理

关注Linux内存管理实现的主要特性,而非讲述操作系统中内存管理的理论。

地址类型

Linux是一个虚拟内存系统,意味着用户程序所使用的地址与硬件使用的物理地址是不同的。

虚拟内存是一个简介层,系统中运行的程序可以分配比物理内存更多的内存。甚至单独进程都拥有比系统物理内存更多的虚拟地址空间。

在任何情况下使用何种类型的地址,内核代码并未明确加以区分,因此程序对此要仔细处理。

  • 用户虚拟地址:这是在用户空间程序所能看到的常规地址。用户地址或者32位的,或者是64位的
  • 物理地址:该地址在处理器和系统内存之家使用。
  • 总线地址:该地址在外围总线和内存之间使用。通常他们与处理器使用的物理地址相同,但这么做并不是必须的。一些计算机提供I/O内存管理(MMU),实现总线和主内存之间的重新映射。
  • 但使用DMA时,MMU变成了一个额外的操作。
  • 内核逻辑地址:内核逻辑地址组成了内核的常规地址空间。kmalloc返回的就是内核逻辑地址
  • 内核虚拟地址:内核虚拟地址和内核逻辑地址,都将内核空间的地址映射到物理地址上。内核虚拟地址与物理地址的映射不是一一对应的。

物理地址和页

高端与低端内存

内存映射和页结构

扫描二维码关注公众号,回复: 3627678 查看本文章

页表

虚拟内存区

vm_area_struct结构

内存映射处理

二、mmap设备操作

使用remap_pfn_range

一个简单的实现

为VMA添加操作

使用nopage映射内存

重映射特定的I/O区域

重新映射RAM

使用nopage方法重映射RAM

重新映射内核虚拟地址

三、执行直接I/O访问

异步I/O

直接访问内存

DMA数据传输概览

分配DMA缓冲区

DIY分配

总线地址

通用DMA层

处理复杂的硬件

DMA映射

建立一致性DMA映射

DMA池

建立流式DMA映射

单页流式映射

分散/聚集映射

PCI双重地址周期映射

一个简单的PCI DMA例子

ISA设备的DMA

注册DMA

与DMA控制器通信

猜你喜欢

转载自www.cnblogs.com/ch122633/p/9816066.html