CPU通过物理地址访问DDR和外设,DDR内存称为物理内存地址空间,外设寄存器组称为I/O内存地址空间。
ARM采用统一编址,而X86采用独立编制。上一章介绍了DDR内存分配,这一章介绍I/O内存分配。
1、I/O内存分配和映射
#include <linux/ioport.h> 分配I/O内存区,失败返回NULL,所有的I/O内存分配可以通过/proc/iomem节点查询 struct resource *request_mem_region(unsigned long start, unsigned long len, char *name); 释放I/O内存区 void release_mem_region(unsigned long start, unsigned long len); #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);
2、存取I/O内存
首先使用request_mem_region分配I/O内存,然后调用ioremap重定位I/O内存到内核虚拟地址空间,接下来使用下述接口进行I/O内存存取。
I/O内存读操作: unsigned int ioread8(void *addr); unsigned int ioread16(void *addr); unsigned int ioread32(void *addr); I/O内存写操作: void iowrite8(u8 value, void *addr); void iowrite16(u16 value, void *addr); void iowrite32(u32 value, void *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); 有一组旧的接口: unsigned readb(address); unsigned readw(address); unsigned readl(address); void writeb(unsigned value, address); void writew(unsigned value, address); void writel(unsigned value, address);