Warm tip: This article is reproduced from serverfault.com, please click

其他-在Linux下,如何将ARM Cortex A上的内存区域表示为“设备”或“强排序”

(其他 - How are memory regions on ARM Cortex A denoted as "device" or "strongly ordered" under Linux)

发布于 2020-11-29 12:58:17

在包含我正在使用的Zynq SoC的一部分的ARM Cortex-A9上,内存区域被标记为“正常”,“设备”或“有序排列”。Zynq技术参考手册中对此进行了描述,但据我了解,这更普遍地是ARM的属性。显然,对于存储器映射设备(在FPGA架构中包括许多设备)具有强排序的存储器访问能力应该会在某种程度上简化软件,因此需要进行设置。

我正在使用UIO驱动程序将设备内存映射到用户空间,该驱动程序的大部分运行在该用户空间中。根据此参考,UIO驱动程序将其映射的内存设置为“设备/强排序”。不幸的是,这是我唯一能找到的参考,在我开始从代码中删除内存屏障之前,我想对正在发生的事情有更多的信心。

目前我还不清楚Linux内核如何表示特定类型的内存区域。在我看来,MT_*属性沿这些方向表示某些东西,但是我找不到每种类型的定义。我也无法弄清楚UIO驱动程序如何指定特定的内存。

无论是一般术语还是理想情况下有关UIO的关于在Linux中如何设置内存属性的任何指示都将特别有用。我很高兴以指向文档的形式获得它。

Questioner
Henry Gomersall
Viewed
0
Henry Gomersall 2020-12-15 00:57:41

这有几个部分。

在包括Zynq-7000的ARMv7上,通过转换表描述符配置的内存区域属性将内存表示为给定类型。有多种配置这些方法的方法,其机制在《ARM体系结构参考手册ARMv7-A》的B3.8节中进行了描述Zynq技术参考手册也很有用,该手册相对于ARM而言不完整,但更易于处理。

大致而言,感兴趣的B位是C(可缓冲)位,(可缓存)位和3个TEX(类型扩展)位。这些可以直接设置,也可以通过在SCTLR.TRE设置位时通过重定向来设置(这实际上允许使用PRRRandNMRR寄存器进行自定义重新映射-可能不止于此,但我无法立即看到结果)。

转换表描述符是在Linux中的内存管理单元(MMU)子系统中设置的。显然,这是非常特定于体系结构的,相关的ARM位在arch / arm / mm中通过mmu.c查看如何在不同类型上配置不同的内存属性很有趣

接下来的内容是投机性的,但我认为是正确的。

核心UIO驱动程序通过调用在物理设备上设置其相关的内存保护pgprot_noncached()现在,我认为这是委托给特定于体系结构的实现的,在ARMv7的情况下,它是arch / arm / include / asm / pgtable.h中定义的宏,并决定设置该L_PTE_MT_UNCACHED标志。

L_PTE_MT_UNCACHED常数是在依次组拱/臂/包括/ ASM / pgtable-2level.h该文件中有很多文档描述了各种常量所代表的含义。对于每种类型的值被重新映射到BCTEX位,或者通过TRE重定向或通过构造一个查找表拱/臂/毫米/ PROC-macros.S我认为TRE重定向寄存器(PRRRNMRR)是在arch / arm / mm / proc-v7-2level.S中配置的如果跟踪这些内容,则会得到与查找表相同的值(查找表引用了arch / arm / include / asm / pgtable-2level-hwdef.h中定义的常量。-请注意,这些常量是用于小页表描述符的,与mmu.c)中使用的常量不同

这在哪里离开我们?所述UIO驱动器配置一块内存作为pgprot_noncached()暗示其是L_PTE_MT_UNCACHED,这又意味着TEX = 000B = 0C = 0查看参考手册中的设置,我们看到这对应于一个无缓冲的,有序的,可共享的内存区域(表示为“强类型”)。

显然,要更改设备(可能允许缓冲写入),我们需要修改内存的驱动程序配置以使用例如pgprot_writecombine()将内存类型设置为正常但关闭缓存的驱动程序还有一个pgprot_device()宏,它也可以设置设备内存类型(可缓冲)和缓存,但是带有一些我尚未正确理解的其他标志(我认为它们用于配置页表项的软件“ Linux”版本(如果硬件不支持它,那么它就不相关了)。