Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9529
  • 博文数量: 4
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 0
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-25 20:02
文章分类
文章存档

2013年(4)

我的朋友

分类:

2013-09-07 17:06:10

下面是接着上一篇继续分析:
/* Set stackpointer in internal RAM to call board_init_f */
call_board_init_f:
 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) /*设置调用c语言函数的堆栈并以八字节对齐*/
 bic sp, sp, #7                     /*8字节对齐*/
 ldr r0,=0x00000000                 /*设置传递给board_init_f的参数r0=0*/            
 bl board_init_f /*跳转到c语言函数中继续执行,该函数在\u-boot-2011.03\arch\arm\lib\board.c中定义*/
/*------------------------------------------------------------------------------*/
/*
 * void relocate_code (addr_sp, gd, addr_moni)
 *
 * This "function" does not return, instead it continues in RAM
 * after relocating the monitor code.
 *
 */
/*在board_init_f的最后中调用relocate_code (addr_sp, id, addr)函数*/
 
 .globl relocate_code      /*定义一个全局变量relocate_code*/
 
 /*保存传过来的参数根据arm调用标准,r0,r1,r2分别对应addr_sp,id,addr*/
relocate_code:
 mov r4, r0 /* save addr_sp */
 mov r5, r1 /* save addr of gd */
 mov r6, r2 /* save addr of destination */
 
 /* 设置堆栈*/
stack_setup:
 mov sp, r4      /*首先把r4 (传过来的第一个参数)放到sp中*/
 adr r0, _start  /*把代码段的开始地址放到r0中*/
 cmp r0, r6      /*比较r0,r6是否相等*/
 beq clear_bss   /*如果相等就不用重定位,证明已经在内存中 ,直接跳到clear _bss标号处*/
 
 /*下面的几行代码是把代码段重定位到内存中*/
 mov r1, r6        /* r1 <- scratch for copy_loop */
 ldr r3, _bss_start_ofs
 add r2, r0, r3    /* r2 <- source end address     */
copy_loop:
 ldmia r0!, {r9-r10}  /* copy from source address [r0]    */
 stmia r1!, {r9-r10}  /* copy to   target address [r1]    */
 cmp r0, r2   /* until source end address [r2]    */
 blo copy_loop
 
#ifndef CONFIG_PRELOADER
 /*
  * fix .rel.dyn relocations
  */
 ldr r0, _TEXT_BASE         /* 把_TEXT_BASE的标号地址(链接地址0x33F8000)的放入r0中*/
 sub r9, r6, r0             /* 把重定位后的偏移地址放入r9中 */
 ldr r10, _dynsym_start_ofs /* 把__dynsym_start段重定位链接地址*/
 add r10, r10, r0           /* r10 <- sym table in FLASH */
 ldr r2, _rel_dyn_start_ofs /* 把__rel_dyn_start段重定位链接地址*/
 add r2, r2, r0             /* r2 <- rel dyn start in FLASH */

 ldr r3, _rel_dyn_end_ofs   /* 把 __rel_dyn_end段重定位链接地址*/
 add r3, r3, r0             /* r3 <- rel dyn end in FLASH */
