25

I have Linux and I have a physical address: (i.e. 0x60000000).
I want to read this address from user-space Linux program.

This address might be in kernel space.

Tony Tannous
  • 14,154
  • 10
  • 50
  • 86
Mikhail Kalashnikov
  • 1,146
  • 1
  • 11
  • 31
  • 3
    You can use `mmap(2)` as described at the following: http://stackoverflow.com/questions/12040303/accessing-physical-address-from-user-space – MTZ4 Mar 12 '14 at 07:20
  • Possible duplicate of [Is there any API for determining the physical address from virtual address in Linux](https://stackoverflow.com/questions/5748492/is-there-any-api-for-determining-the-physical-address-from-virtual-address-in-li) – Ciro Santilli OurBigBook.com Aug 04 '17 at 05:33
  • Do you have `/dev/mem` on your system? Do you have `devmem` program (check with `type devmem`)? If so, does `devmem 0x60000000` work? If it does it's not a big problem to write a function that `mmaps` some part of `/dev/mem`, I have a ready code for that. – Arkadiusz Drabczyk Aug 14 '17 at 19:53
  • There is also `devmem2` on some systems: http://manpages.ubuntu.com/manpages/xenial/man1/devmem2.1.html – Arkadiusz Drabczyk Aug 14 '17 at 19:59

4 Answers4

6

You need a kernel driver to export the phyisical address to user-level.

Have a look at this driver: https://github.com/claudioscordino/mmap_alloc/blob/master/mmap_alloc.c

Claudio
  • 10,614
  • 4
  • 31
  • 71
5

Note that this is now possible via /proc/[pid]/pagemap

3
Is there an easy way I can do that?

For accessing from user space, mmap() is a nice solution.

Is it possible to convert it by using some function like "phys_to_virt()"?

Physical address can be mapped to virtual address using ioremap_nocache(). But from user space, you can't access it directly. suppose your driver or kernel modules want to access that pysical address, this is the best way. usually memory mapped device drivers uses this function to map registers to virtual memory.

Jeyaram
  • 9,158
  • 7
  • 41
  • 63
  • A bounty is now available... A different question asked how to access the physical address of a register of some device. Which will obviously reside in kernel memory. Would it be possible to turn it to virtual address, then give it to `copy_to_user()` function with 4 bytes to get the value of that register ? – Tony Tannous Aug 10 '17 at 17:40
  • 1
    It seems like a job for `devmem`. See my comment under the question. – Arkadiusz Drabczyk Aug 14 '17 at 19:57
0

Something like this in C. if you poll a hardware register, make sure you add volatile declarations so the compiler doesn't optimize out your variable.

#include <stdlib.h>

#include <stdio.h>
#include <errno.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <memory.h>

volatile int *hw_mmap = NULL; /*evil global variable method*/

int map_it() {
/* open /dev/mem and error checking */
int i;
int file_handle = open(memDevice, O_RDWR | O_SYNC);

if (file_handle < 0) {
    DBG_PRINT("Failed to open /dev/mem: %s !\n",strerror(errno));
    return errno;
}

/* mmap() the opened /dev/mem */
hw_mmap = (int *) (mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, file_handle, 0x60000000));
if(hw_mmap ==(void*) -1) {

    fprintf(stderr,"map_it: Cannot map memory into user space.\n");
    return errno;
}
return 0;
}

Now you can read write into hw_mmap.

jaytho
  • 100
  • 8