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

Caching 什么';将代码从闪存复制到ram后,我们必须刷新数据缓存的原因是什么?,caching,embedded,bootloader,u-boot,flash-memory,Caching,Embedded,Bootloader,U Boot,Flash Memory,在嵌入式系统中,引导加载程序用于初始化主板和加载映像。通常,引导加载程序在第一阶段在norflash中运行,需要将自身(.txte+.date代码)从闪存复制到ram,然后跳转到ram执行代码 我的问题是:当将代码从闪存复制到RAM并启用缓存时,我们是否必须刷新数据缓存并使指令缓存无效?我发现uboot和其他引导加载程序执行此操作,但如果我不这样做,系统仍然可以成功引导,为什么我们必须在将代码从闪存复制到ram后刷新数据缓存?简单的嵌入式MCU通常没有任何手段“窥探”总线检查是否有人(甚至它自己

在嵌入式系统中,引导加载程序用于初始化主板和加载映像。通常,引导加载程序在第一阶段在norflash中运行,需要将自身(.txte+.date代码)从闪存复制到ram,然后跳转到ram执行代码


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

简单的嵌入式MCU通常没有任何手段“窥探”总线检查是否有人(甚至它自己)通过写入缓存内存地址使缓存内容无效

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

如果可以确保MCU在复制之前从未“看到”内存区域(因为它不会缓存任何内容,并且无论如何都需要物理读取RAM),那么不执行后一种操作可能会得逞,但为了安全起见,最好执行数据缓存刷新和指令缓存失效


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

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

例如,在i.MX6SoloX中,如果从核(M5)RAM(DDR)上运行,主核(A9)是必须在正确位置提供加载到RAM中的M4核代码的主cpu。这些核心具有不同的D缓存,彼此看不见。如果A9内核在闪存到RAM复制之后没有刷新它的D-Chache,那么一些代码实际上没有复制到RAM,因为仍然在D-Cache内存中。如果从u-boot执行此复制,您可以看到A9(正在运行u-boot)可以看到正确复制的所有数据,但M4可以看到所有代码,但不能看到仍在A9 core的D缓存中的代码

在您的情况下(我猜是像您这样的单个内核),U-Boot刷新D-cache(我猜是在内核拷贝之后),不是强制性的,因为D-cache的所有者是内核本身:它可以在所有内存中看到它的代码


归根结底,原因是要授权执行的数据拷贝将数据完全写入特定地址,您必须刷新D-Cache,否则某些数据可能仍在缓存中。

这(强制或不强制)取决于平台。一些(大多数?)有单独的指令和数据缓存。在这种情况下,即使只有一个内核,也必须刷新数据缓存,指令缓存才能读取。谢谢mfro!非常感谢你的解释。MCU为PowerPC QorIq T1040,具有单独的一级数据和指令缓存。仅启用一级缓存,禁用二级/三级缓存。我还有两个问题,如果有任何想法,我将不胜感激。1评论太长,所以我发布了一个答案,我是一个新的堆栈溢出。