设备通常会提供一组寄存器来控制设备、读写设备和获取设备状态,即控制寄存器、数据寄存器和状态寄存器。这些寄存器可能位于I/O空间,也可能位于内存空间。当位于I/O空间时,通常被称为I/O端口,位于内存空间时,对应的内存空间被称为I/O内存。
再内核访问I/O内存前,需要将设备所处的物理地址映射到虚拟地址
__iomem源码位置:include/linux/compiler.h
# define __force __attribute__((force)) //变量可以进行强制转换
# define __nocast __attribute__((nocast))
/*指针地址必须在设备地址空间,__iomem是个IO map的问题,根据系统的具体情况,
把寄存器映射到虚拟地址的特定位置,这样,访问寄存器就可以像访问普通内存一样简单方便
主要是用于编译器的检查,检查地址空间的有效性*/
# define __iomem __attribute__((noderef, address_space(2))) //
# define __acquires(x) __attribute__((context(x,0,1)))
# define __releases(x) __attribute__((context(x,1,0)))
static inline u8 __raw_readb(const volatile void __iomem *addr)
{
return *(__force volatile u8 *)addr;
}
static inline u16 __raw_readw(const volatile void __iomem *addr)
{
return *(__force volatile u16 *)addr;
}
static inline u32 __raw_readl(const volatile void __iomem *addr)
{
return *(__force volatile u32 *)addr;
}
static inline void __raw_writeb(u8 b, volatile void __iomem *addr)
{
*(__force volatile u8 *)addr = b;
}
static inline void __raw_writew(u16 w, volatile void __iomem *addr)
{
*(__force volatile u16 *)addr = w;
}
static inline void __raw_writel(u32 l, volatile void __iomem *addr)
{
*(__force volatile u32 *)addr = l;
}
static inline u8 __readb(const volatile void __iomem *addr)
{
return *(__force volatile u8 *)addr;
}
static inline u16 __readw(const volatile void __iomem *addr)
{
return flip_word(*(__force volatile u16 *)addr);
}
static inline u32 __readl(const volatile void __iomem *addr)
{
return flip_dword(*(__force volatile u32 *)addr);
}
static inline void __writeb(u8 b, volatile void __iomem *addr)
{
*(__force volatile u8 *)addr = b;
}
static inline void __writew(u16 w, volatile void __iomem *addr)
{
*(__force volatile u16 *)addr = flip_word(w);
}
static inline void __writel(u32 l, volatile void __iomem *addr)
{
*(__force volatile u32 *)addr = flip_dword(l);
}
#define readb(__addr) __readb(__addr)
#define readw(__addr) __readw(__addr)
#define readl(__addr) __readl(__addr)
#define readb_relaxed(__addr) readb(__addr)
#define readw_relaxed(__addr) readw(__addr)
#define readl_relaxed(__addr) readl(__addr)
#define writeb(__b, __addr) __writeb((__b),(__addr))
#define writew(__w, __addr) __writew((__w),(__addr))
#define writel(__l, __addr) __writel((__l),(__addr))
writel() 往内存映射的 I/O 空间上写数据,wirtel() I/O 上写入 32 位数据 (4字节)
其他的都是类似用法。