S&T的笔记 https://bbs.21ic.com/?600909 [收藏] [复制] [RSS] science and technology!

日志

U-Boot启动过程完全分析(3)

已有 792 次阅读2011-12-16 03:16 |个人分类:ARM|系统分类:ARM| U-Boot

7)关闭MMUcache


       接着往下看:


#ifndef CONFIG_SKIP_LOWLEVEL_INIT


       bl    cpu_init_crit


#endif


       cpu_init_crit这段代码在U-Boot正常启动时才需要执行,若将U-BootRAM中启动则应该注释掉这段代码。


       下面分析一下cpu_init_crit到底做了什么:


320  #ifndef CONFIG_SKIP_LOWLEVEL_INIT


321  cpu_init_crit:


322      /*


323       * 使数据cache与指令cache无效 */


324       */ 


325      mov       r0, #0


326      mcr p15, 0, r0, c7, c7, 0    /* c7写入0将使ICacheDCache无效*/


327      mcr p15, 0, r0, c8, c7, 0    /* c8写入0将使TLB失效 */


328 


329      /*


330       * disable MMU stuff and caches


331       */


332      mrc p15, 0, r0, c1, c0, 0    /*  读出控制寄存器到r0  */


333      bic  r0, r0, #0x00002300   @ clear bits 13, 9:8 (--V- --RS)


334      bic  r0, r0, #0x00000087   @ clear bits 7, 2:0 (B--- -CAM)


335      orr   r0, r0, #0x00000002   @ set bit 2 (A) Align


336      orr   r0, r0, #0x00001000   @ set bit 12 (I) I-Cache


337      mcr p15, 0, r0, c1, c0, 0    /*  保存r0到控制寄存器  */


338 


339      /*


340       * before relocating, we have to setup RAM timing


341       * because memory timing is board-dependend, you will


342       * find a lowlevel_init.S in your board directory.


343       */


344      mov       ip, lr


345 


346      bl    lowlevel_init


347 


348      mov       lr, ip


349      mov       pc, lr


350  #endif /* CONFIG_SKIP_LOWLEVEL_INIT */


       代码中的c0c1c7c8都是ARM920T的协处理器CP15的寄存器。其中c7cache控制寄存器,c8TLB控制寄存器。325~327行代码将0写入c7c8,使CacheTLB内容无效。


       332~337行代码关闭了MMU。这是通过修改CP15c1寄存器来实现的,先看CP15c1寄存器的格式(仅列出代码中用到的位):


2.3 CP15c1寄存器格式(部分)






































15


14


13


12


11


10


9


8


7


6


5


4


3


2


1


0


.


.


V


I


.


.


R


S


B


.


.


.


.


C


A


M


       各个位的意义如下:


V :  表示异常向量表所在的位置,0:异常向量在0x000000001:异常向量在 0xFFFF0000
I :  0
:关闭ICaches1 :开启ICaches
R
S : 用来与页表中的描述符一起确定内存的访问权限
B :  0
CPU为小字节序;1 CPU为大字节序
C :  0
:关闭DCaches1:开启DCaches
A :  0
:数据访问时不进行地址对齐检查;1:数据访问时进行地址对齐检查
M :  0
:关闭MMU1:开启MMU


       332~337行代码将c1 M位置零,关闭了MMU


8)初始化RAM控制寄存器


       其中的lowlevel_init就完成了内存初始化的工作,由于内存初始化是依赖于开发板的,因此lowlevel_init的代码一般放在board下面相应的目录中。对于mini2440lowlevel_initboard/samsung/mini2440/lowlevel_init.S中定义如下:


45  #define BWSCON   0x48000000        /* 13个存储控制器的开始地址 */


  … …


129  _TEXT_BASE:


130      .word     TEXT_BASE


131 


132  .globl lowlevel_init


133  lowlevel_init:


134      /* memory control configuration */


135      /* make r0 relative the current location so that it */


136      /* reads SMRDATA out of FLASH rather than memory ! */


137      ldr     r0, =SMRDATA


138      ldr   r1, _TEXT_BASE


139      sub  r0, r0, r1              /* SMRDATA _TEXT_BASE就是13个寄存器的偏移地址 */


140      ldr   r1, =BWSCON   /* Bus Width Status Controller */


141      add     r2, r0, #13*4


142  0:


143      ldr     r3, [r0], #4    /*13个寄存器的值逐一赋值给对应的寄存器*/


144      str     r3, [r1], #4


145      cmp     r2, r0


146      bne     0b


147 


148      /* everything is fine now */


149      mov       pc, lr


150 


151      .ltorg


152  /* the literal pools origin */


153 


154  SMRDATA:            /*  下面是13个寄存器的值  */


155  .word  … …


156   .word  … …


 … …


       lowlevel_init初始化了13个寄存器来实现RAM时钟的初始化。lowlevel_init函数对于U-BootNAND FlashNOR Flash启动的情况都是有效的。


       U-Boot.lds链接脚本有如下代码:


       .text :


       {


                     cpu/arm920t/start.o    (.text)


                board/samsung/mini2440/lowlevel_init.o (.text)


                 board/samsung/mini2440/nand_read.o (.text)


              … …


       }


       board/samsung/mini2440/lowlevel_init.o将被链接到cpu/arm920t/start.o后面,因此board/samsung/mini2440/lowlevel_init.o也在U-Boot的前4KB的代码中。


       U-BootNAND Flash启动时,lowlevel_init.o将自动被读取到CPU内部4KB的内部RAM中。因此第137~146行的代码将从CPU内部RAM中复制寄存器的值到相应的寄存器中。


       对于U-BootNOR Flash启动的情况,由于U-Boot连接时确定的地址是U-Boot在内存中的地址,而此时U-Boot还在NOR Flash中,因此还需要在NOR Flash中读取数据到RAM中。


       由于NOR Flash的开始地址是0,而U-Boot的加载到内存的起始地址是TEXT_BASESMRDATA标号在Flash的地址就是SMRDATATEXT_BASE


       综上所述,lowlevel_init的作用就是将SMRDATA开始的13个值复制给开始地址[BWSCON]13个寄存器,从而完成了存储控制器的设置。


路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)