将代码从闪存复制到内存后,我们必须刷新数据缓存的原因是什么?

What's the reason why we must flush data cache after copy code from flash to ram?

在嵌入式系统中,boot-loader 用于初始化电路板和加载图像。通常,boot-loader在第一阶段运行在norflash中,需要将自身(.txte+.date代码)从flash复制到ram,然后跳转到ram执行代码。

我的问题是:当将代码从flash复制到RAM并启用缓存时,我们是否必须刷新数据缓存并使指令缓存无效?我发现uboot和其他bootloader执行了这个操作,但如果我不这样做,系统仍然可以启动成功,为什么我们必须在从flash复制代码到ram后刷新数据缓存?

简单的嵌入式 MCU 通常没有任何方法 "snoop" 总线检查是否有人(甚至它自己)通过写入缓存内存地址使缓存内容无效。

如果您的 MCU 具有独立的数据和指令缓存(大多数现代 MCU 都有)并且您将代码作为数据从闪存复制到 RAM,则您需要刷新数据缓存(以确保您复制的所有内容都物理写入 RAM ) 并使指令缓存(可能包含 "old" 复制之前的信息)无效,以真正执行您刚刚复制的代码,而不是执行之前存在且仍驻留在指令缓存中的代码。

如果您可以确定您的 MCU 在您刚刚复制之前从未 "seen" 内存区域(因为它不会缓存了任何东西,无论如何都需要物理读取 RAM),但是为了安全起见,最好还是进行数据缓存刷新和指令缓存失效。

将代码从闪存复制到 RAM 自我修改代码的一种特殊情况,作为程序员,您需要确保它不会造成任何损害。

我认为一个主要原因可以在 "more than one core" 个 CPU 中找到。在 不对称核心 的情况下非常重要,例如。 i.MX6SoloX(单芯片上的 Cortex A9 和 Cortex M4)。

例如在 i.MX6SoloX 中,如果从内核 (M5) 运行 在 RAM (DDR) 主核(A9)是主要cpu,必须提供M4核代码加载到RAM 在正确的位置。这些核心有不同的 D 缓存,彼此看不到。如果A9核心在FLASH拷贝到RAM之后,没有flush它的D-Cache,那么部分代码实际上并没有拷贝到RAM,因为还在D-Cache内存中。如果您从 u-boot 执行此复制,您可以看到 A9(即 运行ning U-Boot)看到所有正确复制的数据,但 M4 看到所有代码,但看不到仍在 D-Cache 中的代码A9 核心。

在你的情况下(我猜是像你这样的单核)U-Boot 刷新 D 缓存(我猜是在内核复制之后)不是强制性的,因为 D 缓存的所有者是核心本身:它可以在它所有的记忆中看到它的代码。

最后的原因是,要确保执行的数据副本将数据完全写入特定地址,您必须刷新 D-Cache,否则某些数据仍然在缓存中。