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