uboot系列之------CPU初始化概述(源码)

来源:互联网 发布:橙子网络 编辑:程序博客网 时间:2024/06/13 02:10

这一篇主要讲述uboot对于CPU的初始化

 

Uboot源码开始的地方可以参考链接文件u-boot.lds里面的.text段的第一句话,对于2010.12版本的uboot(基于4412平台),其内容是这样的:

.text :                  

        {

                  arch/arm/cpu/armv7/start.o         (.text)

                  board/samsung/smdk4212/libsmdk4212.o(.text)

                  arch/arm/cpu/armv7/exynos/libexynos.o        (.text)

                  *(.text)

        }

可见uboot源码的第一条语句位于arch/arm/cpu/armv7/start.S文件中

 

下面进入到arch/arm/cpu/armv7/start.S文件,(分析的顺序不是按照程序的书写顺序,而是程序的执行顺序)

.globl _start

_start: b    reset

可见程序的开始就是跳到标号为reset的地方执行

reset:

         /*

          * set the cpu to SVC32 mode

          */

         mrs   r0, cpsr

         bic     r0, r0, #0x1f

         orr     r0, r0, #0xd3

         msr   cpsr,r0

   …….

       bl      cpu_init_crit

从程序的注释就可以看出以上语句是让cpu进入SVC模式,然后跳转到cpu_init_crit

cpu_init_crit:

       blcache_init

       /*

        *Invalidate L1 I/D

      */

       mov r0, #0     @set up for MCR

       mcr p15,0,r0,c8,c7,0 @invalidate TLBS

       mcr p15,0,r0,c7,c5,0  @invalidate icache

       /*

        disable MMU stuff and caches

       */

        mrc p15,0,r0,c1,c0,0

        bic r0,r0,#0x00002000  @clear bits 13(--V--)

       bic     r0, r0,#0x00000007     @ clear bits 2:0 (-CAM)

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

      orr     r0,r0,#0x00000002       @ set bit 1 (--A--) Align

       orr   r0,r0,#0x00000800       @set bit 11 (Z--) BTB

      mrc    p15,0,r0,c1,c0,0

      mov   ip,lr    @persevere link reg across call

      bl   lowlevel_init      @go setup pll,mux,memory

     mov  lr,ip   @restore link

       mov  pc,lr     @back to my caller

cpu_init_cirt主要是初始化cache,关闭MMU和中断,然后进入到lowlevel_initlowlevel_init位于board/samsung/smdk4212/lowlevel_init.s文件中

         .globllowlevel_init

lowlevel_init: 

       ldr     r0,=(INF_REG_BASE+INF_REG1_OFFSET)

       ldr    r1,[r0]

      /*Sleepwakeup reset*/

      ldr  r2,=S5P_CHECK_SLEEP

      cmp r1.r2

    beq  wakeup_reset

       

判断CPU是怎样进入复位的,如果是从睡眠唤醒进入复位的,就跳转到wakeup_reset,否则继续往下执行

         blpmic_init 

          bl uart_asm_init

       初始化电源管理芯片和串口,Uboot运行时打印出来的信息都是通过这个初始化的串口打印出来的

       bl  read_om 

       ......

         read_om:

                /*Readbooting information*/

           ldr r0,=S5PV310_POWER_BASE

           ldr   r1,[r0,#OMR_OFFSET]

            bic   r2,r1,#0cffffffc1

S5PV310_POWER_BASEOM_STAT寄存器,存储OM管脚的信息,整个语句下来,就把OM管脚信息(启动信息)存储在了寄存器r2中,接下来的程序就是判断从何处启动了

         ……

/* eMMC 4.4 BOOT*/

        cmp  r2, #0x8

       moeeq  r2,#BOOT_EMMC_4_4

      cmp  r2,#0x28

       moveq  r3,#BOOT_EMMC_4_4

       ldr r0,=INF_RGE_BASE

       str r3,[r0,#INF_REG3_OFFSET]

        ldr pc,lr

        我这个开发板是从emmc4.4启动所以满足上述语句,同时将启动信息保存在INFORM3寄存器中,然后回到程序跳转的地方,接着bl read_om往下执行

        ldr   r0, =0xff000fff

        bic   r1,pc,r0   /*r0<-current base addr of code*/

         ldr   r2,_TEXT_BASE /*r1<-original base addr in ram*/

         bic  r2,r2,r0   /*r0<-current base addr of code*/

         cmp r1,r2  /*compare r0,r1*/

        beq after_copy

        判断当前程序指针是否在SDRAM中,如果是,则跳过SDRAM的初始化,也不需要装载u-boot.bin了,直接执行after_copy,我这个开发板是从emmc启动的,所以程序此时还不在SDRAM中,还要接着往下执行

 /*Memory initialize */

     bl mem_ctrl_asm_init

      /*initsystem clock*/

      bl  system_clock_init

      b   1f

       内存初始化以及系统时钟初始化,然后跳转到前面的标号为1

1:

         bl tzpc_init

        b   load_uboot 

       初始化trustzoneprotection controller,并跳转到load_uboot

       

load_uboot:

         ldr    r0,=INF_REG_BASE

         ldr  r1,[r0,#INF_REG3_OFFSET]

         ......

         cmp r1,#BOOT_NAND

         ......
         cmp r1,#BOOT_EMMC_4_4

         beq  emmc_boot_4_4

       ......

   通过判断从何处启动,跳转到相应的标号处执行,我这块开发板将跳转到emmc_boot_4_4,该标号处的语句作用就是从emmc处拷贝ubootSDRAM中,然后跳转到after_copy

             

after_copy:

#ifdef CONFIG_SMDKC220 

        /*set up C2C*/

      ldr r0,=S5PV310_SYSREG_BASE

      ldr r2,=GENERAL_CTRL_C2C_OFFSET

     ldr r1,[r0,r2]

     ldr  r3,=0x4000

     orr  r1,e1,r3

     str  r1,[r0,f2]

#endif

#ifdef CONFIG_ENABLE_MMU

      bl   enable_mmu

        

#endif

        /*store second boot information in u-boot C lelve variable*/

      ldr  r0,=CONFIG_PHY_UBOOT_BASE

      sub  r0,r0,#8

       ldr r1,[r0]

      ldr  r0,_second_boot_info

       str  r1,[r0]

      ........

       ldr r0,_board_init_f

      mov pc,r0

     

     after_copy所做的工作主要就是初始化设置C2C,打开MMU,并跳到board_init_f执行板级初始化。

 

 

总结:

  CPU的初始化主要工作如下:

1、 CPU设成SVC模式,并且关闭中断和MMU

2、 初始化串口,便于UBOOT执行时打印相关信息

3、 判断电路板设置为从何处启动

4、 uboot从启动设备拷贝到SDRAM

原创粉丝点击