Linux设备驱动程序的定义,编写设备驱动程序时,在linux中使用__iomem是什么?
许多类型的演员都将“工作得很好”.但是,这不是很严格.没有什么会阻止你将u32转换为u32 *并取消引用它,但是这不符合内核API并且容易出错.__iomem是Sparse使用的一个cookie,用于在内核中查找可能的编码错误.如果您不使用Sparse编译内核代码,__iomem将被忽略.使用稀疏首先安装它,然后添加C = 1到您的make呼叫.例如,当建立模块时,请使用:make -C $KPA
许多类型的演员都将“工作得很好”.但是,这不是很严格.没有什么会阻止你将u32转换为u32 *并取消引用它,但是这不符合内核API并且容易出错.
__iomem是Sparse使用的一个cookie,用于在内核中查找可能的编码错误.如果您不使用Sparse编译内核代码,__iomem将被忽略.
使用稀疏首先安装它,然后添加C = 1到您的make呼叫.例如,当建立模块时,请使用:
make -C $KPATH M=$PWD C=1 modules
__iomem定义如下:
# define __iomem __attribute__((noderef, address_space(2)))
为所有I / O访问添加(和要求)像__iomem这样的cookie是一种更严格的方法,避免编程错误.您不希望使用绝对地址读/写I / O内存区域,因为您通常使用虚拟内存.从而,
void __iomem *ioremap(phys_addr_t offset, unsigned long size);
通常被称为获取I / O物理地址偏移的虚拟地址,以指定的长度大小(以字节为单位). ioremap()返回一个带有__iomem cookie的指针,所以现在可以使用像readl()/ writel()这样的内联函数(尽管现在最好使用更显式的宏ioread32()/ iowrite32()), ,它接受__iomem地址.
此外,Sparse使用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] <2>*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 article关于__iomem的开始和使用它的功能.
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)