0

I am trying to access physical address through the /dev/mem without success. I can access the address space reserved for PCI devices but when I try to map my memory I get error. (I have mapped the virtual to physical through the pagemap interface).

I have added the nopat to the kernel command line and I am running my program as root.

  • virtual address: 0x7f925a266000
  • physical address: 0x1d3a66000

I have also tried aligning it to huge page boundaries without success.

Using the following code, mmap returns -1.

int *addr;
if ((fd = open("/dev/mem", O_RDWR|O_SYNC)) < 0 ) {
    printf("Error opening file. \n");
    close(fd);
    return (-1);
}
addr = (int *)mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0x1d3a66000);
//error message: Operation not permitted, no logs with dmesg
printf("addr: %p \n",addr);
printf("addr: %d \n",*addr); /* CRASH. */

Any ideas on how I can make it work, or if it's not possible through /dev/mem is there other way to map physical addresses? I am running Ubuntu with the latest kernel version.

Edit: I have recompiled the kernel without the strict_devmem as @yano suggested and the problem is fixed.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
gip
  • 25
  • 1
  • 7
  • Did you bother inspecting `errno` after `mmap` returned `(void *)-1`? That will help you narrow down the cause. – R.. GitHub STOP HELPING ICE Jul 11 '17 at 01:42
  • I have updated the post – gip Jul 11 '17 at 01:57
  • 2
    was your kernel compiled with the `CONFIG_STRICT_DEVMEM` flag? http://cateee.net/lkddb/web-lkddb/STRICT_DEVMEM.html – yano Jul 11 '17 at 02:11
  • 1
    I believe you need `MAP_SHARED`, not `MAP_PRIVATE`. You should also check `addr` for the distinguished value `MAP_FAILED`. Finally, you also have to run your program as `root` or with `sudo`. For an example reading dev-board registers through mapped memory, see [MIPS Creator CI20 | ERNG and RNG cgu registers](https://groups.google.com/d/msg/mips-creator-ci20/i92ZtFvyPXY/nuZAacqHAgAJ). Its a small, self-contained program for the ci-20 board. The example is similar, but not the same, as your use case. The PCI bus I/O addresses in your case may behave differently than the registers in my case. – jww Jul 11 '17 at 02:47
  • Also see [How to access mmaped /dev/mem without crashing the Linux kernel?](https://stackoverflow.com/q/11891979/608639), [mmap of /dev/mem fails with invalid argument, but address is page aligned](https://stackoverflow.com/q/39134990/608639) and [How to access kernel space from user space?](https://stackoverflow.com/q/9662193/608639) – jww Jul 11 '17 at 03:24
  • @yano my kernel is compiled with the default configurations so it's probably enabled. Assuming recompiling the kernel is out of the picture, is there any other way to do my job? Maybe with loadable kernel module? I have checked fmem but I couldn't compile it – gip Jul 11 '17 at 14:56
  • you can [check your kernel configurations](https://superuser.com/questions/287371/obtain-kernel-config-from-currently-running-linux-system) to be sure. Beyond that I don't have enough experience to know. I'm currently working on a project basically doing exactly what you are, but the kernel I'm working with was compiled with that flag turned off, so it hasn't been an issue. I believe i read somewhere that with that flag turned on, you only have access to the first 1MB of memory via `/dev/mem`, but don't quote me on that. FWIW I am calling `mmap` with `MAP_SHARED`,, good luck! – yano Jul 11 '17 at 15:32
  • thanks for the info and indeed the space below 1mb (and probably below 4gb) is world readable (the devices' memory) – gip Jul 11 '17 at 17:10
  • I have described a minimal QEMU + Buildroot setup that works at: https://stackoverflow.com/questions/12040303/accessing-physical-address-from-user-space/45127890#45127890 It basically requires combining all the above comments. – Ciro Santilli OurBigBook.com Jul 16 '17 at 12:32
  • interesting thanks. One question here, since it doesn't allow me to post it there, why on the userland memory you state that both proc/maps and proc/pagemap are required? Wouldn't just the pagemap be enough to translate the virtual to physical and pass it to devmem2? – gip Jul 16 '17 at 15:09
  • ok i see, i followed the link and it is required in the case you don't have the virtual address of the wanted region – gip Jul 16 '17 at 15:15

0 Answers0