原文地址:《uboot啓動代碼分析之系統引導時爲什麼要關閉Caches?》
目錄
一、在哪關閉cache
U-Boot-2012.04.01中有如下代碼:
cpu_init_crit:
/*
* flush v4 I/D caches //關閉數據和指令緩存
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
在Linux 2.6.30.4中也有類似的代碼
__arm920_setup:
mov r0, #0
mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
#ifdef CONFIG_MMU
mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
#endif
adr r5, arm920_crval
ldmia r5, {r5, r6}
mrc p15, 0, r0, c1, c0 @ get control register v4
bic r0, r0, r5
orr r0, r0, r6
mov pc, lr
二、系統引導時爲什麼要關閉Caches
從引言中我們可以看出,在U-Boot和Linux的引導階段都關閉了Caches,這是爲什麼呢?
Caches是CPU內部的一個2級緩存,它的作用是將常用的數據和指令放在CPU內部。Caches是通過CP15管理的,剛上電的時候,CPU還不能管理Caches。上電的時候指令Cache可關閉,也可不關閉,但數據Cache一定要關閉,否則可能導致剛開始的代碼裏面,去取數據的時候,從Cache裏面取,而這時候RAM中數據還沒有Cache過來,導致數據預取異常 。
三、關鍵字Volatile
說到Caches就必須提到一個關鍵字Volatile,以後在設置寄存器時會經常遇到。它的本質:是告訴編譯器不要對我的代碼進行優化,作用是讓編寫者感覺變量的變化情況。
優化的過程:是將常用的代碼取出來放到Caches中,它沒有從實際的物理地址去取,它直接從CPU的緩存中去取,但常用的代碼就是爲了感覺一些常用變量的變化
優化原因:如果正在取數據的時候發生跳變,那麼就感覺不到變量的變化了,所以在這種情況下要用Volatile關鍵字告訴編譯器不要做優化,每次從實際的物理地址中去取指令,這就是爲什麼關閉Caches的原因。
但在C語言中是不會關閉Caches,會打開,如果編寫者要感覺外界變化,或變化太快,從Caches中取數據會有誤差,就加一個關鍵字Volatile。