【发布时间】:2020-11-29 01:12:10
【问题描述】:
在 Linux 内核源代码 arch/arm64/kernel/head.S 中,引导要求状态是引导加载程序必须在 D-cache 关闭的情况下进入:
/*
* Kernel startup entry point.
* ---------------------------
*
* The requirements are:
* MMU = off, D-cache = off, I-cache = on or off,
* x0 = physical address to the FDT blob.
...
*/
然后,在preserve_boot_args() 函数中,在将参数加载到boot_args 数组后调用使D-cache 的一个区域无效
SYM_CODE_START_LOCAL(preserve_boot_args)
mov x21, x0 // x21=FDT
adr_l x0, boot_args // record the contents of
stp x21, x1, [x0] // x0 .. x3 at kernel entry
stp x2, x3, [x0, #16]
dmb sy // needed before dc ivac with
// MMU off
mov x1, #0x20 // 4 x 8 bytes
b __inval_dcache_area // tail call
SYM_CODE_END(preserve_boot_args)
如果D-cache关闭,为什么D-cache行需要失效?
【问题讨论】:
-
当缓存关闭时,它们仍然响应命中(即,如果它们没有失效并且软件写入缓存中已经存在的行,则该行在缓存中被修改并且永远不会写入内存)。有一个 ARM 文档说明了这一点。我的假设是:引导加载程序可能已禁用但未使缓存无效,并且由于
boot_args缓冲区的地址是任意的,因此固件/引导加载程序缓存的可能性很小。如果boot_args最终位于先前访问的内存区域中,则会发生这种情况。因此无效。 -
它是否有可能被失效以便在某个时候可以打开?
-
@MargaretBloom 那么你的意思是如果稍后打开缓存,修改后的缓存行会写入内存?我不知道这个“D-cache is off”是什么意思。从这个链接(developer.arm.com/documentation/ddi0344/b/level-2-memory-system/…)听起来 D-cache 关闭意味着数据直接进出内存。
-
@ChanKim 当 D-cache 关闭时,不会在缓存中获取新行但不会刷新缓存,它仍然保留其数据。只要没有命中缓存,数据就会绕过缓存。如果稍后打开缓存,它包含的行将根据替换策略写入内存。如果您缓存了一个位置并禁用了缓存,则该位置将继续从缓存中提供(反之,以前未缓存的位置将绕过它)。
-
@MargaretBloom“如果它们没有失效并且软件写入缓存中已经存在的行,则该行在缓存中被修改并且永远不会写入内存。有一个 ARM 文档说明了这一点”。你能指点那个医生吗?如果您所说的(“从未写入内存”)属实,则意味着任何写入内存都必须伴随着缓存闪存。否则有些数据可能永远不会到达内存。
标签: assembly caching linux-kernel arm64 cpu-cache