在驱动层直接使用应用层的空间

</pre><p>需求:应用层申请一个空间,然后将地址传递到驱动层,驱动直接将处理后的数据放到应用层指定的空间中,类似于Linux下的copy_from_user。</p><p></p><p>应用层代码片段:</p><p><span style="white-space:pre">将申请的地址传递到驱动层</span></p><pre code_snippet_id="576642" snippet_file_name="blog_20150110_2_1402064" name="code" class="cpp">        CHAR    buf[64] = {0};
	int iWriteLen = 0;
	char *pWaddr = NULL;
	char *pRaddr = NULL;
	unsigned long *pTmp = NULL;

	pWaddr = (char*)calloc(1, 32);
	pRaddr = (char*)calloc(1, 32);
	if ((pWaddr ==NULL) || (pRaddr==NULL))
	{
		puts("calloc error");
		CloseHandle(hDevice);
		return 0;
	}

	memset(pWaddr, 'A', 24);
	pTmp = (unsigned long*)buf;

	pTmp[0] = (unsigned long)0;//pWaddr;
	pTmp[1] = (unsigned long)pRaddr;

	if (WriteFile(hDevice, buf, 8, (LPDWORD)&iWriteLen, NULL))
	{
		puts("write Success");
	}
	else
	{
		puts("Write Failed");
	}

驱动层代码片段:

VOID uAddr2dAddr(PVOID pUsr, unsigned long iUsrLen, BOOLEAN bRead)
{
	int i = 0;
	LOCK_OPERATION opt = IoWriteAccess;
	PUCHAR pVir = NULL;
	PMDL mdl ;

	if (!MmIsAddressValid(pUsr))//如果没有这个判断,应用传入的是非法地址时,会导致在下面获得虚拟地址时,蓝屏
	{
		KdPrint(("MmIsAddressValid UnIvalid error\n"));
		return ;
	}

	mdl = IoAllocateMdl(pUsr, iUsrLen, FALSE, TRUE, NULL);

	if (mdl == NULL)
	{
		KdPrint(("IoAllocateMdl error\n"));
		return ;
	}
	if (bRead)
	{
		opt = IoReadAccess;
	}

	MmProbeAndLockPages(mdl, UserMode, opt);

	pVir = MmMapLockedPagesSpecifyCache(mdl,KernelMode,MmCached,NULL,FALSE,NormalPagePriority);//如果pUser不合法时,调用此函数会引起蓝屏
	KdPrint(("MmMapLockedPagesSpecifyCache: %#x\n", (unsigned long)pVir));

	pVir = MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority);<span style="font-family: Arial, Helvetica, sans-serif;">//如果pUser不合法时,调用此函数会引起蓝屏</span>

	KdPrint(("MmGetSystemAddressForMdlSafe: %#x\n", (unsigned long)pVir));

	pVir =  MmGetMdlVirtualAddress(mdl);<span style="font-family: Arial, Helvetica, sans-serif;">//如果pUser不合法时,调用此函数会引起蓝屏</span>

	KdPrint(("MmGetMdlVirtualAddress: %#x\n", (unsigned long)pVir));

	if (pVir == NULL)
	{
		KdPrint(("IoAllocateMdl error\n"));
		return ;
	}

	KdPrint(("\n----------------------DML Data------------------\n\n"));
	if (bRead)
	{
		for (i=0; i<4; i++)
		{
			for (i=0; i<4; i++)
			{
				pVir[i] = 'B';
			}
		}
	}
	else
	{
		for (i=0; i<4; i++)
		{
			KdPrint(("%c ", pVir[i]));
		}
	}
	KdPrint(("\n-------------------End DML Data------------------\n\n"));

	MmUnlockPages(mdl);

	IoFreeMdl(mdl);

}

用DbgView打印驱动中:分别通过3个函数获得的虚拟地址值如下:

MmMapLockedPagesSpecifyCache: 0xae44b3b0

MmGetSystemAddressForMdlSafe: 0xae44b3b0

MmGetMdlVirtualAddress: 0x7013b0

以上三个函数都可以完成需求。

代码下载:

时间: 2024-10-10 13:17:39

在驱动层直接使用应用层的空间的相关文章

2、CC2541芯片中级教程-OSAL操作系统(进一步了解-OLED &amp;&amp; 普通按键和5方向按键-中断!!!)这个系统驱动层和应用层不一样~

本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 中级教程-OSAL操作系统(OSAL系统解基本套路) 中级教程-OSAL操作系统(进一步了解-OLED && 普通按键和5方向按键-中断!!!)这个系统驱动层和应用层不一样~ 中级教程-OSAL操作系统(ADC-光敏电阻) OSAL操作系统-实验16 串口波特率扩展 OSAL操作系统-实验1

Linux 网卡驱动学习(六)(应用层、tcp 层、ip 层、设备层和驱动层作用解析)

