On Wed, 20 Jun 2001 10:59:43 PDT, Louis Lu <netlu visto com> said:
> Hi:
>
> I just wondering whether or not anyone who has the experiences on memory map io function before?
>
> My code is as following:
> int *base;
> unsigned int fd;
> fd = open("dev/mem", O_RDWR);
> base = mmap(0, 0x80000, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0xd800000);
Note that 0x80000 and 0xd8000000 are *VIRTUAL* addresses. This *WILL*
screw you to the wall.
Also, you're missing a MAP_FIXED - Very Bad Juju will result.
Also, you're confusing two meanings of "memory mapped".
The 'mmap()' system call creates a mapping between *virtual addresses* that
possibly belong to different processes.
Memory Mapped I/O means "instead of using an IN or OUT opcode to write data
to/from an I/O port, the device is set up to look like memory. So storing to
a specific memory location becomes an OUTput, and reading it becomes an INput, and so
on".
This is an Incredibly Bad Thing to do from user-land - in particular, you're
quite likely to get hosed by virtual/physical address mapping (hint - what
happens if the virtual page gets paged out? You didn't lock it anyplace ;),
and a whole host of other things that can go wrong.
The Better Way to implement this would be with a device driver - you would
open /dev/yourdev, and issue read() and write() and ioctl() as needed. Inside
the kernel, the (for example) write() call would go into the device driver,
which would then check the buffer location/size, sanity-check all the other
paramaters to write(), lock the pages in memory so the VM manager doesn't move
them around, set an internal lock so other read()/write() to that device
block until this operation finishes, and then finally move data from the user
buffer to the I/O address(es). Depending on the hardware design, you
may be able to get away with an strcpy() (if the card provides address space
for an entire buffer) or you may need a loop like this:
char *dest = (char *) 0x800ffff; /* or whatever address */
for (i=buflen;i;i--) *dest = *userbuf++; /* *NO* ++ on dest */
Many such cards have restrictions that you have to write only bytes, or only
4/8/16 bytes at a time, or that writes have to be aligned, etc.
Your device driver will also have to deal with error conditions, the
existence of read-only and write-only status/control bits, and so on.
I won't get into issues like cache coherency (what happens when the data
that's in the memory-mapped I/O card doesn't match what your CPU has in
its L1/L2 cache), how to make it work right on a SMP system, and so on.
You may wish to ask the card vendor if they have a device driver for your
system already....
--
Valdis Kletnieks
Operating Systems Analyst
Virginia Tech
Attachment:
pgpPKrumlpzTr.pgp
Description: PGP signature