在编写设备驱动程序时,linux中的iomem有什么用途?
我已经看到在编写设备驱动程序时,linux中的iomem有什么用途?,linux,memory-management,linux-kernel,linux-device-driver,Linux,Memory Management,Linux Kernel,Linux Device Driver,我已经看到\uu iomem用于存储ioremap()的返回类型,但是我在ARM体系结构中使用了u32,它工作得很好 那么,\u iomem在这里有什么区别呢?在什么情况下我应该准确地使用它?很多类型转换都会“很好地工作”。但是,这不是很严格。没有什么可以阻止您将u32强制转换为u32*并取消对它的引用,但这并不遵循内核API,而且容易出错 \uu iomem是一个cookie,用于查找内核中可能的编码错误。如果不在启用稀疏的情况下编译内核代码,iomem将被忽略 使用Sparse,首先安装它,
\uu iomem
用于存储ioremap()
的返回类型,但是我在ARM体系结构中使用了u32
,它工作得很好
那么,
\u iomem
在这里有什么区别呢?在什么情况下我应该准确地使用它?很多类型转换都会“很好地工作”。但是,这不是很严格。没有什么可以阻止您将u32
强制转换为u32*
并取消对它的引用,但这并不遵循内核API,而且容易出错
\uu iomem
是一个cookie,用于查找内核中可能的编码错误。如果不在启用稀疏的情况下编译内核代码,iomem
将被忽略
使用Sparse,首先安装它,然后将C=1
添加到make
调用中。例如,在构建模块时,请使用:
make -C $KPATH M=$PWD C=1 modules
\uu iomem
的定义如下:
#定义uuiome uuuuu属性uuuu((noderef,地址空间(2)))
为所有I/O访问添加(并要求)类似cookie的\uuu iomem
,这是一种更加严格并避免编程错误的方法。您不想从具有绝对地址的I/O内存区域读/写,因为您通常使用虚拟内存。因此,
void\u iomem*ioremap(物理地址偏移量,无符号长尺寸);
通常被调用以获取I/O物理地址的虚拟地址偏移量
,以字节为单位指定长度大小
ioremap()
返回一个带有\uIomem
cookie的指针,因此现在可以将它与接受\uIomem
地址的内联函数一起使用,例如readl()
/iowrite32()
(尽管现在最好使用更显式的宏ioread32()
)
另外,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] <asn:2>*
他也不高兴:
warning: dereference of noderef expression
在上一个示例中,第一行是正确的,因为ioremap()
将其值返回给\uu iomem
变量。但是,我们尊重它,我们不应该这样做
这让斯派斯很高兴:
void\uuu iomem*io=ioremap(42,4);
pr_信息(“%x\n”,ioread32(io));
底线:在需要的地方(作为返回类型或参数类型)始终使用\uu iomem
,并使用Sparse确保这样做。另外:不要取消引用iomem
指针
编辑:这里有一个关于
\uu iomem
的开始以及使用它的函数的精彩解释。很好的解释。有一些很好的参考资料就说到点子上了。