read PCI memory and config spyce through /dev/mem
Warlich, Christof
christof.warlich at siemens.com
Tue May 7 02:35:43 EDT 2013
> > $ dd if=/dev/mem bs=1 count=1024 skip=4150263808
> > dd: reading `/dev/mem': Bad address
> > 0+0 records in
> > 0+0 records out
> > 0 bytes (0 B) copied, 6.6658e-05 s, 0.0 kB/s
> >
> > The kernel config help says that _PCI_ memory access is even
> > possible with STRICT_DEVMEM enabled. Can anyone give me a hint
> > what I may do wrong?
>
> You *do* realize that doing a byte access on a 64-bit PCI register
> will probably fail, right? And changing it to bs=8 won't fix it either,
> because some registers are 32-bit, and some are write-only.
The real target that I need to explore is a custom FPGA device on an
embedded (i386) system. One of its BARs (at 0x81423000) point to memory
that _does_ allow unrestricted byte access and has a size of two pages.
But anyhow, all of the following commands show the same error:
$ dd if=/dev/mem bs=1 count=1 skip=2168598528 | hexdump
$ dd if=/dev/mem bs=2 count=1 skip=1084299264 | hexdump
$ dd if=/dev/mem bs=4 count=1 skip=542149632 | hexdump
$ dd if=/dev/mem bs=8 count=1 skip=271074816 | hexdump
$ dd if=/dev/mem bs=4096 count=1 skip=529443 | hexdump # 4096 being the system's page size
Furthermore, read / write access through a simple program using /dev/mem
_does_ work as expected:
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/mman.h>
int main( int argc, char *argv[]) {
char *mem;
int fd;
fd = open ("/dev/mem", O_RDWR);
assert(fd >= 0);
mem = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t) 0x81423000);
assert(mem != MAP_FAILED);
printf("Memory pointer: %p\n", mem);
printf("The PCI memory is : %#x\n", *mem);
*mem = *argv[1];
printf("The PCI memory is : %#x\n", *mem);
munmap(mem, getpagesize());
close(fd);
return 0;
}
Calling it, yields:
$ led 4
Memory pointer: 0xb7678000
The PCI memory is : 0x33
The PCI memory is : 0x34
And the LED matrix display being behind that address switches from 3 to
4 as expected.
Thus, I still cannot see why the access through /dev/mem using dd doesn't
work.
> Bottom line - what you're doing wrong is not accessing the PCI address
> space in the exact manner that the PCI spec requires. You're lucky it
> just threw "bad address" - it *is* possible to end up wiping your entire
> system this way if you screw up the PCI config for your disk controller or
> similar. Be glad you didn't have to recover from your backups this time.
>
> You *do* have backups, right?
Don't worry about that, I've restored the system in less than a minute.
More information about the Kernelnewbies
mailing list