none
Accessing PCI Expansion ROM in NDIS 6.x driver (Need to assign ROMBAR) RRS feed

  • Question

  • Hello

    Currently trying to find a way of reading from an expansion ROM on a PCI card. It is possible to do this by setting ROMBAR, however it appears that it is presently 0x00000000 (disabled). It seems that either Windows (or the BIOS?) doesn't assign any address to this.

    How would I go about this? It looks likely I could assign it a physical address with NdisMSetBusData(), but what physical address? Is it possible to arbitrarily allocate physical PCI memory space?

    Or have I completely missed the point here? Perhaps there is a way to get the O/S to allocate ROMBAR, so I can then call NdisMMapIoSpace() to map that address?

    Friday, November 16, 2018 11:26 AM

Answers

  • The expansion ROM is mapped at boot time so the code within can be executed, but it is disabled once boot completes.  If the vendor didn't provide another way to read the expansion ROM (like using an additional BAR), then there's no good way to get it.

    Even if you are debugging in the lab, it's tricky to hack this.  The PCIe root complex only passes along physical addresses within a certain range.  You would have to go pick an address that is not already in use, shove it into the configuration space, and then map it.  However, you CERTAINLY cannot do this in a production driver.  If there is information your driver needs, you need to modify the hardware to expose it through the BARs.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Friday, November 16, 2018 9:05 PM

All replies

  • The PCI bus driver should automatically assign resources to the card for all BARs that respond with a length. Are you certain that the ROM is enabled and exposed on the bus?

     -Brian


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

    Friday, November 16, 2018 7:02 PM
    Moderator
  • The expansion ROM is mapped at boot time so the code within can be executed, but it is disabled once boot completes.  If the vendor didn't provide another way to read the expansion ROM (like using an additional BAR), then there's no good way to get it.

    Even if you are debugging in the lab, it's tricky to hack this.  The PCIe root complex only passes along physical addresses within a certain range.  You would have to go pick an address that is not already in use, shove it into the configuration space, and then map it.  However, you CERTAINLY cannot do this in a production driver.  If there is information your driver needs, you need to modify the hardware to expose it through the BARs.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Friday, November 16, 2018 9:05 PM
  • The unfortunate nature of this situation is not lost on me...

    Basically the MAC address is (stupidly) programmed in an option ROM. I have been able to retrieve this pretty reliably under Linux using the pci_map_rom() function, which allocates some memory in PCI space, and assigns a BAR (albeit with the possibility of failing - in a yet-to-be-encountered scenario) 

    Not too concerned about risk of it failing. This is only going to be used under controlled circumstances.

    In the case of failure, it'll have to fall back to some other mechanism - likely manually configured. If I were to try and emulate what pci_map_rom does on Windows, where would I even begin?


    Friday, November 16, 2018 10:57 PM
  •  If I were to try and emulate what pci_map_rom does on Windows, where would I even begin?

    Mr. Roberts already answered that. See the 2nd paragraph.

    Maybe you can use a fake MAC address (aka locally assigned, by means or the standard registry parameter& NdisReadNetworkAddress) until getting a better solution.

    -- pa


    • Edited by Pavel A Saturday, November 17, 2018 11:00 PM
    Saturday, November 17, 2018 10:50 PM
  • > Mr. Roberts already answered that. See the 2nd paragraph.

    I wouldn't say entirely. The brutal answer would be: There is not an elegant or safe way of doing this, as is done by pci_map_rom() in Linux. I get why - the situation as I've presented it is in violation of the PCI spec (or at least good practices thereof) - i.e. you cannot depend on being able to access expansion ROMs to run the device from within the O/S.

    An option that could be pursued safely is borrowing the address space allocated to another BAR on the same device (assuming there is one large enough) to temporarily map ROM BAR (there isn't in my case).

    Fortunately I haven't needed to resort to anything like that, as the expansion ROM is exposed as a BAR on another function of the same physical device, I can read it in through a second driver, and (hopefully) be able to fetch it with an IRP sent from the NDIS driver.

    A complicated arrangement but certainly feasible...


    Monday, November 19, 2018 9:09 AM
  • > If I were to try and emulate what pci_map_rom does on Windows, where would I even begin?

    You would reboot into Linux, make your change, and reboot back to Windows.  And I'm serious.


    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Tuesday, November 20, 2018 8:32 AM