Search code examples
windowskerneldevice-driver

How do WINDOWS func kernel drivers communicate with actual hardware?


So I understand that a kernel driver sits on top of HW device and then to communicate with the device via user space you will need to talk to the kernel driver via CreateFile && Read && Write. I have seen the design of Window's kernel drivers and their sample codes whether it is a USB or PCI or...

Now what I want to understand is how does the kernel drive communicate with the hardware? Where is the driver code would we usually find the code responsible for reading/writing registers on a certain device? What does the driver need to communicate with the device? I was told it is the BAR0 value that maps the HW to the virtual memory area which means any address we want to access on a physical device would start at that address. Is that correct? what If I have BAR0 = 0xfc500000, do i have to find addresses of certain register on the device and then ad it as an offset?


Solution

  • Driver need to get HW Resources from the OS. in a PCI device example, you will get MMIO Address and the interrupt vector. the MMIO Address is a physical address the PCI Controller and the BIOS map the device too.

    the driver gets this value in EvtPepareHardware callback (in KMDF) and then need to map it to kernel Virtual address using MmMapIoSpace(). once you get a kernel Virtual address theoretically it is a "pointer" to the HW memory space and you can access the registers as you wish.

    but it is recommended to use the HAL macros to void caching and other issues to access that memory. e.g. READ_REGISTER_ULONG64

    to find the address of a registers you the Hardware device spec

    for more info read this "Reading and Writing to Device Registers"