• 设备读写 之 直接方式(Direct I/O)


    这种方式需要在创建完设备对象后,为设备设置属性DO_DIRECT_IO

     

    和缓冲读写设备不同,直接方式读写设备,操作系统会将用户模式下的缓冲区锁住。然后操作系统将这段缓冲区在内核模式地址空间中再映射一遍。这样,用户模式的缓冲区和内核模式的缓冲区指向的是同一区域的物理内存。无论操作系统如何切换进程,内核模式地址保持不变。

     

    操作系统(IO管理器)先将用户模式的地址锁定后,操作系统(IO管理器)用内存描述符表(MDL 数据结构)记录这段内存。如下图。用户模式的这段缓冲区在虚拟内存上是连续的,但是在物理内存上可能是离散的。

     

     

     

     

    MDL记录这段虚拟内存,这段虚拟内存的大小存储在Mdl->ByteCount里,这段虚拟内存所在第一个页首地址是Mdl->StartVa,这段虚拟内存的首地址对于第一个页首地址的偏移量是Mdl->ByteOffset。因此,这段虚拟内存的首地址应该是:

    Mdl->StartVa + Mdl->ByteOffset

     

    下面是DDK定义的几个宏,方便我们得到这几个数值。

     

    #define MmGetMdlByteCount(Mdl) ((Mdl)->ByteCount)

    #define MmGetMdlByteOffset(Mdl) ((Mdl)->ByteOffset)

    #define MmGetMdlVirtualAddress(Mdl) \

         ((PVOID)((PCHAR)((Mdl)->StartVa) + ((Mdl)->ByteOffset))

     

    例子:

    // 读

    NTSTATUS Read(IN PDEVICE_OBJECT   DeviceObject,

                      IN PIRP             Irp)

    {

           PIO_STATCK_LOCATION IrpSp;

            ULONG ReadLength;

           ULONG MdlLength;

           ULONG MdlOffset;

           PVOID MdlAddress;

           ULONG KernelAddress;

     

       // 获得当前堆栈单元

       IrpSp = IoGetCurrentIrpStackLocation(Irp);

     

           // 获取应用层要读的字节数

       ReadLength = IrpSp->Parameters.Read.Length;

     

       // 得到应用层被锁定的虚拟缓冲区的长度

       MdlLength = MmGetMdlByteCount(Irp->MdlAddress);

     

       // 得到锁定缓冲区的偏移量

       MdlOffset = MmGetMdlByteOffset(Irp->MdlAddress);

     

       // 得到锁定缓冲区的虚拟地址

           MdlAddress = MmGetMdlByteOffset(Irp->MdlAddress);

     

       // 获得虚拟缓冲区在内核模式下的映射地址

       KernelAddress = MmGetSystemAddressForMdlSafe(Irp->MdlAddress);

     

           Irp->IoStatus.Status = STATUS_SUCCESS;

           Irp->IoStatus.Information = 0;

           IoCompleteRequest(Irp,IO_NO_INCREMENT);

     

       retrun STATUS_SUCCESS;

    }

  • 相关阅读:
    「仰望天空和脚踏实地」​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​写出我心(一百四十八)
    Backtrader中文笔记之Analyzers(二次修复)
    Backtrader中文笔记之Tick Data and Resampling
    NumPy学习记录
    mac通过ln创建软连接使用。
    mac电脑Pycharm的书签设置。
    matplotlib学习记录.
    Backtrader中文笔记之Pandas DataFeed Example
    Backtrader中文笔记之Using Indicators(指标)
    chmod
  • 原文地址:https://www.cnblogs.com/lzjsky/p/1881926.html
Copyright © 2020-2023  润新知