zhangc98
驱动牛犊
驱动牛犊
  • 注册日期2002-03-30
  • 最后登录2004-10-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2047回复:6

请教大侠:有关WDM驱动程序中内存分配的问题

楼主#
更多 发布于:2002-06-01 23:13
    我毕业设计做一个ISA卡的驱动程序,眼看时间越来越少了,不得不着急,还请各位大侠多多帮忙,问题如下:
    驱动程序在启动设备的过程中,需要开辟一块32M的非分页内存给某个固定的设备扩展:dx->pLinearFactor,在应用程序中通过DeviceIoControl调用将一个32M的数据读入到这块内存中。开始是IOCTL的方式我定义的是METHOD_BUFFERED,可是后来看Waltoney的书上说超过一页的传输应该用DIRECT方式,就将其改过来,可是还是不行,一执行到这一步就出问题。我试过了,到1M大小的时候都没有什么问题,2M的时候就有问题了,是不是在这方面有限制?请问如果有限制的话,最大可以传送多大的数据呢?在开始启动设备时好像是分配成功了,就是DeviceIoControl的时候死机。如果真的是有限制的话,我用什么方法可以达到相同的效果呢?
    谢谢各位高人指点迷津,我实在很着急。
    有关程序如下:
case IOCTL_AMIS_SETLINEARFACTOR:
//先检查传来的数据大小是否小于PACQ_PARAMETERS_DEVICE的大小
if (IrpStack->Parameters.DeviceIoControl.InputBufferLength <33554432)
{
//返回内存不足信息
    DebugPrintMsg(\"The buffer is too small\");
    Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
}
else
{
 PULONG CurrentBuffer=(PULONG)  MmGetSystemAddressForMdl(Irp->MdlAddress);
RtlCopyMemory(dx->pLinearFactor , CurrentBuffer , 33554432);
DebugPrintMsg(\"Linear Factor\'s RtlCopyMemory successful!\");
}
//通知系统完成操作
status = Irp->IoStatus.Status;
break;

最新喜欢:

cb615cbcb615c...
目前:新手上路; 目标:高级站友; 理想:开国大佬; 方法:自己的努力+大家的关照!
zhangc98
驱动牛犊
驱动牛犊
  • 注册日期2002-03-30
  • 最后登录2004-10-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-06-01 23:22
我再补充一点,
在NT的驱动程序里面,
这一部分基本上是相同的,
而且还使用METHOD_BUFFERED的方式,
传输上没有什么问题。
这是怎么回事呢?

还是由于别的什么原因引起的呢?
谢谢!:)
目前:新手上路; 目标:高级站友; 理想:开国大佬; 方法:自己的努力+大家的关照!
mailme
驱动老牛
驱动老牛
  • 注册日期2001-05-21
  • 最后登录2010-02-25
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-06-02 10:55
我也遇到过你这种情况,一次要传输大量的数据到驱动程序中。当时看到Walter Oney的书里说有传输大小的限制,就没采用buffer方式,采用的direct方式,我试过10M数据量,一点问题都没有,包括98和2000。buffer方式是将数据拷贝到内核,direct方式我觉得好像是驱动直接操作用户层数据。

[编辑 -  6/2/02 by  mailme]
早起早睡 精神百倍
mailme
驱动老牛
驱动老牛
  • 注册日期2001-05-21
  • 最后登录2010-02-25
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-06-02 11:25
我把我的方法告诉你,希望对你能有所帮助:
1。首先设置DeviceIoControl参数:输入缓冲区随便设置,比如输入数据长度(32M);输出缓冲区很重要,将你的32M数据的地址赋给他,也就是用输出缓冲区来输入数据。
2。在驱动Control_handler中,先锁定内存页,然后获取MDL地址,然后你就可以访问你的32M数据了。记住最后不要忘记解锁内存页,不然机子就直接reset了:)
MmProbeAndLockPages(Irp->MdlAddress, KernelMode, IoReadAccess);
//pUserBuf是你的数据首地址
PULONG pUserBuf = (PULONG) MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);//2000下用
PULONG pUserBuf = (PULONG) MmGetSystemAddressForMdl(Irp->MdlAddress);//98下用

//访问你的数据
、、、、、、、、、

//切记解锁内存页!
MmUnlockPages(Irp->MdlAddress);
早起早睡 精神百倍
mailme
驱动老牛
驱动老牛
  • 注册日期2001-05-21
  • 最后登录2010-02-25
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-06-02 11:28
ft,居然误操作一次,白敲了那么多字:(
早起早睡 精神百倍
zhangc98
驱动牛犊
驱动牛犊
  • 注册日期2002-03-30
  • 最后登录2004-10-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-06-02 12:28
谢谢,不过我不知道输出缓冲区有什么用,
因为我的32M的数据是在驱动程序里面开辟的,
DeviceIoControl中不需要返回输出数据,
只是需要将外面的数据输入到驱动程序加载是开辟的非分页内存区域中供给驱动程序使用。我想应该不会用到输出缓冲区吧?
简单来说,这次数据传输仅仅是由客户端应用程序向内核驱动程序的单向传输。我用同样的程序在2000的环境下试,连128k的数据都自动重启,不知道是不是和操作系统有关系?

现在我想到的解决办法就是不用DeviceIoControl来完成,改用WriteFile来进行,初步试下来还是成功的:)

吼吼!
另外,不知道是不是由于bbs上的多了,经常在敲完一大段字后习惯性的按下Ctrl+W,导致(*&%^^$%^$*(&^&*%&^$
实在是恼火,你是不是也这样啊:)
目前:新手上路; 目标:高级站友; 理想:开国大佬; 方法:自己的努力+大家的关照!
mailme
驱动老牛
驱动老牛
  • 注册日期2001-05-21
  • 最后登录2010-02-25
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-06-02 23:42
1.在direct方式下,DeviceIoControl就是用输出缓冲区来“传输”你的输入数据的(实际上是让你在驱动中获得你的32M数据首地址,通过MDL),这里的输出缓冲区并没有起通常的输出缓冲区作用,这一点我以前也很糊涂。反正,如果direct方式中你想“传输”数据到驱动中,必须在用户层把数据缓冲区的首地址丢在DeviceIoControl的输出缓冲区的参数中。这样,你在驱动中就可以访问这个缓冲区了,就好像它是你在驱动程序中分配的内存一样。我的驱动也是从应用层向内核单向传输数据,和你的一样,我用这个方法就很好。你可以好好研究一下walter oney的书,就在第七章读写数据的“寻址数据缓冲区”这一节和第九章专门问题的“I/O控制操作”这一节,再看看msdn中DeviceIoControl这个函数的用法。
2。WriteFile我没怎么用过,帮不上你了,我也是新手嘛:)
3。bbs很久没上了,主要是在家里总不能天天拨号吧,我还是满怀念以前一个年级齐上阵灌水地那种壮观场面di,呵呵

早起早睡 精神百倍
游客

返回顶部