Part of the WritingPortableDrivers section

I/O Memory Access

Unlike on most typical embedded systems, accessing I/O memory on Linux cannot be done directly. This is due to the wide range of different memory types and maps present on the wide range of processors on which Linux runs. To access I/O memory in a portable manner, you must call ioremap() to gain access to a memory region and iounmap() to release access.

ioremap() is defined as:

void __iomem *ioremap(unsigned long offset, unsigned long size);

You pass in a starting offset of the region you wish to access and the size of the region in bytes. You cannot just use the return value as a memory location to read and write from directly, but rather it is a token that must be passed to different functions to read and write data.

The functions to read and write data using memory mapped by ioremap() are:

   1 unsigned char  readb(const volatile void __iomem *addr);  /* read 8 bits */
   2 unsigned short readw(const volatile void __iomem *addr);  /* read 16 bits */
   3 unsigned int   readl(const volatile void __iomem *addr);  /* read 32 bits */
   5 void writeb (unsigned char  value, volatile void __iomem *addr);  /* write 8 bits */
   6 void writew (unsigned short value, volatile void __iomem *addr);  /* write 16 bits */
   7 void writel (unsigned int   value, volatile void __iomem *addr);  /* write 32 bits */

After you are finished accessing memory, you must call iounmap() to free up the memory so that others can use it if they want to.

The code example below from the Compaq PCI Hot Plug driver in drivers/hotplug/cpqphp_core.c shows how to access a PCI device's resource memory properly.

FIXME, put a good example here, the hotplug one isn't good...

KernelNewbies: IoMemoryAccess (last edited 2017-12-30 01:30:09 by localhost)