内存访问——直接内存访问(DMA)

Linux内存管理 —— DMA和一致性缓存 1. 出现内存不一致的原因 CPU写内存的时候有两种方式: 1. write through: CPU直接写内存,不经过cache。 2. write back: CPU只写到cache中。cache的硬件使用LRU算法将cache里面的内容替换到内存。通常是这种方式。 DMA可以完成从内存到外设直接进行数据搬移。但DMA不能访问CPU的cache,CPU在读内存的时候,如果cache命中... 阅读详情

1. 什么是DMA

直接内存访问是一种硬件机制,它允许外围设备和主内存之间直接传输它们的I/O数据,而不需要系统处理器的参与。使用这种机制可以大大提高与设备通信的吞吐量。

直接内存访问(DMA)方式是一种完全由硬件执行I/O交换的工作方式。DMA控制器从CPU完全接管对总线的控制。数据交换不经过CPU,而直接在内存和I/O设备之间进行。
DMA控制器采用以下三种方式:
① 停止CPU访问内存:当外设要求传送一批数据时,由DMA控制器发一个信号给CPU。DMA控制器获得总线控制权后,开始进行数据传送。一批数据传送完毕后,DMA控制器通知CPU可以使用内存,并把总线控制权交还给CPU。
②周期挪用:当I/O设备没有 DMA请求时,CPU按程序要求访问内存:一旦 I/O设备有DMA请求,则I/O设备挪用一个或几个周期。
③DMA与CPU交替访内:一个CPU周期可分为2个周期,一个专供DMA控制器访内,另一个专供CPU访内。不需要总线使用权的申请、建立和归还过程。

2. DMA数据传输

有两种方式引发数据传输:

第一种情况:软件对数据的请求

1. 当进程调用read,驱动程序函数分配一个DMA缓冲区,并让硬件将数据传输到这个缓冲区中。进程处于睡眠状态。

2. 硬件将数据写入到DMA缓冲区中,当写入完毕,产生一个中断

3. 中断处理程序获取输入的数据,应答中断,并唤起进程,该进程现在即可读取数据

第二种情况发生在异步使用DMA时

1. 硬件产生中断,宣告新数据的到来

2. 中断处理程序分配一个缓冲区,并且告诉硬件向哪里传输数据

3. 外围设备将数据写入数据区,完成后,产生另外一个中断

4. 处理程序分发新数据,唤醒任何相关进程,然后执行清理工作

 

高效的DMA处理依赖于中断报告。

 

3. 分配DMA缓冲区

使用DMA缓冲区的主要问题是:当大于一页时,它们必须占据连续的物理页,因为设备使用ISA或PCI系统总线传输数据,而这两种方式使用的都是物理地址。

使用get_free_pasges可以分配几M字节的内存(MAX_ORDER是11),但是对于较大数量(即使是远小于128KB)的请求,通常会失败,这是因为系统内存充满了内存碎片。

解决方法之一就是在引导时分配内存,或者为缓冲区保留顶部物理内存。

例子:在系统引导时,向内核传递参数“mem=value”的方法保留顶部的RAM。比如系统有256内存,参数“mem=255M”,使内核不能使用顶部的1M字节。随后,模块可以使用下面代码获得该内存的访问权:

