0

I am building a program on a RPi3 using Buildroot as linux distro and I need to write to a given physical address. I've read that the best approach is to first use mmap, then obtain a virtual address at which you normally write. In my case, the test program must write a single character at the given address.

The strange thing is that, when I read the value from the virtual address after the mapping, the first time works, but the second time, the same address points to nothing. This is a snippet from my program:

    ...

    int mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
    if (0 > mem_fd) {
        fprintf(stderr, "Could not open memory!\n");
        return -1;
    }

    map_base = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, ATTEST_START & ~map_mask);
    map_target = map_base + (ATTEST_START & map_mask);

    *((unsigned char *) map_target) = (char) ((rand() % 25) + 65);
    printf("After assignment %p, val is %c\n", map_target, *((unsigned char *) map_target)); // here I can read the value
    printf("After assignment %p, val is %c\n", map_target, *((unsigned char *) map_target)); // here it is empty!!!

    ...

ATTEST_START is the registered physical address (using register_phys_mem, in OP-TEE trusted OS). I would very much appreciate if you could tell me why the second read doesn't work and what can I do differently to make it work. Thanks!

  • If this is a device register at that address, then (1) you need to access it as a volatile object, e.g. `*(volatile unsigned char *) map_target` and (2) there is no guarantee that you can read it twice in a row and get the same value. – n. m. could be an AI Jul 18 '21 at 14:47
  • Thank you, but what does `volatile` do? How does it differ from a normal call? – Cosmin Aprodu Jul 18 '21 at 15:05
  • Also, I there a way to lock the memory? Something like `mlock` perhaps? I need to red that memory for some seconds in a row, that's why. – Cosmin Aprodu Jul 18 '21 at 15:06
  • What do you mean "points to nothing" or "is empty"? That's impossible. More likely the value is a character that isn't printable. Try using `%x` instead of `%c` to see its hex value. – Nate Eldredge Jul 18 '21 at 15:24
  • https://en.cppreference.com/w/c/language/volatile : basically, `volatile` ensures that the program actually loads from the relevant address every time your source code dereferences the pointer. Without that, the compiler could load the value once, keep it in a register, and print out the same value both times. – Nate Eldredge Jul 18 '21 at 15:25
  • I don't understand what you mean by "lock". If the value in the hardware register is changing, and you want to see the changes, then keep dereferencing the pointer (after changing to `volatile`). If you want to keep using the old value even if the value in the register changes, copy it into a local variable and use that. Note that `mlock` does something unrelated which isn't relevant here. – Nate Eldredge Jul 18 '21 at 15:27
  • @NateEldredge the following is an output after I replaced `%c` with `%x`: `After assignment 0x7fbf6d3000, val is 53 After assignment 0x7fbf6d3000, val is 0` How can I keep derreferencing the pointer using `volatile`? (I have never worked this low level before) – Cosmin Aprodu Jul 18 '21 at 15:30
  • Okay, so the value changed from `0x53` to `0x0`. If it's a hardware device that might be normal. What is the device, and what does its documentation say is supposed to happen when you read and write that address? – Nate Eldredge Jul 18 '21 at 15:32
  • Or, if it's ordinary memory that some other part of the machine is accessing, that would be normal as well. What's the backstory here? Why are you reading and writing to this random memory address? What are you expecting to happen, and on what basis do you expect that? – Nate Eldredge Jul 18 '21 at 15:33
  • @NateEldredge I have an application running in the TrustZone normal world. The only way of accessing the data written by it from the trusted world, is by setting a fixed physical address for it to write at. This is why I want to do this. – Cosmin Aprodu Jul 18 '21 at 15:36
  • Proposal: Instead of mapping `/dev/mem` map a plain file to try the code. My guess is RAM just changes. – U. Windl Jul 21 '21 at 15:27

0 Answers0