3

我正在阅读 Linux 内核。我很好奇在内存中写入数据的方式。

在驱动程序的某些部分,他们使用在该writel()函数asm/io.h中定义的函数和在该函数的定义中,他们使用movnti指令 - 实际上我不明白该指令的含义,除了它是一种mov指令。

writel()无论如何,在内存中写入数据时,使用和直接在内存中写入有什么区别,例如 **address = data;.

情况如下:

static inline void __writel(__u32 val, volatile void __iomem *addr)
{
    volatile __u32 __iomem *target = addr;
    asm volatile("movnti %1,%0"
             : "=m" (*target)
             : "r" (val) : "memory");
}

这是另一种情况:

*(unsigned int*)(MappedAddr+pageOffset) = result;
4

2 回答 2

2

writel看起来它是为内存映射 IO 设计的,有一些东西可以支持这一点,首先是volatile指针的使用(这会阻止优化,例如重新排序调用或优化它们等)和非临时指令(IO 写入/读取不应该被缓存)当然iomem注释似乎也支持这一点。

于 2013-07-17T07:21:13.023 回答
1

如果我理解正确,那么使用该指令moventi将对处理器数据缓存的影响降至最低。相反,使用*(unsigned int*)(MappedAddr+pageOffset) = result;它使编译器可以自由选择move它喜欢的任何指令,并且它可能会选择一个导致缓存线被拉入缓存的指令。如果您正在与内存映射设备交互,这可能不是您想要的。

于 2013-07-17T07:22:17.037 回答