dmabuf=ioremap(0XFF00000/**255M/, 0X100000/*1M/*);

解决方法之二是使用GPF_NOFAIL分配标志为缓冲区分配内存,但是该方法为内存管理子系统带来了相当大的压力。

解决方法之三十设备支持分散/聚集I/O,这可以将缓冲区分配成多个小块,设备会很好地处理它们。

 

4. 通用DMA层

DMA操作最终会分配缓冲区,并将总线地址传递给设备。内核提高了一个与总线——体系结构无关的DMA层。强烈建议在编写驱动程序时,为DMA操作使用该层。使用这些函数的头文件是<linux/dmamapping.h>。

int dma_set_mask(struct device *dev, u64 mask);

该掩码显示该设备能寻址能力对应的位。比如说,设备受限于24位寻址,则mask应该是0x0FFFFFF。

5. DMA映射

IOMMU在设备可访问的地址范围内规划了物理内存,使得物理上分散的缓冲区对设备来说成连续的。对IOMMU的运用需要使用到通用DMA层,而vir_to_bus函数不能完成这个任务。但是,x86平台没有对IOMMU的支持。

解决之道就是建立回弹缓冲区,然后,必要时会将数据写入或者读出回弹缓冲区。缺点是降低系统性能。

根据DMA缓冲区期望保留的时间长短,PCI代码区分两种类型的DMA映射:

一是一致性DMA映射,存在于驱动程序生命周期中,一致性映射的缓冲区必须可同时被CPU和外围设备访问。一致性映射必须保存在一致性缓存中。建立和使用一致性映射的开销是很大的。

二是流式DMA映射,内核开发者建议尽量使用流式映射,原因:一是在支持映射寄存器的系统中,每个DMA映射使用总线上的一个或多个映射寄存器,而一致性映射生命周期很长,长时间占用这些这些寄存器,甚至在不使用他们的时候也不释放所有权;二是在一些硬件中,流式映射可以被优化,但优化的方法对一致性映射无效。

6. 建立一致性映射

驱动程序可调用pci_alloc_consistent函数建立一致性映射:

void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, int falg);

该函数处理了缓冲区的分配和映射,前两个参数是device结构和所需的缓冲区的大小。函数在两处返回DMA映射的结果:函数的返回值是缓冲区的内核虚拟地址,可以被驱动程序使用;而与其相关的总线地址保存在dma_handle中。

当不再需要缓冲区时,调用下函数:

void dma_free_conherent(struct device *dev, size_t size, void *vaddr, dma_addr_t *dma_handle);

7. DMA池

DMA池是一个生成小型,一致性DMA映射的机制。调用dma_alloc_coherent函数获得的映射,可能其最小大小为单个页。如果设备需要的DMA区域比这还小,就是用DMA池。在<linux/dmapool.h>中定义了DMA池函数:

struct dma_pool *dma_pool_create(const char *name, struct device *dev, size_t size, size_t align, size_t allocation);

void dma_pool_destroy(struct dma_pool *pool);

name是DMA池的名字,dev是device结构,size是从该池中分配的缓冲区的大小,align是该池分配操作所必须遵守的硬件对齐原则(用字节表示),如果allocation不为零,表示内存边界不能超越allocation。比如说传入的allocation是4K,表示从该池分配的缓冲区不能跨越4KB的界限。

在销毁之前必须向DMA池返回所有分配的内存。

void * dma_pool_alloc(sturct dma_pool *pool, int mem_flags, dma_addr_t *handle);

void dma_pool_free(struct dma_pool *pool, void *addr, dma_addr_t addr);

8. 建立流式DMA映射       

在某些体系结构中,流式映射也能够拥有多个不连续的页和多个“分散/聚集”缓冲区。建立流式映射时,必须告诉内核数据流动的方向。

DMA_TO_DEVICE

DEVICE_TO_DMA

如果数据被发送到设备,使用DMA_TO_DEVICE;而如果数据被发送到CPU,则使用DEVICE_TO_DMA。

DMA_BIDIRECTTONAL

如果数据可双向移动,则使用该值

DMA_NONE

该符号只是出于调试目的。

当只有一个缓冲区要被传输的时候,使用下函数映射它:

dma_addr_t dma_map_single(struct device *dev, void *buffer, size_t size, enum dma_data_direction direction);

返回值是总线地址,可以把它传递给设备;如果执行错误,返回NULL。

当传输完毕后,使用下函数删除映射:

void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, enum dma-data_direction direction);

使用流式DMA的原则:

一是缓冲区只能用于这样的传送,即其传送方向匹配与映射时给定的方向值;

二是一旦缓冲区被映射,它将属于设备,不是处理器。直到缓冲区被撤销映射前,驱动程序不能以任何方式访问其中的内容。只用当dma_unmap_single函数被调用后,显示刷新处理器缓存中的数据,驱动程序才能安全访问其中的内容。

三是在DMA出于活动期间内,不能撤销对缓冲区的映射,否则会严重破坏系统的稳定性。             

如果要映射的缓冲区位于设备不能访问的内存区段(高端内存),怎么办?一些体系结构只产生一个错误,但是其他一些系统结构件创建一个回弹缓冲区。回弹缓冲区就是内存中的独立区域,它可被设备访问。如果使用DMA_TO_DEVICE标志映射缓冲区,并且需要使用回弹缓冲区,则在最初缓冲区中的内容作为映射操作的一部分被拷贝。很明显,在拷贝后,最初缓冲区内容的改变对设备不可见。同样DEVICE_TO_DMA回弹缓冲区被dma_unmap_single函数拷贝回最初的缓冲区中,也就是说,直到拷贝操作完成,来自设备的数据才可用。

有时候,驱动程序需要不经过撤销映射就访问流式DMA缓冲区的内容,为此内核提供了如下调用:

void dma_sync_single_for_cpu(struct device *dev, dma_handle_t bus_addr, size_t size, enum dma_data_directction direction);

应该在处理器访问流式DMA缓冲区前调用该函数。一旦调用了该函数,处理器将“拥有”DMA缓冲区,并可根据需要对它进行访问。然后在设备访问缓冲区前,应该调用下面的函数将所有权交还给设备:

void dma_sync_single_for_device(struct device *dev, dma_handle_t bus_addr, size_t size, enum dma_data_direction direction);

再次强调,处理器在调用该函数后,不能再访问DMA缓冲区了。

直接内存访问(DMA)算法 DMA控制器根据预先设置好的传输参数(如源地址、目的地址、传输长度等),直接在内存和设备之间进行数据的搬移,期间不需要CPU频繁地参与每一个数据字节的传输操作。包括源地址寄存器(指定数据的来源地址,比如设备的数据缓冲区地址)、目的地址寄存器(指定数据要传输到的内存地址)、传输长度寄存器(指定要传输的数据字节数)等。请注意,以上代码只是为了演示DMA传输控制和缓冲区管理的基本原理和实现方式,在实际应用中,可能需要根据具体的硬件平台和系统环境进行更深入的调整和优化。• 首先将内存中的数据填充到DMA缓冲区。 阅读详情

相关推荐

直接内存访问 (DMA) 控制器

本文设计了在高速外设和 DDR3 内存之间进行高效数据传输的直接内存访问 (DMA) 控制器,附有详细原理与源代码!!!

m0_67400176的博客 1679

关于dma_alloc_coherent的用法

目录 概述 DMA映射 建立一致性DMA映射 DMA池 建立流式DMA映射 单页流式映射 分散/聚集映射 PCI双重地址周期映射 DAC 简单的PCI DMA例子 ISA设备DMA 概述 DMA的操作是需要物理地址的,但是在linux内核中使用的都是虚拟地址,如果想要用DMA对一段内存进行操作,如何得到这一段内存的物理地址和虚拟地址的映射呢?dma_alloc_coherent这个函数实现了这种机制。 1、函数原型: void *dma_alloc_coherent( struct

六六哥的博客 1万+

集成电路学习:什么是DMA直接内存访问

DMA(直接内存访问)是一种计算机数据传输技术,允许外设直接访问内存而不经过CPU。其工作流程包括CPU初始化、DMA请求、总线控制权转移、数据传输和结束信号五个步骤。DMA技术能显著降低CPU负担,提高数据传输速度,广泛应用于磁盘I/O、网络通信和图形处理等领域。这项技术是现代计算机系统中实现高效数据传输的关键手段。

limengshi138392的博客 1355

dma_alloc_coherent DMA内存申请学习笔记

dma_alloc_coherent 相关的知识网络上有很多,将相关的知识收集汇总以便于后续遇到问题方便查找。这一次对dma_alloc_coherent进行学习的原因是在使用rapidio驱动时申请大于64M的DMA内存时,遇到多次申请无法申请到内存的情况(加大预留DMA内存不能解决)。进而学习一下相关知识看是否有方法能解决相关问题。遇到的问题DMA无法申请大于32M的内存,MAX_ORDER 这个宏设置的太小,这个宏限制了一次请求所能分配的最大物理页数。如果申请5MB内存,MAX_ORDER 需要不小于

qq_42254853的博客 8685

DMA(直接内存访问)是什么?

DMA(直接内存访问)是一种硬件技术,允许外设直接与内存交换数据而无需CPU参与,显著提升系统性能。其核心优势在于解放CPU资源、提高数据传输效率并降低功耗。DMA通过专用控制器实现,支持单次、突发和循环传输模式,广泛应用于视频采集、网络数据处理等场景。使用时需注意缓存一致性和内存安全问题。与CPU搬运相比,DMA在大批量数据传输中具有明显速度优势,是现代计算机系统中不可或缺的高效数据传输解决方案。

guigenyi的专栏 1309

ESP32-CAM入门教程

ArduinoESP32-CAM下载模块(接上USB就能用,很方便,如果没有买就只有资金用USB-TTL了)如下图两个合在一起如下图。

qq_48778364的博客 3万+

【STM32】直接内存访问DMA

        直接内存访问(DMA)允许不同速度的硬件装置来沟通,而不需要依赖于 CPU 的大量中断负载。在 STM32 中,DMA 可以在不占用 CPU 的情况下实现数据的快速传输,提高系统的效率。以下是一个基于 STM32Cube HAL 库的 DMA 驱动程序开发示例,以实现从内存到外设(如串口)的数据传输为例。

大雨淅淅的博客 1462

手把手教你用AirSim生成无人机训练数据集:RGB/深度图/分割图全攻略

本文详细介绍了如何使用AirSim仿真插件在UE4环境中生成无人机训练数据集,涵盖RGB、深度图和分割图等多种模态数据的采集与处理。通过实战指南,读者可以掌握环境配置、多模态数据采集、自动化流程设计及数据后处理等关键技术,为无人机视觉算法开发提供高质量训练数据。

weixin_29008805的博客 439

DMA访问(直接内存访问)

DMA的工作原理是,如果按数据块进行I/O,即需要传输大量数据时,就无须CPU的介入。在这种情况下,我们可以让I/O设备与计算机内存进行直接数据交换。而CPU则可以去忙别的事情。这种将CPU的介入减少的I/O模式称为直接内存访问。 问题是,将CPU从繁忙等待中解脱出来,难道DMA的整个数据读写过程不需要使用处理器的功能吗?当然不是。数据传输当然使用CPU,只不过这里使用的CPU不是计算机里面所有进程共享的CPU,而是由另外一个CPU来负责数据传输。这个另外的CPU就是DMA控制器。 也许读者会问,这有什么意

鸭梨的博客 1万+

Ubuntu桌面消失?可能是lightdm配置在捣鬼:详细解析/etc/lightdm.conf的优先级机制与实战修复

本文详细解析了Ubuntu系统因lightdm显示管理器配置错误导致桌面消失的问题。通过分析/etc/lightdm.conf的优先级加载机制,提供了从systemctl诊断、调试模式运行到实战修复配置语法错误(如缺失[Seat:*]组)的完整方案。文章还探讨了在系统无法启动时使用chroot或恢复模式进行高级救援,并对比了lightdm与gdm3在NVIDIA驱动环境下的不同表现,帮助用户高效恢复图形界面。

weixin_29313547的博客 414

避坑指南:SAP成本中心分割结构配置常见错误及解决(含KA06/KL01前置步骤)

本文深入解析了SAP成本中心会计中分割结构配置的关键步骤与常见错误。重点强调了配置前必须通过KA06创建次级成本要素(类别42)和通过KL01创建活动类型这两个核心前置步骤,并详细剖析了在OKES中定义分割规则及版本时的高频报错原因与解决方案,帮助顾问和运维人员有效规避配置陷阱,确保成本分摊的准确性。

pear55的博客 858

CW32L052 DMA直接内存访问

CW32L052支持DMA(Direct Memory Access),即直接内存访问,无需CPU干预,实现高速数据传输。

weixin_70940338的博客 1193

【信号与系统】Multisim 仿真信号合成与分解

软件 Multisim 进行方波信号的产生、分解和合成,观察信号波形的分解与合成,加深对信号频谱的理解。

AXYZdong的博客 2万+

直接内存访问(DMA)

直接内存访问是一种硬件机制,它允许外围设备和主内存之间直接传输它们的I/O数据,而不需要系统处理器的参与。使用这种机制可以大大提高与设备通信的吞吐量。

缘起宇轩阁 7076

[ 虚拟专用网 ] IPsce 虚拟局域网(安全的IP协议的虚拟专用网)详解(二) --- 安全联盟SA

???? 博主介绍 ????‍???? 博主介绍:大家好,我是_PowerShell,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 ????点赞➕评论➕收藏 == 养成习惯(一键三连)???? ????欢迎关注????一起学习????一起讨论⭐️一起进步????文末有彩蛋 ????作者水平有限,欢迎各位大佬指点,相互学习进步! 目录 ???? 博主介绍 一、什么是安全联盟 二、协商参数两种方式:(手动、IKE) 1. 手动 2.

qq_51577576的博客 2795

网络系统管理专栏-配套练习+知识点详解

网络系统管理专栏-配套练习+知识点详解

bfq05234214的博客 677

直接内存访问——DMA

DMA是一种允许外设不经过CPU直接与内存交换数据的硬件机制,文章介绍了其工作原理、工作流程和应用场景。

wtmdnsn的博客 1679

实战:RK3568 Android14 点亮 LVDS 屏幕

4组数据 (D0~D3) + 1组时钟 (CLK)。最大支持 1280x800 @ 60Hz。8组数据 (Even03, Odd03) + 2组时钟。支持 1080P 及以上。/ {/* 背光与电源 *//** 关键配置:数据格式映射* 可选值: "jeida-18", "jeida-24", "vesa-24"* 6位屏选 xx-18, 8位屏选 xx-24* 颜色不对(偏色/底片效果)就换 VESA <-> JEIDA*/

qq_33427070的博客 1160

直接内存访问--DMA

DMA数据传输: DMA允许外围设备和主内存之间直接传输 I/O 数据, DMA 依赖于系统。每一种体系结构DMA传输不同,编程接口也不同。 数据传输可以以两种方式触发:一种软件请求数据,另一种由硬件异步传输。 在第一种情况下,调用的步骤可以概括如下(以read为例): (1)在进程调用 read 时,驱动程序的方法分配一个 DMA 缓冲区,随后指示硬件传送它的数据。进程进

xp_super的专栏 7904

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

直接内存访问 (Direct Memory Access, DMA)

Table of Contents 直接内存访问 (Direct Memory Access, DMA) DMA 模型 设备 DMA 的类型 总线主控器 DMA 第三方 DMA 第一方 DMA 主机平台 DMA 的类型 DMA 软件组件:句柄、窗口和 Cookie DMA 操作 执行总线主控器 DMA 传送 执行第一方 DMA 传送 执行第三方 DMA 传送 DMA 特性...

RToax 3241

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

linux中直接内存访问(DMA)

1. 什么是DMA 直接内存访问是一种硬件机制,它允许外围设备和主内存之间直接传输它们的I/O数据,而不需要系统处理器的参与。使用这种机制可以大大提高与设备通信的吞吐量。   2. DMA数据传输 有两种方式引发数据传输: 第一种情况:软件对数据的请求 1. 当进程调用read,驱动程序函数分配一个DMA缓冲区,并让硬件将数据传输到这个缓冲区中。进程处于睡眠状态。 2. 硬件将数据写

u014379540的博客 2457

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

DMA(Direct Memory Access):直接内存访问

DMA(Direct Memory Access)即直接存储器访问,通过内部控制器实现内存和外设之间的数据传输。DMA的引入使得CPU可以专注于内存数据的处理,而数据的搬运工作由DMA硬件完成。开始传输时刻:DMA向CPU申请总线周期的占用时间。结束传输时刻:DMA向CPU发送中断请求,请求CPU处理数据。fill:#333;CPUDMAMemoryDevice开始传输时刻DMA请求申请总线周期批准总线占用读取/写入数据结束传输时刻发送中断请求处理数据CPUDMAMemory。

码事漫谈 2415

DMA直接内存访问

DMA 直接内存访问(DMA)是一种内存访问技术。它允许某些电脑内部的硬件子系统,可以独立地直接读写系统内存,而不需要中央处理器CPU介入处理。在同等程度的处理负担下,DMA是一种快速的数据传送方式。很多硬件的系统会使用DMA,包括硬件控制器,绘图显卡,网卡和声卡。 DMA是所有现代电脑的重要特色,它允许不同速度的硬件设备沟通,而不需要依赖于中央处理器的大量中断负载。否则,中央处理器需要从来源把每一片段的资料复制到寄存器,然后把它们再次写回到新的地方。在这个时候,中央处理器对于其他的工作来说就无法使用。 D

qq_36553387的博客 2734
上一篇: Linux忘记用户密码时如何登陆系统方法详解~
下一篇: Html.ActionLink()重载方法简介
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值