MAP_ANON,DMA, mmap...

Hello all,

In the mmap documentation one can find the next piece of code to allocate a
DMA buffer:

/* Allocate a physically contiguous buffer */
addr = mmap( 0,
262144,
PROT_READ|PROT_WRITE|PROT_NOCACHE,
MAP_PHYS|MAP_ANON,
NOFD,
0 );

Is the flag MAP_ANON really necessary?? In the same documentation it says:

MAP_ANON : This is most commonly used with MAP_PRIVATE. The fildes parameter
must be NOFD.The allocated memory is zero-filled. This is equivalent to
opening /dev/zero.

I don’t understand this description, am I the only one? Moreover, I don’t
understand why this flag should be used mmaping memory for DMA.
The problem is that if I remove from my code MAP_ANON, it doesn’t work
anymore, it seems that the memory is not reserved.

What I really want to do is to share a DMA buffer with other processes, but,
moreover, MAP_ANON seems to be inconpatible with MAP_SHARE…

Sorry, but I am a little confuse, I was not able to find in the old news a
clear example how to do this. The most similar thread I have found is this
one:

http://groups.google.it/groups?hl=it&lr=&ie=UTF-8&oe=UTF-8&threadm=3A217696.
D8DB7BB5%40student.math.uwaterloo.ca&rnum=1&prev=/groups%3Fq%3Dshm_open%2Bdm
a%26hl%3Dit%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3D3A217696.D8DB7BB5%254
0student.math.uwaterloo.ca%26rnum%3D1

I have done what it is suggested but it seems not to work, moreover, it is
not very clear how to access this piece of memory from another process.

Thanks.

Carlos.

Carlos Beltran <cbeltran@dist.unige.it> wrote:

Hello all,

In the mmap documentation one can find the next piece of code to allocate a
DMA buffer:

/* Allocate a physically contiguous buffer */
addr = mmap( 0,
262144,
PROT_READ|PROT_WRITE|PROT_NOCACHE,
MAP_PHYS|MAP_ANON,
NOFD,
0 );

Is the flag MAP_ANON really necessary?? In the same documentation it says:

MAP_ANON : This is most commonly used with MAP_PRIVATE. The fildes parameter
must be NOFD.The allocated memory is zero-filled. This is equivalent to
opening /dev/zero.

I don’t understand this description, am I the only one? Moreover, I don’t
understand why this flag should be used mmaping memory for DMA.
The problem is that if I remove from my code MAP_ANON, it doesn’t work
anymore, it seems that the memory is not reserved.

MAP_PHYS - … If used with MAP_ANON,
then physically contiguous memory is allocated. …

Basically you need MAP_ANON to ensure that the allocated memory is allocated
in Contigous RAM, which is of course required for DMA.


regards,
Tom

Hi Thomas

Thank for your answer.
But, can I use MAP_ANON and MAP_SHARE together? It doesn’t seem so, why?

Carlos.

“Thomas Emberson” <temberson@softwareremodeling.com> wrote in message
news:ahmdqq$g38$1@inn.qnx.com

Carlos Beltran <> cbeltran@dist.unige.it> > wrote:
Hello all,

In the mmap documentation one can find the next piece of code to
allocate a
DMA buffer:

/* Allocate a physically contiguous buffer */
addr = mmap( 0,
262144,
PROT_READ|PROT_WRITE|PROT_NOCACHE,
MAP_PHYS|MAP_ANON,
NOFD,
0 );

Is the flag MAP_ANON really necessary?? In the same documentation it
says:

MAP_ANON : This is most commonly used with MAP_PRIVATE. The fildes
parameter
must be NOFD.The allocated memory is zero-filled. This is equivalent to
opening /dev/zero.

I don’t understand this description, am I the only one? Moreover, I
don’t
understand why this flag should be used mmaping memory for DMA.
The problem is that if I remove from my code MAP_ANON, it doesn’t work
anymore, it seems that the memory is not reserved.

MAP_PHYS - … If used with MAP_ANON,
then physically contiguous memory is allocated. …

Basically you need MAP_ANON to ensure that the allocated memory is
allocated
in Contigous RAM, which is of course required for DMA.


regards,
Tom

Carlos Beltran <cbeltran@dist.unige.it> wrote:

Hello all,

In the mmap documentation one can find the next piece of code to allocate a
DMA buffer:

/* Allocate a physically contiguous buffer */
addr = mmap( 0,
262144,
PROT_READ|PROT_WRITE|PROT_NOCACHE,
MAP_PHYS|MAP_ANON,
NOFD,
0 );

