1.  ExAllocatePool()

函数说明:

ExAllocatePool allocates pool memory of the specified type and returns a pointer to the allocated

block.

函数定义:

PVOID ExAllocatePool(

__in  POOL_TYPE PoolType,

__in  SIZE_T NumberOfBytes

);

代码中用来分配设备描述DMA adepter设备的特性(DEVICE_DESCRIPTION),作为参数传递给IoGetDmaAdapter()函数。在调用IoGetDmaAdapter()函数之前就要对PDEVICE_DESCRIPTION结构进行指定各种特性。

实际中这样使用:

PDEVICE_DESCRIPTION DeviceDescription = (PDEVICE_DESCRIPTION) ExAllocatePool

(PagedPool, sizeof(DEVICE_DESCRIPTION));

2. RtlZeroMemory()

函数说明:

The RtlZeroMemory routine fills a block of memory with zeros, given a pointer to the block and the length, in bytes, to be filled.

函数定义:

VOID RtlZeroMemory(

__in  VOID UNALIGNED *Destination,

__in  SIZE_T Length

);

3. IoGetDmaAdapter()

函数说明:

The IoGetDmaAdapter routine returns a pointer to the DMA adapter structure for a physical device object.

函数定义:

struct _DMA_ADAPTER* IoGetDmaAdapter(

__in_opt  PDEVICE_OBJECT PhysicalDeviceObject,

__in      struct _DEVICE_DESCRIPTION *DeviceDescription,

__out     PULONG NumberOfMapRegisters

);

实际代码中这样使用:

ULONG  NumberOfMapRegisters=100;

pdx->DmaAdapter=IoGetDmaAdapter(pdx->NextStackDevice,DeviceDescription,&NumberOfMapRegisters);// NextStackDevice在AddDevice函数中已经attach了。

4. AllocateCommonBuffer()

函数说明:

The AllocateCommonBuffer routine allocates memory and maps it so that it is simultaneously accessible from both the processor and a device for DMA operations。

函数定义:

PVOID AllocateCommonBuffer(

__in   PDMA_ADAPTER DmaAdapter,

__in   ULONG Length,

__out  PPHYSICAL_ADDRESS LogicalAddress,

__in   BOOLEAN CacheEnabled

);

注:第一个参数是IoGetDmaAdapter()返回的,第三个参数是自己顶一顶一个物理地址类型,用来接收分配得到的物理地址首址。

返回值:返回值为虚拟地址,供上层使用

实际代码中这样使用:

pdx->descAddress=pdx->allocateCommonBuffer(pdx->DmaAdapter,(ULONG)DESC_ADDRESS*PORT_NUM,&pdx->DescLogicalAddress,FALSE);

附:使用该函数必不可少的会使用下面的函数

pdx->DmaAdapter=IoGetDmaAdapter(pdx->NextStackDevice,DeviceDescription,&NumberOfMapRegisters);

//创建一个DMA适配器

pdx->allocateCommonBuffer=*pdx->DmaAdapter->DmaOperations->AllocateCommonBuffer;

//分配连续的物理内存DMA函数

pdx->freeCommonBuffer = *pdx->DmaAdapter->DmaOperations->FreeCommonBuffer;

//释放连续的物理内存DMA函数

pdx->putDmaAdapter=*pdx->DmaAdapter->DmaOperations->PutDmaAdapter;

//释放DMA Adapter对象

当通过AllocateCommonBuffer()分配得到地址之后需要把这个地址分成两部分来处理,与硬件打交道的需要用LogicAddress 与 应用程序打交道需用 Virtual Address.

最好将AllocateCommonBuffer()函数取得的这两个地址保存到设备扩展中特定的变量中(根据内存块的用处),便于以后操作。可以这样做:

pdx->RxDescVirBase=(PCHAR)pdx->descAddress;

pdx->RxDescPhyBase=(ULONG)(pdx->DescLogicalAddress.LowPart); //物理地址

WRITE_REGISTER_ULONG( (PULONG)&pdx->pHBARegs->RxAddr_des_0,pdx->rx_fc_des

c_buf_phy[0]+16);

WRITE_REGISTER_ULONG( (PULONG)&pdx->pHBARegs->RxAddr_des_addr0_ptr,pdx->r

x_fc_desc_buf_phy[0]+4);

注意前面的 +16 和 +4 实际分别代表美一块内存的的偏移位置,由于我们定义了这块内存的结构,并在里面布局,+16 其实代表了struct rx_fc_ctl_tab 结构中的 struct rx_fc_desc_entity entity[RX_FC_DESC_NUM] 域,这里又是一个结构,也就是我们最终会用到的“描述符”。注意:我们这里的操作是将一个地址写到一个寄存器,这个地址必须是物理地址,也就是前面说的LogicAddress。这里pHBARegs是通过pdx->pHBARegs=(PHBA_REGS)pdx->RegsBase;    
获得的,也就是在CmResourceTypeMemory传过来时解析,代表硬件提供的DMA寄存器首址。

