Test it out with busybox devmem

busybox devmem is a tiny CLI utility that mmaps /dev/mem .

You can get it in Ubuntu with: sudo apt-get install busybox

Usage: read 4 bytes from the physical address 0x12345678 :

sudo busybox devmem 0x12345678

Write 0x9abcdef0 to that address:

sudo busybox devmem 0x12345678 w 0x9abcdef0

Source: https://github.com/mirror/busybox/blob/1_27_2/miscutils/devmem.c#L85

MAP_SHARED

When mmapping /dev/mem , you likely want to use:

open("/dev/mem", O_RDWR | O_SYNC); mmap(..., PROT_READ | PROT_WRITE, MAP_SHARED, ...)

MAP_SHARED makes writes go to physical memory immediately, which makes it easier to observe, and makes more sense for hardware register writes.

CONFIG_STRICT_DEVMEM and nopat

To use /dev/mem to view and modify regular RAM on kernel v4.9, you must fist:

disable CONFIG_STRICT_DEVMEM (set by default on Ubuntu 17.04)

(set by default on Ubuntu 17.04) pass the nopat kernel command line option for x86

IO ports still work without those.

See also: https://stackoverflow.com/questions/39134990/mmap-of-dev-mem-fails-with-invalid-argument-for-virt-to-phys-address-but-addre/45127582#45127582

Cache flushing

If you try to write to RAM instead of a register, the memory may be cached by the CPU: https://stackoverflow.com/questions/22701352/how-to-flush-the-cpu-cache-for-a-region-of-address-space-in-linux and I don't see a very portable / easy way to flush it or mark the region as uncacheable:

So maybe /dev/mem can't be used reliably to pass memory buffers to devices?

This can't be observed in QEMU unfortunately, since QEMU does not simulates caches.

How to test it out

Now for the fun part. Here are a few cool setups: