Re: mmap problem

On Sep 21, 1:47 am, Cat22 <erben...@xxxxxxxxxxx> wrote:
On Mon 9/20/2010 9:48 PM, loozadroog wrote:

On Sep 20, 9:44 pm, Cat 22<ca...@xxxxxxxxxxx>  wrote:
Tauno Voipio wrote:
Cat 22 wrote:
system: mandriva x86_64 (2010.0), kernel (really its
my config'd&  compiled version of it), 6gig ram

I cant seem to mmap regular ram unless its below 1meg or
above 3.2G (e.g mmio space)
(I am running everything as root in a console)
the error from mmap is always EINVAL

I wrote a short test program here (mmap_test.c):

int main(int argc, char **argv)
int fd;
uint32_t *vptr;
uint32_t base_addr;
size_t pg_sz;

      fd = open("/dev/mem", O_RDWR);

      base_addr = strtoul(argv[1], 0, 16);
      pg_sz = getpagesize();
      vptr = mmap(0, pg_sz, PROT_READ|PROT_WRITE, MAP_SHARED, fd,
      base_addr); if(vptr == MAP_FAILED) {
         return 1;
      munmap(vptr, getpagesize());

return 0;

and i ran it via this script


for((i=0; i<4294967296; i+=4096))
   addr=$(printf "0x%x" $i)
  ./mmap_test $addr
   if [ "$prev_flag" -ne "$flag" ];
           if [ "$flag" -ne 0 ]; then
                 echo "bad -  $addr  $i";
                 echo "good - $addr  $i";
#    echo "$addr $i"
echo "last address checked: $addr"
here is the results:
mmap    hex addr    decimal addr
good -    0x0               0
bad -  0x101000        1052672
good - 0xbf790000   3212378112
last address checked: 0xfffff000

So what i see is that i can mmap below 1 meg ok and above 3.2G or
so ok but nothing in between (most of dram space).
Am i doing this wrong? some missing attribute to open or mmap?
One other thing:
as an example, if i try to mmap a page at 512meg i see this in
strace ./mmap_test  20000000
   [snip bunch of strace output]
open("/dev/mem", O_RDWR)                = 3
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, 3, 0x20000000)
= -1 EINVAL (Invalid argument)


mmap() is intended for files in the file system, not for
device files. It would be a silly action from the kernel
to allow mapping to paged areas of the memory.

Would you care to explain what you're attempting to achieve?

Sure, this got started with a request to be able to modify some registers
in mmcfg space via a simple program to test some things. In the process i
had accidentally discovered that mmap dram really wasnt working but mmcfg
space was ok.
I just thought you could mmap a pointer to any physical address but i guess
thats not the case?

You're using two different interfaces into memory. You should
perhaps open the mem device and use file operations *or*

mmap (0x20000000, 4096, PROT_READ|PROT_WRITE,

make that: ..., -1, 0);

and use memory operations.

I don't see why you're stitching both of these together.


The man page says that MAP_ANONYMOUS initializes the contents to 0's so
i hadnt considered that it would be useful in my application.  I took
that to mean it would simply zero out any mapped memory.
Anyway, thanks for the info. I may play wiht that just to see what i can
see in memory - curiosity mostly. mmapping mmcfg space works ok
and gives me fast access to registers as opposed to opening /dev/mem and
using file operations to repeatedly access a particular register
Thanks again,

Yeah, I saw that part. I thought that combining it with MAP_SHARED
would prevent the zero-ing, but on re-reading it doesn't appear to
say that anywhere.
It seems like it would have to preserve contents with MAP_SHARED,
but I don't know for sure, and I can advise no further.

But did you see this one?

Put the mapping into the first 2GB of the process
address space. Ignored when
MAP_FIXED is set. This flag is currently only
supported on x86-64, for 64-bit

That seems to match your platform and roughly matches the
memory boundary you describe.