进行Linux驱动方面开发的程序员,经常需要使用readl/writel系列函数对Memory-Mapped IO进行读写。那么readl/__readl/raw_readl/__raw_readl几个函数的具体语义有何差别呢?

内核中关于这几个函数的说明非常有限,根据stackoverflow上的这个问答,我们可以总结为:

  1. raw前缀只与byteorder相关,即readl/writel是linux默认的小端操作,而raw_readl/raw_writel是native访问。也就是说:如果是小端系统,raw_readlreadl相同,如果是大端系统,raw_readlreadl的有字节序差别。

  2. 双下划线前缀与指令保序相关,即readl/writel包含存储器栅栏指令mb,能够保证IO读写顺序,而__readl/__writel则不能保证。

另外,有的体系结构还会定义readl_relaxed/writel_relaxed接口,其含义应该与__readl/__writel相同,表示小端、不带存储器栅栏的读写。