在嵌入式系统中,boot-loader用于初始化板和加载映像。通常,boot-loader在第一阶段在norflash中运行,需要将自身(.txte + .date代码)从flash复制到ram,然后跳转到ram执行代码。
我的问题是:当从闪存复制代码到RAM和缓存启用时,我们是否必须刷新数据缓存并使指令缓存无效?我发现uboot和其他bootloader执行了这个操作,但如果我不这样做,系统仍然可以启动成功,为什么我们必须在将代码从flash复制到ram之后刷新数据缓存?
答案 0 :(得分:3)
简单的嵌入式MCU通常没有任何手段来监听" snoop"总线检查是否有人(甚至自己)通过写入缓存的内存地址使缓存内容无效。
如果您的MCU具有单独的数据和指令缓存(大多数现代MCU都有)并且您将代码作为数据从闪存复制到RAM,则需要刷新数据缓存(以确保您复制的所有内容都物理写入RAM)和使指令缓存无效(可能包含复制前的#34;旧"信息),以真正执行刚刚复制的代码,而不是执行之前的代码并仍然驻留在指令缓存中。
如果你可以确定你的MCU从未见过"你可能会离开而不是做后者刚刚复制之前的内存区域(因为它不会缓存任何东西,无论如何都需要物理读取RAM),但是做好数据缓存刷新和指令缓存失效仍然是安全的一面是很好的做法。 / p>
将代码从闪存复制到RAM 是一种自修改代码的特例,作为程序员,您需要确保它不会造成任何损害。
答案 1 :(得分:0)
我认为主要原因可以在“多个核心”CPU中找到。在不对称核心的情况下非常重要,例如。 i.MX6SoloX(单芯片上的Cortex A9和Cortex M4)。
例如在i.MX6SoloX中,如果从核(M5)在 RAM(DDR)上运行主核心(A9),主要的cpu必须在正确的位置提供 M4核心代码加载到 RAM 。这些核心具有不同的D-caches,彼此之间没有看到。如果A9内核在FLASH到RAM复制之后没有刷新它的D-Chache,那么部分代码实际上并没有复制到RAM中,因为它仍然存在于D-Cache内存中。如果从u-boot执行此副本,您可以看到A9(运行U-Boot)看到所有正确复制的数据,但M4查看所有代码,但不是仍然在A9核心的D-Cache中的代码。 / p>
在你的情况下(像我这样的单核)U-Boot不是必须刷新D-cache(我猜之后是内核副本),因为D-cache的所有者是核心本身:它可以在其所有记忆中看到它的代码。
最后一个原因是,为了让执行的数据副本完全将数据写入特定地址,您必须刷新D-Cache,否则一些数据仍然可以在缓存中。