本文将介绍网络连接建立的过程.收发包流程,以及当中应用层.tcp层.ip层.设备层和驱动层各层发挥的作用. 1.应用层 对于使用socket进行网络连接的server端程序.我们会先调用socket函数创建一个套接字: fd = socket(AF_INET, SOCK_STREAM, 0); 以上指定了连接协议,socket调用返回一个文件句柄,与socket文件相应的inode不在磁盘上,而是存在于内存. 之后我们指定监听的port.同意与哪些ip建立连接,并调用bind完毕port绑定:

Minifilter微过滤框架:框架介绍以及驱动层和应用层的通讯

minifilter是sfilter后微软推出的过滤驱动框架.相比于sfilter,他更容易使用,需要程序员做的编码更简洁. 系统为minifilter专门制作了一个过滤管理器,这个管理器本身其实是一个传统过滤驱动,它向minifilter的使用者提供许多接口,让原本复杂的文件过滤驱动变得方便简单.之所以简单是因为传统的过滤驱动把大量的工作放在绑定设备上,而现在这些工作都交给minifilter中的过滤管理器来完成. 缺点:纯粹的使用minifilter提供的接口看不见设备对象和IRP的,所以编

DeviceIoControl 应用层如何和驱动层通信?

调用的方法之一的DeviceIoControl 驱动层提供设备名 例如filedisk 在驱动层 首先先是注册列表 用winObj查看 filedisk的驱动对象 但是 这八个对象时怎么生成的呢? 我们在加载filedisk.sys驱动时进行中断 查看过程 具体的双击调试 看我的另一篇文章 http://www.cnblogs.com/UnMovedMover/p/3690369.html 在下载的源码filedisk中sys下面的filedisk-17\filedisk-17\sys\src

s5p4418 Android 4.4.2 驱动层 HAL层 服务层 应用层 开发流程记录(一 硬件驱动层)

本文章是记录Android开发中驱动层.HAL层.应用层之间的关系,以及其开发方法,本文将会以实现LED的控制为例来进行记录. 一是可以给以后自己做开发做参考,二是希望可以帮助正在学习的朋友参考. 一般的app不需要我们去关注hal和驱动,但在设计一个硬件系统时,原生的Android并未提供合适的服务,所以我们才需要去了解这个流程.由于也是刚入门,很多还不太懂,朋友们有什么疑问可以留言. 首先需要了解,Android的app想要操作硬件,是什么样的一个流程.一般是这样的,app应用层.服务层.硬

14.linux-platform机制实现驱动层分离(详解)

版权声明:本文为博主原创文章,未经博主允许不得转载. 本节目标:        学习platform机制,如何实现驱动层分离 1.先来看看我们之前分析输入子系统的分层概念,如下图所示: 如上图所示,分层就是将一个复杂的工作分成了4层, 分而做之,降低难度,每一层专注于自己的事情, 系统只将其中的核心层和事件处理层写好了,所以我们只需要来写驱动层即可,接下来我们来分析platform机制以及分离概念 2.分离概念 优点: 将所有设备挂接到一个虚拟的总线上,方便sysfs节点和设备电源的管理 使得驱

《驱动学习 - platform机制实现驱动层分离》

1.先来看看我们之前分析输入子系统的分层概念,如下图所示: 如上图所示,分层就是将一个复杂的工作分成了4层, 分而做之,降低难度,每一层专注于自己的事情, 系统只将其中的核心层和事件处理层写好了,所以我们只需要来写驱动层即可,接下来我们来分析platform机制以及分离概念. 2.分离概念 优点: 将所有设备挂接到一个虚拟的总线上,方便sysfs节点和设备电源的管理 使得驱动代码,具有更好的扩展性和跨平台性,就不会因为新的平台而再次编写驱动 介绍: 分离就是在驱动层中使用platform机制把硬

块设备之设备驱动层

块设备是通过generic_make_request提交请求给I/O调度层,然后驱动层通过调用blk_init_queue来准备请求,这节来看看怎么样写一个块设备驱动程序.一个块设备的是由一个gendisk结构体来描述,每一个gendisk可以支持多个分区,内核对于块设备的访问,都是基于这个结构体展开 struct gendisk { int major; //主设备号 int first_minor; //第一个次设备号 int minors; //次设备个数,每个分区都需要一个次设备号 ch

QT开发(四十七)——数据库驱动层

QT开发(四十七)--数据库驱动层 驱动层为具体的数据库和SQL接口层之间提供了底层的桥梁,主要类包括Qt SQL模块中的QSqlDriver.QSqlDriverCreator.QSqlDriverCreatorBase.QSqlDriverPlugin和QSqlResult. 一.QSqlDriver QSqlDriver是访问具体SQL数据库的抽象基类,不能直接使用.如果要创建自定义的数据库驱动,可以根据需要重写QSqlDriver类的纯虚函数和虚函数. 自定义数据库驱动 QSqlData