io_mmap() in a Resource Manager

Does anyone have an example of how to implement io_mmap() within a Resource
Manager? The online documentation and Rob Krten’s book are both somewhat
reticent on the subject.

We are trying to port an existing Unix device driver that requires support
for mmap().

TIA

Rob Rutherford
Ruzz Technology

Robert Rutherford <ruzz@ruzz.com> wrote:

Does anyone have an example of how to implement io_mmap() within a Resource
Manager? The online documentation and Rob Krten’s book are both somewhat
reticent on the subject.

What exactly does io_mmap() do? Is this a client asking to mmap() in
a file/directory? Or is this the driver try to access hardware using
mmap()?

The second is fairly easy – the first is messier.

We are trying to port an existing Unix device driver that requires support
for mmap().

Hm… the driver should supply support for mmap() and client require it
if we’re looking at the messy case.

Can you give a bit more detail on what you’re trying to do here?

Thanks,
-David

QNX Training Services
dagibbs@qnx.com

What exactly does io_mmap() do? Is this a client asking to mmap() in
a file/directory? Or is this the driver try to access hardware using
mmap()?

In this case the resource manager is acting as a device driver for a
hardware (PCI) card. The driver maps in the PCI memory into its own address
space (no problem there).

The client then calls mmap() with the fd of the resource manager, trying to
map a subset of the card’s address space (offset, len) into it’s own address
space.

Of course, if necessary we could fudge this by turning the client-side
mmap() into a devctl(), with the driver returning the physical address of
the memory. The client side could then do it’s own mmap_device_memory() with
the physical address supplied by the driver. But we are trying to keep the
client-side library compatible with Linux/SunOS etc, and they all perform
the mmap() as above. Also we are trying to prevent the client from having to
be run as root.

Hope this gives you enough info, let me know if you need more.

Rob Rutherford

Robert Rutherford <ruzz@ruzz.com> wrote:

What exactly does io_mmap() do? Is this a client asking to mmap() in
a file/directory? Or is this the driver try to access hardware using
mmap()?

In this case the resource manager is acting as a device driver for a
hardware (PCI) card. The driver maps in the PCI memory into its own address
space (no problem there).

The client then calls mmap() with the fd of the resource manager, trying to
map a subset of the card’s address space (offset, len) into it’s own address
space.

Ok.

Of course, if necessary we could fudge this by turning the client-side
mmap() into a devctl(), with the driver returning the physical address of
the memory. The client side could then do it’s own mmap_device_memory() with
the physical address supplied by the driver. But we are trying to keep the
client-side library compatible with Linux/SunOS etc, and they all perform
the mmap() as above. Also we are trying to prevent the client from having to
be run as root.

I would suggest going with the fudge, at least for now. (Wrap it in
another routine, locally, so that when/if we document how to do what
you want to do, you can replace it with the proper way.)

-David

QNX Training Services
dagibbs@qnx.com

In article <9hakb9$an6$2@nntp.qnx.com>, David Gibbs <dagibbs@qnx.com>
wrote:

Robert Rutherford <> ruzz@ruzz.com> > wrote:
Of course, if necessary we could fudge this by turning the client-side
mmap() into a devctl(), with the driver returning the physical address of
the memory. The client side could then do it’s own mmap_device_memory() with
the physical address supplied by the driver. But we are trying to keep the
client-side library compatible with Linux/SunOS etc, and they all perform
the mmap() as above. Also we are trying to prevent the client from having to
be run as root.

I would suggest going with the fudge, at least for now. (Wrap it in
another routine, locally, so that when/if we document how to do what
you want to do, you can replace it with the proper way.)

I use a dirty trick in one of my PCI drivers which sidesteps the issues
Robert raises. My resource manager maps its PCI areas using
shm_open/shm_ctl. When the resource manager starts up, it creates a
shared memory area, and uses shm_ctl with the SHMCTL_PHYS flag to mark
that area as anchored to a physical address. The client application then
only needs to devctl to get the name of the area to shm_open. After
shm_open’ing the are, the client application can mmap the file as normal.

This is less attractive than just mmap’ing the resource manager, but
I’ve never figured out how to implement the mmap resource manager hook.
And this trick means that the client application doesn’t have to be root
to map the card into its address space!!

Hope this helps,
Eric

“David Gibbs” <dagibbs@qnx.com> wrote in message
news:9hakb9$an6$2@nntp.qnx.com

Robert Rutherford <> ruzz@ruzz.com> > wrote:

What exactly does io_mmap() do? Is this a client asking to mmap() in
a file/directory? Or is this the driver try to access hardware using
mmap()?

In this case the resource manager is acting as a device driver for a
hardware (PCI) card. The driver maps in the PCI memory into its own
address
space (no problem there).

The client then calls mmap() with the fd of the resource manager, trying
to
map a subset of the card’s address space (offset, len) into it’s own
address
space.

Ok.

Of course, if necessary we could fudge this by turning the client-side
mmap() into a devctl(), with the driver returning the physical address
of
the memory. The client side could then do it’s own mmap_device_memory()
with
the physical address supplied by the driver. But we are trying to keep
the
client-side library compatible with Linux/SunOS etc, and they all
perform
the mmap() as above. Also we are trying to prevent the client from
having to
be run as root.

I would suggest going with the fudge, at least for now. (Wrap it in
another routine, locally, so that when/if we document how to do what
you want to do, you can replace it with the proper way.)

Do you mean that’s it’s possible but not just document?

-David

QNX Training Services
dagibbs@qnx.com

“Eric Berdahl” <berdahl@intelligentparadigm.com> wrote in message
news:berdahl-E8FBF1.15304426062001@nntp.qnx.com…>

I use a dirty trick in one of my PCI drivers which sidesteps the issues
Robert raises. My resource manager maps its PCI areas using
shm_open/shm_ctl. When the resource manager starts up, it creates a
shared memory area, and uses shm_ctl with the SHMCTL_PHYS flag to mark
that area as anchored to a physical address. The client application then
only needs to devctl to get the name of the area to shm_open. After
shm_open’ing the are, the client application can mmap the file as normal.

This is less attractive than just mmap’ing the resource manager, but
I’ve never figured out how to implement the mmap resource manager hook.
And this trick means that the client application doesn’t have to be root
to map the card into its address space!!

Eric, Thanks for the suggestion. This should actually work quite nicely as
it turns out I can avoid the devctl() completely since I can just use the
device name as the name of the shared memory region.

I would still like to know the answer to Mario’s question - is the
capability to do this “properly” in there at all? Maybe something for a
future release?

Robert

“Mario Charest” <mcharest@deletezinformatic.com> wrote in message
news:9hbekn$12c$1@inn.qnx.com

I would suggest going with the fudge, at least for now. (Wrap it in
another routine, locally, so that when/if we document how to do what
you want to do, you can replace it with the proper way.)

Do you mean that’s it’s possible but not just document?

It sure should be possible since you can do mmap() on regular files (which
means QNX block I/O managers handle it). This feature was added to 2.11 at
last moment (in 2.0 you could only mmap() files from /dev/shmem or
/proc/boot). It was implemented primarily to support ELF shared libs (which
were only shared if they were in /dev/shmem or /proc/boot in 2.0). In fact
mmap() in 2.11 betas would return ENOSYS unless you passed MAP_ELF with
flags. It probably was done in rather messy way indeed, no wonder it is not
documented.

  • Igor