编写设备驱动程序时linux中__iomem的用途是什么?
我已经看到它__iomem用于存储的返回类型ioremap(),但是我已经u32在ARM体系结构中使用了它,并且效果很好。
那么,这有什么不同__iomem呢?在什么情况下我应该使用它呢?
回答:
许多类型强制转换只会“工作得很好”。但是,这不是很严格。没有什么可以阻止您将a强制转换u32为a u32
*并取消对其的引用,但这并不遵循内核API,因此容易出错。
__iomem是Sparse使用的cookie
,该工具用于在内核中查找可能的编码错误。如果您未在启用稀疏的情况下编译内核代码,__iomem则无论如何都会被忽略。
首先安装它,然后添加C=1到您的make通话中,以使用稀疏。例如,在构建模块时,请使用:
make -C $KPATH M=$PWD C=1 modules__iomem 定义如下:
# define __iomem __attribute__((noderef, address_space(2)))__iomem为所有I / O访问添加(并要求)cookie 是一种更严格的方法,可以避免编程错误。您不想使用具有绝对地址的I /
O内存区域进行读/写操作,因为您通常使用虚拟内存。从而,
void __iomem *ioremap(phys_addr_t offset, unsigned long size);通常调用,以获取I /
O物理地址的虚拟地址offset,并size以字节为单位指定长度。ioremap()返回一个带有__iomemcookie 的指针,因此它
现在 可以与内联函数一起使用,例如readl()/ writel()(尽管现在最好使用更明确的宏ioread32()/
iowrite32()),这些函数接受__iomem地址。
同样,noderef稀疏使用该属性来确保您不取消引用__iomem指针。取消引用应该在I /
O确实是内存映射的某些体系结构上起作用,但是其他体系结构使用特殊的指令来访问I / O,在这种情况下,取消引用将不起作用。
让我们看一个例子:
void *io = ioremap(42, 4);稀疏不开心:
warning: incorrect type in initializer (different address spaces) expected void *io
got void [noderef] <asn:2>*
要么:
u32 __iomem* io = ioremap(42, 4);pr_info("%x\n", *io);
稀疏也不高兴:
warning: dereference of noderef expression在最后一个示例中,第一行是正确的,因为ioremap()将其值返回给__iomem变量。但是然后,我们尊重它,我们不应该这样做。
这使稀疏感到高兴:
void __iomem* io = ioremap(42, 4);pr_info("%x\n", ioread32(io));
底线:请始终__iomem在需要的地方使用(作为返回类型或参数类型),并使用稀疏来确保已这样做。另外:不要取消引用__iomem指针。
:这是一篇有关LWN的起始__iomem和使用它的功能的LWN文章。
以上是 编写设备驱动程序时linux中__iomem的用途是什么? 的全部内容, 来源链接: utcz.com/qa/399160.html

