U-Boot-2011.06启动流程分析

2014-11-24 10:09:34 · 作者: · 浏览: 0

首先系统是从arch/arm/cpu/arm920t目录下的start.s文件开始执行,并且实际开始执行的代码是从第117行开始:


117:start_code:


118: /*


119: * set the cpu to SVC32 mode


120: */


121: mrs r0, cpsr


122: bic r0, r0, #0x1f


123: orr r0, r0, #0xd3


124: msr cpsr, r0


上述代码的含义是设置cpu为SVC32模式,即超级保护模式,用于操作系统使用。



140:#ifdef CONFIG_S3C24X0


141: /* turn off the watchdog */


142:


143:# if defined(CONFIG_S3C2400)


144:# define pWTCON 0x15300000


145:# define INTMSK 0x14400008 /* Interupt-Controller base addresses */


146:# define CLKDIVN 0x14800014 /* clock divisor register */


147:#else


148:# define pWTCON 0x53000000


149:# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */


150:# define INTSUBMSK 0x4A00001C


151:# define CLKDIVN 0x4C000014 /* clock divisor register */


152:# endif


153:


154: ldr r0, =pWTCON


155: mov r1, #0x0


156: str r1, [r0]


157:


158: /*


159: * mask all IRQs by setting all bits in the INTMR - default


160: */


161: mov r1, #0xffffffff


162: ldr r0, =INTMSK


163: str r1, [r0]


164:# if defined(CONFIG_S3C2410)


165: ldr r1, =0x3ff


166: ldr r0, =INTSUBMSK


167: str r1, [r0]


168:# endif


169:


170: /* FCLK:HCLK:PCLK = 1:2:4 */


171: /* default FCLK is 120 MHz ! */


172: ldr r0, =CLKDIVN


173: mov r1, #3


174: str r1, [r0]


175:#endif /* CONFIG_S3C24X0 */


该段代码的含义为,先定义几个需要的寄存器,然后关闭开门狗定时器,以及屏蔽所有中断和子中断,最后设置三个时钟频率之间的比值。



181:#ifndef CONFIG_SKIP_LOWLEVEL_INIT


182: bl cpu_init_crit


183:#endif


在第182行中,程序跳转到cpu_init_crit中,它也是在start.s文件中,函数的位置在第328行至第356行,它的作用是设置一些重要的寄存器(如MMU和caches等)以及内存时序。其中在第353行,程序又跳转到了lowlevel_init函数,它是在board/samsung/smdk2410目录下的lowlevel_init.s文件中定义的,这个文件的目的就是为了设置内存的时序。



186:call_board_init_f:


187: ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)


188: bic sp, sp, #7 /* 8-byte alignment for ABI compliance */


189: ldr r0,=0x00000000


190: bl board_init_f


从cpu_init_crit返回后,来到了调用board_init_f的函数处。首先进行堆栈的设置,然后就跳转到board_init_f函数,其中传递给该函数的参数为0。board_init_f这个函数是在arch/arm/lib目录下的board.c文件内定义的,函数的位置是在第268行至第422行,它的作用是初始化开发板。需要注意的是,此时程序是在flash中运行的。



下面我们就来分析board_init_f函数。


275: /* Pointer is writable since we allocated a register for it */


276: gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);


277: /* compiler optimization barrier needed for GCC >= 3.4 */


278: __asm__ __volatile__("": : :"memory");


279:


280: memset ((void*)gd, 0, sizeof (gd_t));


281:


282: gd->mon_len = _bss_end_ofs;


gd是一个保存在ARM的r8寄存器中的gd_t结构体的指针,该结构体包括了u-boot中所有重要的全局变量,它是在arch/arm/include/asm目录下的global_data.h文件内被定义的。上述代码的作用是为gd分配地址,并清零,最后得到整个u-boot的长度。