蜗窝科技

Linux下“用户空间修改设备寄存器或者物理内存”的问题

蜗窝讨论区存档 · Linux kernel技术问答 · 楼主 anchen · 2016-09-26 · 4 帖

本文是原「蜗窝讨论区」的历史存档(2016-09-26),来自版块「Linux kernel技术问答」,共 4 帖。讨论区已停止服务,此处仅供查阅。

anchen · 2016-09-26 14:59

我想请教一个和O_SYNC有关的具体问题。

我的系统是Altera的SoC,我要在用户空间为DMAC(pl330)更新其微码,结果发现DMA第一次运行正常,第二次运行依然执行前一次操作(虽然微码中的源和目的我都更新过了)。现在的结论是,因为这个SoC的架构,DMAC总是通过ACP访问L2 cache,意外着,DMA第一次会将微码锁存在L2 cache中,而用户空间在更新微码的过程中,没有处理L2 cache和memory的一致性,造成DMA第二次访问时,L2 cache依然命中,所以再次运行第一次的操作。我考虑过如下O_SYNC的使用,但也没有成功,不知道这样使用对不对?

FdforOcm = open("/dev/mem", O_RDWR); OcmAddr = mmap(NULL, 0x40000, PROT_READ|PROT_WRITE, MAP_SHARED, FdforOcm, 0xFFE00000); //这个返回的地址用来给程序更新DMA微码,不使用O_SYNC,意味着一定会写入cache,然后更新memory吗?

FdforDMA = open("/dev/mem", O_RDWR | O_SYNC); DMAAddr = mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, FdforDMA, 0xFFDA0000);
//这个返回的地址用来给程序访问DMA的寄存器

anchen · 2016-09-26 15:01

我两种都试了,无论是加还是不加 O_SYNC,结果似乎都是直接写入最终的物理设备,而没有同时更新到cache。有没有什么办法可以满足我的要求,写入最终设备的同时,更新到cache?或者说,如何在更新物理设备的同时,能够在用户空间,失效相对应的那部分cache?对现在的情况来说,我只要求物理memory和L2 cache能保持一致就可以了。

wowo · 2016-09-26 18:47

我觉得你的需求应该就是invalidate l2 cache? 以arm平台为例,其实就是一条写p15协处理器的指令(当然,需要一些内存屏障操作)。 arm平台为这个需求抽象出来了一系列的接口,头文件在:arch/arm/include/asm/outercache.h 可以参考kernel中某些CPU的实现,例如:arch/arm/mm/cache-feroceon-l2.c 当然,如果粗暴一些,你也可以自己写一个,开放给用户空间程序使用。 不知道还有没有其它好的方法?知道的同学也吱一声~~~

linuxer · 2016-09-27 18:59

wowo 写道: 我觉得你的需求应该就是invalidate l2 cache? 以arm平台为例,其实就是一条写p15协处理器的指令(当然,需要一些内存屏障操作)。 arm平台为这个需求抽象出来了一系列的接口,头文件在:arch/arm/include/asm/outercache.h 可以参考kernel中某些CPU的实现,例如:arch/arm/mm/cache-feroceon-l2.c 当然,如果粗暴一些,你也可以自己写一个,开放给用户空间程序使用。 不知道还有没有其它好的方法?知道的同学也吱一声~~~

我觉得选择mapping成 write back cache辅以clean cache to poc会比较适合这个用户场景。 当然,如果选择mapping成non cache的,那么invalidate cache to poc指令也能让功能正常(应该在DMAC访问memory之前进行,确保DMAC可以访问到main memory中的更新后的数据),只是性能受一点影响。