Is the flag MAP_ANON really necessary??

Yes, it is.

If you used MAP_PHYS without MAP_ANON you would mmap() in whatever lives
at physical address 0 for the number of bytes you asked for.

MAP_ANON really says “allocate please”. MAP_PHYS combined with it
is a combinations that says “allocate physically continguous please”.

In the same documentation it says:

MAP_ANON : This is most commonly used with MAP_PRIVATE. The fildes parameter
must be NOFD.The allocated memory is zero-filled. This is equivalent to
opening /dev/zero.

Here, MAP_ANON says “allocate please”, combined with “MAP_PRIVATE” it
says “allocate zero filled ram for me please” – that is, just give me
some pages of memory. (This is the fundamental allocator used by malloc()
for instance.)

I don’t understand this description, am I the only one? Moreover, I don’t
understand why this flag should be used mmaping memory for DMA.
The problem is that if I remove from my code MAP_ANON, it doesn’t work
anymore, it seems that the memory is not reserved.

Yup.

What I really want to do is to share a DMA buffer with other processes, but,
moreover, MAP_ANON seems to be inconpatible with MAP_SHARE…

Yes it is. If you want a DMA buffer to be shared between proceses:

– allocate it with MAP_ANON|MAP_PHYS
– get the physical address with mem_offset()
– pass that address to the other process
– map that memory in with MAP_PHYS|MAP_SHARED and offset == to value
from mem_offset
– this will give the second process a virtual pointer to the same
physical DMA safe memory that the first process allocated

Hope this helps,

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Hi David,

What I really want to do is to share a DMA buffer with other processes,
but,
moreover, MAP_ANON seems to be inconpatible with MAP_SHARE…

Yes it is. If you want a DMA buffer to be shared between proceses:

– allocate it with MAP_ANON|MAP_PHYS
– get the physical address with mem_offset()
– pass that address to the other process
– map that memory in with MAP_PHYS|MAP_SHARED and offset == to value
from mem_offset
– this will give the second process a virtual pointer to the same
physical DMA safe memory that the first process allocated

Hope this helps,

-David

Thanks for your answer. It is clear how to do it now. Just one more question
:slight_smile:.
Can I use shm_open(…) to obtain a pointer to the share memory??
I am doing something like this but it doesn’t seem to work:

fd = shm_open("/shimage", O_RDWR, 0777);

if (fd == -1)
{
perror(“shm_open”);
exit(EXIT_FAILURE);
}

i->buffer = (unsigned char ) mmap(0,
1024
h*2,
PROT_READ,
MAP_PHYS|MAP_SHARED,
fd,
0);

“shimage” was created in the first process with mmap → then mem_offset →
and then shm_ctl(…)

Thanks!

Carlos

Carlos Beltran <cbeltran@dist.unige.it> wrote:

Hi David,

Yes it is. If you want a DMA buffer to be shared between proceses:

– allocate it with MAP_ANON|MAP_PHYS
– get the physical address with mem_offset()
– pass that address to the other process
– map that memory in with MAP_PHYS|MAP_SHARED and offset == to value
from mem_offset
– this will give the second process a virtual pointer to the same
physical DMA safe memory that the first process allocated

Hope this helps,

-David

Thanks for your answer. It is clear how to do it now. Just one more question
:slight_smile:> .
Can I use shm_open(…) to obtain a pointer to the share memory??
I am doing something like this but it doesn’t seem to work:

“shimage” was created in the first process with mmap → then mem_offset –
and then shm_ctl(…)

I expect you did:
fd = shm_open("/shimage", O_RDWR|O_CREAT, 0777 );
ptr = mmap(… MAP_ANON|MAP_PHYS, …);
mem_offset(ptr, … phys_addr );
shmctl( fd, SHMCTL_PHYS, phys_addr, …);


fd = shm_open("/shimage", O_RDWR, 0777);

note: the 0777 are permission bits – only meaningful if you passed
in O_CREAT as a flag.

if (fd == -1)
{
perror(“shm_open”);
exit(EXIT_FAILURE);
}

i->buffer = (unsigned char ) mmap(0,
1024
h*2,
PROT_READ,
MAP_PHYS|MAP_SHARED,
fd,
0);

Don’t use MAP_PHYS here – you’re no longer mapping a physical object
(from your point of view) – you’re mapping the memory associated with
the shared memory object “/shimage”. So, you only need MAP_SHARED.
Essentially MAP_PHYS is only meaningful/useful if you are passing in
NO_FD as your file descriptor.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.