我正在阅读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;
答案 0 :(得分:2)
writel
看起来像是用于内存映射IO,有一些东西要支持这个,首先使用volatile
指针(这会阻止优化,例如重新排序调用或优化它们之间)其他事情)和非temproal指令(IO写/读不应该被缓存)当然iomem
注释似乎也支持这一点。
答案 1 :(得分:1)
如果我正确理解this,那么使用moventi
指令将最大限度地减少对处理器数据缓存的影响。使用*(unsigned int*)(MappedAddr+pageOffset) = result;
代替编译器自由选择它喜欢的move
指令,并且它可能选择一个导致缓存行被拉入缓存的指令。如果您正在与内存映射设备进行交互,那么这可能不是您想要的。