fixloop:
 ldr r0, [r2]  /* r0 <- location to fix up, IN FLASH! */
 add r0, r0, r9  /* r0 <- location to fix up in RAM */
 ldr r1, [r2, #4]
 and r7, r1, #0xff
 cmp r7, #23   /* relative fixup? */
 beq fixrel
 cmp r7, #2   /* absolute fixup? */
 beq fixabs
 /* ignore unknown type of fixup */
 b fixnext
fixabs:
 /* absolute fix: set location to (offset) symbol value */
 mov r1, r1, LSR #4  /* r1 <- symbol index in .dynsym */
 add r1, r10, r1  /* r1 <- address of symbol in table */
 ldr r1, [r1, #4]  /* r1 <- symbol value */
 add r1, r1, r9  /* r1 <- relocated sym addr */
 b fixnext
fixrel:
 /* relative fix: increase location by offset */
 ldr r1, [r0]
 add r1, r1, r9
fixnext:
 str r1, [r0]
 add r2, r2, #8  /* each rel.dyn entry is 8 bytes */
 cmp r2, r3
 blo fixloop
#endif
clear_bss:               /*清除bss段*/
#ifndef CONFIG_PRELOADER
 ldr r0, _bss_start_ofs /*bss段的开始偏移地址*/
 ldr r1, _bss_end_ofs   /*bss段的结束偏移地址*/
 mov r4, r6             /*重定位bss代码段的地址 */
 add r0, r0, r4
 add r1, r1, r4
 mov r2, #0x00000000  /* clear*/
 
/*循环清除bss段*/
clbss_l:str r2, [r0]  /* clear loop...      */
 add r0, r0, #4
 cmp r0, r1
 bne clbss_l
 
/*下面的两行代码是为AT91RM9200而设计的led显示状态*/
 bl coloured_LED_init
 bl red_LED_on
#endif
/*
 * We are done. Do not return, instead branch to second part of board
 * initialization, now running from RAM.
 */
#ifdef CONFIG_NAND_SPL
 ldr     r0, _nand_boot_ofs
 mov pc, r0
_nand_boot_ofs:
 .word nand_boot
#else
 ldr r0, _board_init_r_ofs  /*把标号为_board_init_r_ofs的地址加载进r0*/
 adr r1, _start             /*把 _start的地址加载进r1*/
 add lr, r0, r1             /*把r1,r2相加后的结果放入lr链接寄存器中*/
 add lr, lr, r9             /*把lr加上r9的结果放入lr中*/
 
/*relocate_code (addr_sp, id, addr)函数传递的后两个参数放入r0,r1, 重新传给board_init_r  (gd_t  *id, ulong dest_addr)函数*/
 mov r0, r5  /* gd_t */
 mov r1, r6  /* dest_addr */
 /* jump to it ... */
 mov pc, lr  /*跳转到函数board_init_r (gd_t *id, ulong dest_addr)中开始执行,该函数定义在\u-boot-2011.03\arch\arm\lib\board.c中*/
_board_init_r_ofs:
 .word board_init_r - _start
#endif
 
/*__rel_dyn_start,__rel_dyn_end,__dynsym_start在uboot.lds中定义*/
_rel_dyn_start_ofs:
 .word __rel_dyn_start - _start /* 计算出__rel_dyn_start的偏移地址*/
_rel_dyn_end_ofs:
 .word __rel_dyn_end - _start   /* 计算出__rel_dyn_end的偏移地址*/
_dynsym_start_ofs:
 .word __dynsym_start - _start  /* 计算出__dynsym_start的偏移地址*/
/*
 *************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************
 */

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
cpu_init_crit:
 /*
  * flush v4 I/D caches 刷新指令和数据缓存,TLB缓存表
  */
 mov r0, #0
 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
 /*
  * disable MMU stuff and caches 关闭mmu
  */
 mrc p15, 0, r0, c1, c0, 0
 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
 bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
 orr r0, r0, #0x00000002 @ set bit 2 (A) Align
 orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
 mcr p15, 0, r0, c1, c0, 0
 /*
  * before relocating, we have to setup RAM timing
  * because memory timing is board-dependend, you will
  * find a lowlevel_init.S in your board directory.
  */
 mov ip, lr
 bl lowlevel_init  /*对内存进行初始化*/
 mov lr, ip
 mov pc, lr
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
/*
 *************************************************************************
 *
 * Interrupt handling 中断处理程序
 *
 *************************************************************************
 */
@
@ IRQ stack frame.
@
#define S_FRAME_SIZE 72
#define S_OLD_R0 68
#define S_PSR  64
#define S_PC  60
#define S_LR  56
#define S_SP  52
#define S_IP  48
...................................
..................................
start.S文件就分析到此。也是uboot执行的第一阶段的代码。以后会接着对后续流程继续跟踪。
阅读(669) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~