It seems like
root@testbox:~# dd if=/dev/mem bs=1 count=4 skip=2149646336 | hd
should be nearly equivalent to
root@testbox:~# devmem 2149646336 32

But, while devmem works great, that dd invocation gives me a segfault. For many other bs,skip combinations (found by accident during my attempt to figure this out) dd successfully returns, but the data is nothing like what I'm expecting. All of this suggests I'm not actually addressing where I think I'm addressing, when I use dd. Some memory-mapping issue perhaps? I'm a hardware guy, so I only think in physical addresses.

Some gory details:

I'm building an embedded system with linux running on a Xilinx FPGA with on-chip ARM A53 cores. I routinely use devmem to read or write memory-mapped registers in my FPGA logic. I'd like to use dd instead of devmem to read a long block of addresses with one command, and save the data to a file or pipe it to another process.

My FPGA design has an internal RAM block, read-writable, mapped to byte-address 0x80210000.

I wrote a shell script like so:

devmem 0x80210000 32 0x5AB000CD  
devmem 0x80210004 32 0x5AB001CD  
devmem 0x80210008 32 0x5AB002CD  
devmem 0x8021000C 32 0x5AB003CD  
... etc etc <250 more lines> ...  
devmem 0x802103F8 32 0x5AB0FECD  
devmem 0x802103FC 32 0x5AB0FFCD  

It just fills the first kbyte of my block-RAM with some recognizable gibberish. After executing that shell script, I can use devmem to read words from that memory.

root@testbox:~# devmem 2149646336 32
root@testbox:~# devmem 2149646340 32
root@testbox:~# devmem 2149646344 32
root@testbox:~# devmem 2149646348 32

So far so good.

Note that:
0x80210000 = 2149646336 decimal
0x80210000 / 16 = 134352896 decimal

Next I try to read the same 4 words of memory using dd:

root@testbox:~# dd if=/dev/mem of=/tmp/junk1 bs=1 count=16 skip=2149646336
root@testbox:~# dd if=/dev/mem of=/tmp/junk1 bs=16 count=1 skip=134352896
or suchlike.

Either of these lines gives me a segfault. I've tried many other combinations of bs, skip, etc, trying to find my block of memory.

Other invocations of dd "succeed". e.g. :

root@testbox:~# dd if=/dev/mem bs=16 count=1 skip=2149646336 | hd
1+0 records in
1+0 records out
16 bytes copied, 0.00032236 s, 49.6 kB/s
00000000  ff ff fd ba 85 ff 4c ce  ff ff bd df e4 d5 9d ed  |......L.........|

but I don't recognize this data. I guess I'm just reading from who-knows-where in my DRAM.

Is the addressing for dd if=/dev/mem different than for devmem ?

2 Answers 2


Partial answer:

If your devmem is from busybox, it uses /dev/mem to read and write values, so you should get the same results.

That said, note that the unit of skip is blocks (bs bytes), so bs=16 count=1 skip=2149646336 wouldn't read at 0x80210000, but at 0x802100000, which probably wraps to 0x02100000.

As the MSB of your skips is one, if there's a signed/unsigned confusion somewhere in the source and/or compiler, that could also screw up things.

So first thing I'd do is to test reading at 0x80210000 using something along the lines of bs=16 skip=134352896. If that still fails, second thing I'd do is to write a small C program that directly reads /dev/mem and verifies if that works.


This is indeed a sign error (for busybox version):

if (skip) {
    if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) {
        do {
            ssize_t n = safe_read(ifd, ibuf, ibs);
            if (n < 0)
                goto die_infile;
            if (n == 0)
        } while (--skip != 0);

lseek() returns the file offset (2149646336) which is converted to int32 making it negative (-2145320960), so dd believes this is an error code. It then reads all the bytes from the file until given offset as an attempt to implement a basic seek. This means reading all bytes on the bus from 0 to your address, which can only lead to troubles.

You can try to fix dd by checking if the return value is a valid error code (anything between -1 and -4095), but writing your own C program is probably quicker than compiling busybox again.

BTW, devmem uses mmap() to read /dev/mem which is slightly different.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .