l 让L1的I/D cache失效 1. 什么是cache Cache 是位于 CPU与主存储器DRAM之间的少量超高速静态存储器 SRAM(static RAM),其是为了解决 CPU 与主存之间速度匹配问题而设置的。 Cache又分为I-cache(用来存指令)和D-cache(用来存数据) 2. 为什么要让cache失效 我们在使用cache的时候要经过一系列的配置,在没配置之前是不能使用的。所以我们要关闭cache,但是在关闭cache之前cache里面可能已经有数据了,为了不影响我们的代码,所以要先让其失效,在进行关闭。 3. 怎么让cache失效 根据A8内核手册中的3.2.1Register allocation一节我们找到了其对CP15协处理器的寄存器的简介,我们仔细阅读其对所有寄存器的说明可以找到下面的表 那么怎么去设置这个寄存器呢,我们稍微看看文档就会发现下面东西 所以我们让cache失效的代码就很简单了,通过下面的指令就可以让cache失效了。 view sourceprint?
1.1 mcr p15, 0, r0, c7, c5, 0//让cache失效
注:在u-boot中这一部分代码还失效了别的东西,我们这里就不关注了。 l 关闭MMU和cache 1. 什么是MMU: MMU就是负责虚拟地址(virtual address)转化成物理地址(physical address)。 在这里肯定有人跟我一样的疑惑,既然有物理地址我们访问的时候访问物理地址不就完事了吗?为什么要有虚拟地址的存在,然后还要加个专门的硬件去转换,这就是多此一举吗? 其实加入了虚拟地址后有下面两个作用 1) 虚拟内存:有了虚拟内存,可以在处理器上运行比实际物理内存大的应用程序。 2) 内存保护:根据需要对特定的内存区块的访问进行保护,通过这一功能,我们可以将特定的内存块设置成只读、只写或是可同时读写。 2. 为什要关闭MMU 跟cache的原因一样,在使用MMU之前要进行一系列的初始化,并且过程比较复杂,现在用不到所以要关闭它。 3. 怎么关闭MMU 同样在刚才的寄存器列表中我们可以找到一个Control Register 我们重点关注一下它的下面几个位 从上图我们可以看到,我们只要将这个寄存器的0、2、12、位设置为零就可以关闭我们的cache和MMU了。 那么如何设置呢,我们稍微往下找找就可以找到 我们先要将里面的数据读出来,经过处理后在写入。所以就不难理解u-boot的代码了 view sourceprint?
01.1 mrc p15, 0, r0, c1, c0, 0
02.2
03.3 bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
04.4
05.5 bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
06.6
07.7 orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
08.8
09.9 orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
10.10
11.11 #ifdef CONFIG_SYS_ICACHE_OFF
12.12
13.13 bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
14.14
15.15 #else
16.16
17.17 orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
18.18
19.19 #endif
20.20
21.21 mcr p15, 0, r0, c1, c0, 0
注:我们重点关注我们刚才提到的几个是不是为零即可
接着流程往下,我们应该是检查reset状态和恢复IO引脚为默认值了,由于这两部分不是很重要的初始化,所以我们在此就跳过了,在往下就应该到关闭看门狗了 l 关闭看门狗 1. 什么是看门狗 看门狗的用途是使微控制器在进入错误状态后(死机)的一定时间内复位。当看门狗使能时,如果用户程序没有在周期时间内喂狗(重装),看门狗会产生一个系统复位。 2. 看门狗原理解析 我们在每个芯片的芯片手册中都可以找到下图: 1) PCLK经过预分频器以及选择器以后会产生看门狗时钟,然后通过计数逻辑模块,开始计数。 2) WTDAT是预先存放的计数初值,WTCNT是减量计数模块,当WTCNT从WTDAT的值减到0的时候,如果还没有更新WTDAT,则认为没有喂狗,系统死机。 3) 发出reset 信号,强制系统重启 3. 为什么要关看门狗 1) 要一直喂狗麻烦 2) 普遍认为bootloader代码较少,不需要看门狗。 4. 怎么关闭看门狗 在芯片手册中我们可以轻松的找到WTCON寄存器 通过上面寄存器的介绍,我们可以知道向其最低位写入0可关闭,其复位,想第二位写入0可关闭中断,索性我们之间写入0就完事,所以也就不难理解u-boot中的代码了 view sourceprint?
01.1 /* Disable Watchdog */
02.2
03.3
04.4
05.5 ldr r0, =ELFIN_WATCHDOG_BASE /* 0xE2700000 */
06.6
07.7 mov r1, #0
08.8
09.9 str r1, [r0] |