对于硬件的初始化就是通过WRITE_REGISTER_ULONG()函数来完成,针对设备的起始地址来进行偏移,自己定义结构来匹配各个寄存器的内容,注意这个自己定义的结构一定要严格跟硬件寄存器相同,一bit都不能差。

PCI设备内存操作函数总结的更多相关文章

  1. c++ void,内存操作函数

    void的含义 void的字面意思是“无类型”, void * 则为“无类型指针”, void * 可以指向任何类型的数据 void几乎只有“注释”和限制程序的作用,因为从来没有人会定义一个void变 ...

  2. c#读写共享内存操作函数封装

    原文 c#读写共享内存操作函数封装 c#共享内存操作相对c++共享内存操作来说原理是一样,但是c#会显得有点复杂. 现把昨天封装的读写共享内存封装的函数记录下来,一方面希望给需要这块的有点帮助,另一方 ...

  3. Delphi中复制带有String的记录结构时不能使用Move之类的内存操作函数

    请看下面的代码: program TestRecord; {$APPTYPE CONSOLE} uses  SysUtils,  Math; type  TRecordA = record    Na ...

  4. 内存操作函数memmove,memcpy,memset

    通过字符串的学习,我们知道字符串操作函数的操作对象是字符串,并且它的结束标志是结束符\0,当然这个说的是不 受限制的字符串函数.然而当我们想要将一段内存的数据复制到另一块内存时,我们不能使用字符串操作 ...

  5. C语言中内存操作函数

      一.malloc/calloc 名称: Malloc/calloc 功能: 动态内存分配函数 头文件: #include <stdlib.h> 函数原形: void *malloc(s ...

  6. 自己实现内存操作函数memset(),memcmp(),memcpy(),memmove()

    1.memset()内存设置函数(初始化) void *my_memset(void* dest, int c, size_t count) { assert(dest != NULL); char  ...

  7. 【转】C内存操作函数

    一.malloc/calloc 名称: Malloc/calloc 功能:  动态内存分配函数 头文件: #include <stdlib.h> 函数原形: void *malloc(si ...

  8. c语言学习之基础知识点介绍(十九):内存操作函数

    一.malloc函数 /* 首先需要导入头文件 #include <stdlib.h> malloc void* malloc(n); n是字节大小 开辟堆空间,开辟的字节数以n为准 返回 ...

  9. Delphi 的内存操作函数(1): 给字符指针分配内存

    马上能想到的函数有: GetMem AllocMem ReallocMem FreeMem GetMemory ReallocMemory FreeMemory New Dispose NewStr ...

随机推荐

  1. 数据库MySQL的基本操作

    1.MySQL数据库的安装: CentOS6上mysql服务端和客户端的安装和启动: #使用yum安装mysql数据库的服务端和客户端 yum install -y mysql mysql-serve ...

  2. ABP官方文档翻译 2.2 ABP会话

    ABP会话 介绍 关于IAbpSession 注入会话 会话属性 覆盖当前会话值 警告! 用户标示 介绍 如果应用需要登录的话,同样也需要知道当前用户可以执行哪些操作.ABP在展现层提供了会话对象,同 ...

  3. POJ [P3020] Antenna Placement

    二分图匹配求最小边覆盖 建图方法中的黑白染色法,题目中说信号可以覆盖相邻两个块,那么我们可以将给定的地图染成国际象棋棋盘的样子,一个黑格可以与周围的四个白格共用信号,对于城市,从每一个黑格出发,向其周 ...

  4. css模板

    最近好多人问我博客的css模板.... 现在是高三,没多少时间,趁放假赶紧更一下 主体就是把博客园的一个模板改动了一点 上面的图片特效,也是从别人那里得到的代码,大致就是下面那些,下面的三个图片换成自 ...

  5. BZOJ 2004: [Hnoi2010]Bus 公交线路 [DP 状压 矩阵乘法]

    传送门 题意: $n$个公交站点,$k$辆车,$1...k$是起始站,$n-k+1..n$是终点站 每个站只能被一辆车停靠一次 每辆车相邻两个停靠位置不能超过$p$ 求方案数 $n \le 10^9, ...

  6. POJ 3581 Sequence [后缀数组]

    Sequence Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6911   Accepted: 1543 Case Tim ...

  7. SDN第四次作业

    作业链接 1.阅读 了解SDN控制器的发展 http://www.sdnlab.com/13306.html http://www.docin.com/p-1536626509.html 了解ryu控 ...

  8. 《第一行代码 android》 读书笔记:找出当前界面对应的Activity

    在android开发中找出当前界面对应的Activity,步骤如下: 新建一个BaseActivity继承自Activity,然后在BaseActivity中重写onCreate()方法,通过getC ...

  9. 小甲鱼OD学习第9讲

    这次我们的任务是破解这个要注册的软件,如下图所示 当我们输入账号密码的时候,它会提示输入的账号密码是无效的,如下图 我们把程序载入OD,然后在查找字符串那里输入提示的无效账号密码的字符串,如下图 然后 ...

  10. SaltStack 的远程执行机制

    html,body { font-size: 15px } body { font-family: Helvetica, "Hiragino Sans GB", "微软雅 ...