PCI BAR mmap

Artem Belevich art at freebsd.org
Tue Jul 31 19:32:19 UTC 2012

On Tue, Jul 31, 2012 at 10:41 AM, Konstantin Belousov
<kostikbel at gmail.com> wrote:
>> It's a bit of a hack, but if you are root, you can access physical
>> memory via /dev/mem.
>> memfd = open(/dev/mem)
>> ptr = mmap(NULL, bar_size, PROT_READ, 0, memfd, bar_address);
>> You can even use dd:
>> dd if=/dev/mem bs=4k skip=<BAR_ADDRESS/4k> count=<BAR_SIZE/4k> of=bar.dump
> This probably only works on x86, only for memory BARs, and only if BAR
> is already activated. But yes, I did grabbed scanouts (i.e. screen) on
> Intel GPUs this way.

Indeed, the hack above makes number of assumptions.
* BARs indeed should be enabled.
* one should know where on particular architecture BARs are mapped.
BAR address is not necessarily the address kernel will see it at.
* MD part of mem driver should cover that address range.

The last one is a problem even on i386/amd64. It appears that, at
least on i386/amd64, implicit assumption is that /dev/mem is for
accessing RAM (or that peripherals are mapped in the hole below 4GB).
/dev/mem does not work for devices that are mapped way above RAM in
physical address space. On one of industrial boards I worked with
64-bit BARs were mapped at addresses 0xffff_xxxx_xxxx and those
devices could not be accesses via /dev/mem because DMM didn't cover
that range. I think DMM size got bumped up since then, but I don't
think it covers complete physical address range. If device is not in
that range, one can't use /dev/mem to access it.


More information about the freebsd-net mailing list