编写设备驱动程序时linux中__iomem的用途是什么?

维伦德拉·库玛(Virendra Kumar):

我已经看到它__iomem用于存储的返回类型ioremap(),但是我已经u32在ARM体系结构中使用了它,并且效果很好。

那么,这有什么不同__iomem呢?在什么情况下我应该使用它呢?

eepp:

许多类型强制转换只会“工作得很好”。但是,这不是很严格。没有什么可以阻止您将a强制转换u32为a u32 *并取消对其的引用,但这并不遵循内核API,因此容易出错。

__iomemSparse使用的cookie,Sparse是一种用于在内核中查找可能的编码错误的工具。如果您未在启用稀疏的情况下编译内核代码,__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的诞生和使用它的功能。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

obj-m是什么意思:在Linux设备驱动程序Makefile中

Linux设备驱动程序代码中的MODULE_ALIAS是什么?

“其他驱动程序”中的此设备是什么?

写入设备驱动程序时会发生什么?

raspberry pi:编写Linux设备驱动程序

如何编写简单的Linux设备驱动程序?

如何练习编写真正的Linux设备驱动程序?

使用 OpenSource 驱动程序时,在 Xubuntu 14.04 中监控 GPU 温度的最佳方法是什么?

在Linux设备驱动程序中使用GPL lincense的重要性是什么

在Linux设备驱动程序中使用浮点的编码约定是什么?

在Linux设备驱动程序中使用浮点的编码约定是什么?

某个设备文件背后的驱动程序是什么?

设备驱动程序中IN PDRIVER_OBJECT driverObject中的IN是什么?

确定是否可以在OSX的用户空间中编写HID设备驱动程序的最佳方法是什么?

我的“其他驱动程序”中的“未知设备”是什么?

什么是Linux驱动程序中的wmb()

laravel 中的驱动程序是什么?例如缓存驱动

Linux平台驱动程序和普通设备驱动程序有什么区别?

为什么Linux中的文件系统未归类为设备驱动程序?

Linux内置驱动程序加载顺序是什么?

Linux 中的字符设备驱动程序读/写

Linux内核中的WS2812设备驱动程序

如何在Linux设备驱动程序中设置errno?

Linux设备驱动程序中的静态函数?

Ubuntu基本更新中的Linux通用标头和驱动程序是什么?

Linux驱动程序中的platform_get_resource是什么?

使用CQL jdbc驱动程序时连接字符串应该是什么

使用GCC驱动程序时,是什么使静态库“不兼容”?

uri 驱动程序中的前缀名称是什么