请注意,我对 ARM 和嵌入式 Linux 不熟悉,所以我所有的 cmets 都是从一般的角度来看的。
首先,关于缓存:在启动的早期,操作系统会进行一些缓存初始化。这需要的确切内容因处理器而异,但最终效果是确保缓存正确初始化,然后允许处理器使用它。在此之后,缓存由处理器独占操作,操作系统或您的程序没有进一步的交互。
现在,关于外部(片外)和内部(片上)存储器:
操作系统拥有系统上的所有硬件,包括内部和外部存储器,因此最终负责在内核和用户进程中发现、配置和分配这些资源。在典型的系统(例如,您的台式机或 1u 服务器)中,通常不会有任何特殊的内部(片上)内存,因此操作系统可以平等地对待所有内存。它将进入一个通用页面池(通常为 4k),用于分配给进程、文件系统缓冲区等。在具有各种特殊内存(nvram、高速片上内存和其他一些内存)的系统上,操作系统的一般策略通常不正确。
如何呈现给用户取决于将操作系统移植到该系统时所做的选择。
以下是您的一些具体问题的答案。
操作系统在区分这些不同的记忆方面发挥了多大作用?
如果您的系统采用上述设备驱动程序方法,那么操作系统可能只知道外部内存,或者可能只知道内部内存足以正确初始化它们,尽管设备驱动程序中也可能有,如果在一切皆有可能。如果操作系统更明确地知道片上存储器,那么它肯定会包含任何所需的初始化代码,以及某种提供对用户进程的访问的方案。
如何决定哪些缓冲区在外部存储器中,哪些缓冲区将在内部 SRAM 中分配,等等。
在我看来,操作系统不太可能尝试自动执行此类选择。相反,我怀疑操作系统或设备驱动程序会提供一个通用接口来提供对片上存储器的访问,并将其留给您的用户代码来决定如何处理它。
当在这样的系统/代码上调用 calloc/malloc 时,返回的指针来自哪个内存:内部还是外部?
几乎可以肯定,malloc 和朋友会返回指向通用片外内存的指针。在上面建议的基于驱动程序的方法中,您将使用mmap 来访问片上内存。如果您需要进行比这更细粒度的分配,则需要编写自己的分配器,或者找到一个可以指定显式内存区域的分配器。
用户能否在他选择的内存中分配缓冲区(内部/外部)?
如果 buffers 是指从标准 malloc 调用返回的区域,则可能不是。但是,如果您的意思是“用户程序能否以某种方式获得指向片上内存的指针”,那么答案几乎肯定是肯定的,但机制将取决于将 linux 移植到该系统时所做的选择。
在 ARM 架构中,还有一种称为“紧耦合内存”(TCM) 的内存。那是什么以及用户如何启用和使用它?我可以在这个内存中声明缓冲区吗?
我不知道这是什么。如果我不得不猜测,我会假设它只是另一种形式的片上 ram,但由于它的名称不同,也许我错了。
我是否需要查看硬件板的内存映射(如果有)来了解典型硬件板中存在的所有这些不同的物理内存?
如果操作系统和/或设备驱动程序提供了对这些内存区域的某种抽象访问,那么您不需要明确了解地址映射。然而,在内核或设备驱动程序中实现这种访问需要这些知识。
我希望这会有所帮助。