1. I/O 内存可以或者不可以通过页表来存取.
    当通过页表存取, 内核必须首先安排物理地址, 并且这常常意味着在做任何 I/O 之前你必须调用ioremap .
    如果不需要页表, I/O 内存位置看来很象 I/O 端口, 并且你只可以使用对应函数读写.
  2. I/O 内存分配和映射

    I/O 内存区必须在使用前分配. 分配内存区的接口是( 在 定义):
    struct resource *request_mem_region(unsigned long start, unsigned long len, char *name);
    这个函数分配一个 len 字节的内存区, 从 start 开始. 如果一切顺利, 一个 非NULL 指针返回; 否则返回值是 NULL. 所有的 I/O 内存分配来 /proc/iomem 中列出.

    内存区在不再需要时应当释放:
    void release_mem_region(unsigned long start, unsigned long len);

    IO内存分配完后,如果要直接进行存取还一定要经过一个映射. 这是 ioremap 函数的功能。这个函数设计来特别的安排虚拟地址给 I/O 内存区.

#include <asm/io.h>
void *ioremap(unsigned long phys_addr, unsigned long size);
void *ioremap_nocache(unsigned long phys_addr, unsigned long size);
void iounmap(void * addr);


一旦装备了 ioremap (和iounmap), 一个设备驱动可以存取任何 I/O 内存地址, 不管是否它是直接映射到虚拟地址空间. 但是, 从 ioremap 返回的地址不应当直接引用; 相反, 应当使用内核提供的存取函数.

存取 I/O 内存




从 I/O 内存读, 使用下列之一:

unsigned int ioread8(void *addr);
unsigned int ioread16(void *addr);
unsigned int ioread32(void *addr);

这里, addr 应当是从 ioremap 获得的地址(也许与一个整型偏移); 返回值是从给定 I/O 内存读取的.

有类似的一系列函数来写 I/O 内存:

void iowrite8(u8 value, void *addr);
void iowrite16(u16 value, void *addr);
void iowrite32(u32 value, void *addr);


如果你必须读和写一系列值到一个给定的 I/O 内存地址, 你可以使用这些函数的重复版本:

void ioread8_rep(void *addr, void *buf, unsigned long count);
void ioread16_rep(void *addr, void *buf, unsigned long count);

void ioread32_rep(void *addr, void *buf, unsigned long count);
void iowrite8_rep(void *addr, const void *buf, unsigned long count);
void iowrite16_rep(void *addr, const void *buf, unsigned long count);
void iowrite32_rep(void *addr, const void *buf, unsigned long count);

这些函数读或写 count 值从给定的 buf 到 给定的 addr. 注意 count 表达为在被写入的数据大小; ioread32_rep 读取 count 32-位值从 buf 开始.

上面描述的函数进行所有的 I/O 到给定的 addr. 如果, 相反, 你需要操作一块 I/O 地址, 你可使用下列之一:

void memset_io(void *addr, u8 value, unsigned int count);
void memcpy_fromio(void *dest, void *source, unsigned int count);
void memcpy_toio(void *dest, void *source, unsigned int count);


当前不鼓励使用旧的代码方式  readb/w/l 和 writeb/w/l 等IO内存读写函数。

10-25 11:57
查看更多