none
How to map MDL to PCIe BAR0, BAR2 of Straxtix IV board? RRS feed

  • Question

  • After user virtual address had has an MDL for processing itself in Kernel mode. I want to read/write the address at BARs PCIe, not in system memory.

    how can I handle it? 

    Here is the code call ZwReadFile read the file from the kernel buffer to the user and ZwWriteFile write files from user to kernel buffer;

     FileDiskThread (/*first call KeSetPriorityThread change the thread priority for LOW_REALTIME_PRIORITY,*/
        IN PVOID Context
        )
    {
        PDEVICE_OBJECT      device_object;
        PDEVICE_EXTENSION   device_extension;
        PLIST_ENTRY         request;
        PIRP                irp;
        PIO_STACK_LOCATION  io_stack;
        PUCHAR              system_buffer;
        PUCHAR              buffer;

        PAGED_CODE();//detect code that runs at IRQL >= DISPATCH_LEVEL,                                      

        ASSERT(Context != NULL);

        device_object = (PDEVICE_OBJECT) Context;

        device_extension = (PDEVICE_EXTENSION) device_object->DeviceExtension;

        KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);

        FileDiskAdjustPrivilege(SE_IMPERSONATE_PRIVILEGE, TRUE);

        for (;;)
        {
            KeWaitForSingleObject( //wait for the event object signal
                &device_extension->request_event,
                Executive,  
                KernelMode,
                FALSE,
                NULL
                );

            if (device_extension->terminate_thread)
            {
                PsTerminateSystemThread(STATUS_SUCCESS);
            }
    while ((request = ExInterlockedRemoveHeadList(//removes an entry from the beginning of a doubly linked list of LIST_ENTRY structures.
                &device_extension->list_head,
                &device_extension->list_lock
                )) != NULL)
            {
                irp = CONTAINING_RECORD(request, IRP, Tail.Overlay.ListEntry); 
    //and the address of a field within the containing structure.
                io_stack = IoGetCurrentIrpStackLocation(irp);

                switch (io_stack->MajorFunction)
                {

    case IRP_MJ_READ: system_buffer = (PUCHAR) MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority); if (system_buffer == NULL) { irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; irp->IoStatus.Information = 0; break; } buffer = (PUCHAR) ExAllocatePoolWithTag(PagedPool, io_stack->Parameters.Read.Length, FILE_DISK_POOL_TAG); if (buffer == NULL) { irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; irp->IoStatus.Information = 0; break; } ZwReadFile( device_extension->file_handle, NULL, NULL, NULL, &irp->IoStatus, buffer, io_stack->Parameters.Read.Length, &io_stack->Parameters.Read.ByteOffset, NULL ); RtlCopyMemory(system_buffer, buffer, io_stack->Parameters.Read.Length); ExFreePool(buffer); break; case IRP_MJ_WRITE: if ((io_stack->Parameters.Write.ByteOffset.QuadPart + io_stack->Parameters.Write.Length) > device_extension->file_size.QuadPart) { irp->IoStatus.Status = STATUS_INVALID_PARAMETER; irp->IoStatus.Information = 0; break; } ZwWriteFile( device_extension->file_handle, NULL, NULL, NULL, &irp->IoStatus, MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority), io_stack->Parameters.Write.Length, &io_stack->Parameters.Write.ByteOffset, NULL ); break;

    Thanks and regards.

     




    • Edited by Baothinh95 Monday, June 5, 2017 7:22 PM
    Monday, June 5, 2017 7:12 PM

Answers

  • Your original question is "After user virtual address had has an MDL for processing itself in Kernel mode. I want to read/write the address at BARs PCIe, not in system memory."  For access a BAR you use MmMapIoSpace, so instead of copying to/from a system buffer you would copy to/from the virtual address that is returned from that call.

    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    • Marked as answer by Baothinh95 Wednesday, June 7, 2017 8:05 AM
    Tuesday, June 6, 2017 1:42 PM

All replies

  • I am at a complete loss on trying to figure out what you're trying to do. What do you think Zw{Read|Write}File have to do with accessing a BAR? Please explain

     -Brian


    Azius Developer Training www.azius.com Windows device driver, internals, security, & forensics training and consulting. Blog at www.azius.com/blog

    Monday, June 5, 2017 7:51 PM
    Moderator
  • To go beyond what Brian asked, what is the purpose of this driver to begin with.  FileDisk is an old sample (stolen by the way and it is still possible the original author can sue if used in a commercial product), that supports a driver that acts like a disk with a file on the file system being the media.    I can't see where you would think you need to access PCI hardware from this driver.

    If you are looking to access a PCI device and present a disk, look at the Storport code.   If you are trying to do something else tell us, and we will suggest an approach.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Monday, June 5, 2017 8:29 PM
  • I referenced some data flow(see attached image1), I figured that the driver using Direct I/O with PIO to read/write the data. 

    In image1 it has MDL for Buffer in order to processing in Kernel. And about MDL for AliasBuffer I think it handle read/write in memory.

    So, I hypothesize that I change MDL for AliasBuffer to reference the DDR3 of FPGA (Stratix IV board). I do not know whether it works?

    I searched and found the image2 in OSRonline, the image describe something like image1.

    here is the link topic:

    1/ https://msdn.microsoft.com/en-us/library/windows/hardware/ff565381(v=vs.85).aspx

    2/ https://www.codeproject.com/Articles/8651/A-simple-demo-for-WDM-Driver-development (at I/O Support : Direct I/O Mode)

    Please tell me that I could do it.

    Thank you very much! 

    Image1:

    Image2:


    • Edited by Baothinh95 Tuesday, June 6, 2017 4:59 AM
    Tuesday, June 6, 2017 4:58 AM
  • But what are you trying to do? What kind of device is this? What kind of driver are you trying to write?

     -Brian


    Azius Developer Training www.azius.com Windows device driver, internals, security, & forensics training and consulting. Blog at www.azius.com/blog

    Tuesday, June 6, 2017 5:27 AM
    Moderator
  • I'm trying to mount a memory that contained in FPGA into disk drive. The device is Stratix IV which connect through port PCIe. I found Filedisk driver can mount into a virtual diskdrive, I read source code and see the place it read/write the data from user to kernel, I showed above.

    • Edited by Baothinh95 Tuesday, June 6, 2017 8:10 AM
    Tuesday, June 6, 2017 6:13 AM
  • Use a Virtual Storport Driver see http://www.osronline.com/article.cfm?article=538   FileDisk is old and incomplete, and is a terrible start for what you are trying to do.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Tuesday, June 6, 2017 11:30 AM
  • I see in https://www.acc.umu.se/~bosse/ . They update for compatibility with Visual 2015+ WDK10. So, you mean that following this project is wrong way and I can't finish what I'm trying to do?

    Best regards.

    Tuesday, June 6, 2017 12:29 PM
  • It is missing a lot (the sample is over 20 years old), so you might get it working somewhat, then spend months decoding what is needed to make it a fully functional disk.  If you use a virtual storport then Microsoft takes care of much of that for you.   Any experienced developer in Windows today would start with the Storport model.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Tuesday, June 6, 2017 12:38 PM
  • Thanks for your reply. actually, I don't have to make a fully functional disk. I need to fake it showing in explore, and can read/write file, of course the memory in FPGA. Please tell me I can or cannot.

    I'm so grateful !
    Tuesday, June 6, 2017 12:48 PM
  • All I can say is try the unmodified FileDisk if it does everything you need, then in theory you can do it with this software.  I don't use FileDisk since I have known the original author from the beginning, and remember the pain in trying to stop the theft of the software, and the malicious placing of the code in open source.

    I will say if this ever becomes anything more than a demo, you would be wise to use something other than FileDisk, even the Microsoft pseudo disk sample is better than this.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Tuesday, June 6, 2017 12:54 PM
  • Yes, I know the importance of copyright. But from the beginning, I tried to find open source to learn and follow. Finally, my demo is just a small project at a small university. I also did not have much time, so I continued to do what I started and also apologized to the author.

    With regards.

    Tuesday, June 6, 2017 1:05 PM
  • would you please have a look in those image above? 

    Thank you!

    Tuesday, June 6, 2017 1:22 PM
  • Your original question is "After user virtual address had has an MDL for processing itself in Kernel mode. I want to read/write the address at BARs PCIe, not in system memory."  For access a BAR you use MmMapIoSpace, so instead of copying to/from a system buffer you would copy to/from the virtual address that is returned from that call.

    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    • Marked as answer by Baothinh95 Wednesday, June 7, 2017 8:05 AM
    Tuesday, June 6, 2017 1:42 PM
  • This is the answer I need the most today. I'm very grateful.

    With regards.


    • Edited by Baothinh95 Tuesday, June 6, 2017 1:52 PM
    Tuesday, June 6, 2017 1:52 PM
  • To amplify about FileDisk this was more than just Copyright.  The original developer was kind enough to share with some people if they specifically requested it from him and agreed to not use it commercially or distribute it.  The individual who put it into open source ignored all this removed the original copyright and claimed it as his own.

    Microsoft and others put out samples that are freely useable, but are much better quality than most of the open source samples for Windows.  There is absolutely no reason to use a GNU licensed sample for a windows driver.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Wednesday, June 7, 2017 12:17 AM
  • Thank you for your time. I'm very appreciate your guidance. It helps me a lot. My knowledge will not be enough to do great things with this source code, what I need is the results to graduate. After graduation, maybe I will not go in this direction anymore.

    With regards.

    Wednesday, June 7, 2017 3:16 AM
  • One more question. Can I use MmMapIoSpace in the code I listed above? I want to hear the assertion from you, please!

    with regards.

    Wednesday, June 7, 2017 8:29 AM
  • It is better to call MmMapIoSpace earlier in the driver (in DeviceAdd but IIRC FileDisk doesn't have one) and leave the information setup, but yes you can do it here.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Wednesday, June 7, 2017 10:33 AM
  • Thanks for your guidance.

    with regards.

    Wednesday, June 7, 2017 1:08 PM
  • It comes up with the problem "The MmMapIoSpace routine maps the given physical address range to nonpaged system space." . How can I open the given physical address? I think it must be open the PCIe device, after that we can go further. It's really big challenge to me. Please give me some instructions.

    With regards.

    Wednesday, June 7, 2017 5:21 PM
  • Throw out FileDisk, from the beginning you implied you had access to the device.   At this point you have do a PnP driver, so the easiest solution is to do virtual storport I suggested initially.   

    There is no "open the PCIe" device, you have to have the resources assigned to you which means PnP.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Wednesday, June 7, 2017 5:25 PM