u-boot 2009.08 (一)

                                                   u-boot2009.08.start.S代码分析

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

下面定义一些全局变量,

这里_TEXT_BASE是一个标签,告诉编译器在这里分配一个word的空间,存放的值为TEXT_BASE

_TEXT_BASE:
 .word TEXT_BASE 

.globl _armboot_start  这里用.globl伪指令定义一个全局标号,可以在其他文件引用


_armboot_start:                  
 .word _start                  

/*
 * These are defined in the board-specific linker script.
 */
.globl _bss_start  //bss段开始
_bss_start:             
 .word __bss_start

.globl _bss_end  //bss段结束
_bss_end:
 .word _end

#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */  

.globl IRQ_STACK_START
IRQ_STACK_START:
 .word 0x0badc0de

/* IRQ stack memory (calculated at run-time) */ 

 .globl FIQ_STACK_START
FIQ_STACK_START:
 .word 0x0badc0de   
#endif

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>/*
 * the actual start code
 */

start_code:  //进入代码段
 /*
  * set the cpu to SVC32 mode  
  */
 mrs r0,cpsr       //设置处理器模式操作系统使用的保护模式
 bic r0,r0,#0x1f  //屏蔽所有中断,在bootloader执行中不需要中断
 orr r0,r0,#0xd3
 msr cpsr,r0

 bl coloured_LED_init    //点灯针对具体的开发板,需要修改,测试用,可屏蔽
 bl red_LED_on

#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
 /*
  * relocate exception table
  */
 ldr r0, =_start          //重定位向量表
 ldr r1, =0x0
 mov r2, #16
copyex:
 subs r2, r2, #1
 ldr r3, [r0], #4
 str r3, [r1], #4
 bne copyex
#endif

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440)
 /* turn off the watchdog */

# if defined(CONFIG_S3C2400)
#  define pWTCON  0x15300000
#  define INTMSK  0x14400008 /* Interupt-Controller base addresses */
#  define CLKDIVN 0x14800014 /* clock divisor register */
#else
#  define pWTCON  0x53000000
#  define INTMSK  0x4A000008 /* Interupt-Controller base addresses */
#  define INTSUBMSK 0x4A00001C
#  define CLKDIVN 0x4C000014 /* clock divisor register */
# endif

 ldr     r0, =pWTCON    //各个硬件还未就绪,关闭看门狗
 mov     r1, #0x0
 str     r1, [r0]

 /*
  * mask all IRQs by setting all bits in the INTMR - default
  */
 mov r1, #0xffffffff    //禁止所有中断
 ldr r0, =INTMSK
 str r1, [r0]
# if defined(CONFIG_S3C2410)
 ldr r1, =0x3ff
 ldr r0, =INTSUBMSK
 str r1, [r0]
# endif

 str r1, [r0]
# if defined(CONFIG_S3C2440)
 ldr r1, =0x7fff
 ldr r0, =INTSUBMSK
 str r1, [r0]
# endif

# if defined(CONFIG_S3C2440)
#define MPLLCON    0x4c000004
#define UPLLCON    0x4c000008   
        ldr     r0,=CLKDIVN
        mov     r1,#05
        str     r1,[r0]

        ldr     r0,=MPLLCON    /* FCLK:HCLK:PCLK = 1:4:8 */  //设置时钟比例 FCLK用于CPU,HCLK用于AHB,PCLK用于APB

        ldr     r1,=0x7f021    /*405Mhz*/
        str     r1,[r0]
       
        ldr     r0,=UPLLCON  /*48Mhz*/
        ldr     r1,=0x38022
        ldr     r1,[r0]
#else

 /* FCLK:HCLK:PCLK = 1:2:4 */
 /* default FCLK is 120 MHz ! */
 ldr r0, =CLKDIVN
 mov r1, #3
 str r1, [r0]
#endif
#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */

 /*
  * we do sys-critical inits only at reboot,
  * not when booting from ram!
  */

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
 bl cpu_init_crit  //初始化cpu
#endif

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

 

下面这段代码是u-boot第一阶段最重要的工作,重定位代码段。这里要介绍一下adr指令,简单的说就是把 _start地址读出来,而且这个地址是相对当前pc的,所以和当前程序运行地址相关,如果在0x30000000运行,r0 = pc(0x30000004 + 0x08) + #0 = 0x3000000C;如果在0x00000000运行, r0 = pc(0x00000004 + 0x08) + #0 = 0x0000000C,所以在不同的位置运行,r0所得到的结果是不一样的,唯一确定的相对偏移量。


relocate:    /* relocate U-Boot to RAM     */
 adr r0, _start  /* r0 <- current position of code   */   r0<-得到_srart的运行地址
 ldr r1, _TEXT_BASE  /* test if we run from flash or RAM */  //r1<-Text_Base
 cmp     r0, r1                  /* don't reloc during debug         */   //如果两个地址相同,则在ram中,否则把代码搬运到ram中运行
 beq     stack_setup
       
                             

 ldr r2, _armboot_start                      //代码代码段起始地址
 ldr r3, _bss_start                            //bss段起始地址
 sub r2, r3, r2  /* r2 <- size of armboot            */        u-boot代码大小=-bss-start-_start
 add r2, r0, r2  /* r2 <- source end address         */  //u-boot大小加上_start运行地址,得出u-boot的运行结束地址

copy_loop:   
 ldmia r0!, {r3-r10}  /* copy from source address [r0]    */    把r0中的的数据放入r3-r10,r0加1,
 stmia r1!, {r3-r10}  /* copy to   target address [r1]    */       //把r3-r10的数据存入r1指向的地址,r1加1
 cmp r0, r2   /* until source end addreee [r2]    */
 ble copy_loop
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */

 /* Set up the stack          */
stack_setup:
 ldr r0, _TEXT_BASE  /* upper 128 KiB: relocated uboot   */ 
 sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area                      */
 sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo     

  text段向下移动  CONFIG_SYS_MALLOC_LEN 字节作为栈区域,栈向下移动 CONFIG_SYS_GBL_DATA_SIZE   字节作为全局数据结构区域            */


#ifdef CONFIG_USE_IRQ
 sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
 sub sp, r0, #12  /* leave 3 words for abort-stack    */   //得到最终的sp,设置sp

clear_bss:
 ldr r0, _bss_start  /* find start of bss segment        */  r0指向bss开始
 ldr r1, _bss_end  /* stop here                        */     r1指向bss结束
 mov r2, #0x00000000  /* clear                            */   r2=0

clbss_l:str r2, [r0]  /* clear loop...                   */  把r2内容放入r0中地址中,清零
 add r0, r0, #4                                 
 cmp r0, r1
 ble clbss_l

 ldr pc, _start_armboot                     至此堆栈已经建立,开始进入c代码,开始第二阶段

_start_armboot: .word start_armboot

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值