标签:
u-boot2013.01 smdk2410 -->2440 启动分析_start: b start_code1.1 set the cpu to SVC32 mode
mrs r0, cpsr bic r0, r0, #0x1f orr r0, r0, #0xd3 msr cpsr, r0
# define pWTCON 0x53000000 ldr r0, =pWTCON mov r1, #0x0 str r1, [r0]
# define INTMSK 0x4A000008 /* Interrupt-Controller base addresses */ mov r1, #0xffffffff ldr r0, =INTMSK str r1, [r0]//2410 部分 2440 没有
# if defined(CONFIG_S3C2410) ldr r1, =0x3ff ldr r0, =INTSUBMSK str r1, [r0] # endif
/* FCLK:HCLK:PCLK = 1:2:4 */ /* default FCLK is 120 MHz ! */ ldr r0, =CLKDIVN mov r1, #3 str r1, [r0]1.5cpu 底层初始化
#ifndef CONFIG_SKIP_LOWLEVEL_INIT bl cpu_init_crit //在初始化内存之前没有进行时钟的设置 #endif cpu_init_crit: a.flush v4 I/D caches b.disable MMU stuff and caches c.bl lowlevel_init //底层的初始化
bl _main ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) //0x30000f80 看确定sp的值分析一节 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ sub sp, #GD_SIZE /* allocate one GD above SP */ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */==> bic sp, sp, #清低8位。
mov r8, sp /* GD is above SP */ mov r0, #0==> sp 的值为0x30000f00。这里的mov r8,sp 可以通过r8寄存器,来访问目前sp(0x30000f00) 这个地址空间
gd->mon_len = _bss_end_ofs; _bss_end_ofs:的定义 .globl _bss_end_ofs _bss_end_ofs: .word __bss_end__ - _start__bss_end__:在u-boot.lds 中进行的定义
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { hang (); } }
arch_cpu_init, /* basic arch cpu dependent setup */ mark_bootstage, board_early_init_f, timer_init, /* initialize timer */ env_init, /* initialize environment */ init_baudrate, /* initialze baudrate settings */ serial_init, /* serial communications setup */ console_init_f, /* stage 1 init of console */ display_banner, /* say that we are here */ print_cpuinfo, /* display cpu info (and speed) */ dram_init, /* configure available RAM banks */ NULL, //表示结束
int arch_cpu_init(void) __attribute__((weak, alias("__arch_cpu_init"))); int __arch_cpu_init(void) { return 0; }
memset((void *)gd, 0, sizeof(gd_t));//初始化0x30000f00 到0x30000f80之前的内存单元。 #define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */ #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 gd->ram_size = PHYS_SDRAM_1_SIZE;
/* reserve TLB table */ gd->tlb_size = 4096 * 4; addr -= gd->tlb_size;
/* * reserve memory for U-Boot code, data & bss * round down to next 4 kB limit */ addr -= gd->mon_len; addr &= ~(4096 - 1);==>addr = addr - _bss_end_ofs;
* reserve memory for malloc() arena 保留malloc 空间 */ addr_sp = addr - TOTAL_MALLOC_LEN; #define TOTAL_MALLOC_LEN (CONFIG_SYS_MALLOC_LEN + CONFIG_ENV_SIZE)==>TOTAL_MALLOC_LEN = 0x410000 (详见TOTAL_MALLOC_LE 长度分析一节)
/* * (permanently) allocate a Board Info struct * and a permanent copy of the "global" data */ addr_sp -= sizeof (bd_t); bd = (bd_t *) addr_sp; gd->bd = bd;
addr_sp -= sizeof (bd_t); //为board Info 保留一块空间
bd = (bd_t *) addr_sp; //堆addr_sp进行强制类型的转换。并复制给bd (bd 里边包含了bi_arch_number 见bd gd 结构体分析) gd->bd = bd; //将bd 赋值给gd的成员bd。 这样就可以通过gd这个全局 的寄存器变量来找到boadr info 信
addr_sp -= sizeof (gd_t); //为gd_t 保留一块空间 为后续的将低端的GD数据拷贝到高端D==>addr_sp addr_sp - sizeof (bd_t) - sizeof (gd_t) 地址做准备
#if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL) /* * If the device tree is sitting immediate above our image then we * must relocate it. If it is embedded in the data section, then it * will be relocated with other data. */ if (gd->fdt_blob) { fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32); addr_sp -= fdt_size; new_fdt = (void *)addr_sp; debug("Reserving %zu Bytes for FDT at: %08lx\n", fdt_size, addr_sp); } #endif/* setup stackpointer for exeptions */
#define PHYS_SDRAM_1 0x30000000 /* SDRAM Bank #1 */ #define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 void __dram_init_banksize(void) { gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; //0x30000000 gd->bd->bi_dram[0].size = gd->ram_size; // 在board_init_f 进行的设置 大小为0x04000000 64M } void dram_init_banksize(void) __attribute__((weak, alias("__dram_init_banksize"))); gd->relocaddr = addr; /* Start address of U-Boot in RAM */ //U-boot 在RAM的起始地址 gd->start_addr_sp = addr_sp; /* start_addr_stackpointer */ //栈指针的起始地址 gd->reloc_off = addr - _TEXT_BASE; //重定位的偏移量 即搬移后u-boot的首地址
memcpy(id, (void *)gd, sizeof(gd_t)); //将低端的gd所在的数据,拷贝到高端id处
#define GENERATED_GBL_DATA_SIZE (128) /* (sizeof(struct global_data) + 15) & ~15 */ #define GENERATED_BD_INFO_SIZE (32) /* (sizeof(struct bd_info) + 15) & ~15 */ #define GD_SIZE (128) /* sizeof(struct global_data) */ #define GD_BD (0) /* offsetof(struct global_data, bd) */ #define GD_RELOCADDR (52) /* offsetof(struct global_data, relocaddr) */ #define GD_RELOC_OFF (72) /* offsetof(struct global_data, reloc_off) */ #define GD_START_ADDR_SP (68) /* offsetof(struct global_data, start_addr_sp) */ldr sp, [r8, #GD_START_ADDR_SP] /* r8 = gd->start_addr_sp */
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ ldr r8, [r8, #GD_BD] /* r8 = gd->bd */ sub r8, r8, #GD_SIZE /* new GD is below bd */ 此时r8指向的空间为bd的首地址 adr lr, here //在重定位完成后,返回地址 ldr r0, [r8, #GD_RELOC_OFF] /* lr = gd->start_addr_sp */ [r8, #GD_RELOC_OFF] 得到重定位的偏移量 add lr, lr, r0 //在here的基础上加上重定位的偏移量 ldr r0, [r8, #GD_START_ADDR_SP] /* r0 = gd->start_addr_sp */ //void relocate_code (addr_sp, gd, addr_moni) 重定位代码的第一个参数 mov r1, r8 /* r1 = gd */ //第二个参数 ldr r2, [r8, #GD_RELOCADDR] /* r2 = gd->relocaddr */ //第三个参数,即重定位的位置跳转到重定位relocate_code 代码去
mov r4, r0 /* save addr_sp */ mov r5, r1 /* save addr of gd */ mov r6, r2 /* save addr of destination */adr r0, _start //伪指令代码adl 的分析 见https://www.douban.com/note/331036776/
copy_loop: ldmia r0!, {r9-r10} /* copy from source address [r0] */ 从r0单元中读出8个字节的数据存在r9 r10 中,同时r0 自动加8 stmia r1!, {r9-r10} /* copy to target address [r1] */ 将刚才读出的数据放入r1单元的8个 cmp r0, r2 /* until source end address [r2] */ 比较数据源地址和 目的地址的尾地址是否相同 blo copy_loop //小于则跳转 也就是数据搬移还没有结束=================从NOR FLASH 拷贝到SDRAM 完成 ===========================
/* * fix .rel.dyn relocations */ ldr r0, _TEXT_BASE /* r0 <- Text base */ 读内存指令 //r0 = 0 //代码段的基地址 sub r9, r6, r0 /* r9 <- relocation offset */ //r9 = r6 -r0 = 代码搬移的目标地址 - 代码段的基地址 = 重定位的偏移量 //r9 = 0x33f34000 - 0 = 0x33f34000 ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ //r10 = 符号表的首地址,这个地址是连接脚本中相对于链接脚本中的地址量。 //r10 = 0x0007cb24 (反汇编得到) add r10, r10, r0 /* r10 <- sym table in FLASH */ //r10 = r10 +r0 = 代码段的基地址 + 符号表的地址 = 符号表在flash 中的地址 //r10 = 0x0007cb24 + 0 = 0007cb24 ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ //r2 = rel_dyn的首地址。 这个地址是连接脚本中相对于链接脚本中的地址量。 //r2 = 0x00073b9c add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ //r2 = r2 +r0 = 在flash中rel_dyn的地址 //r2 = 0x00073b9c ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ //在flash中 rel_dyn_end d地址 // r3 = 0007cb24 fixloop: ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ //将r2单元的数据读到r0 。即rel_dyn在flash的地址 //第一次循环:r0 = [r2] = [0x00073b9c] = 0x00000020 add r0, r0, r9 /* r0 <- location to fix up in RAM */ // r0 = r0+r9 = 代码段的基地址 + 重定位的偏移量 = 在RAM中的地址 //第一次循环: r0= r0 + r9 = 0x00000020 + 0x33f34000 = 0x33f34020 ldr r1, [r2, #4] //r1 = *(r2 +4) = 取出rel_dyn + 4 单元的数据到r1中 //第一次循环: r1+= [r1 +4 ] = [0x00073b9c +4 ] = [0x00073ba0] = 00000017 and r7, r1, #0xff //第一次循环: r7 = r1 & 0xff = 00000017 cmp r7, #23 /* relative fixup? */ //第一次循环: 比较r7是否等于23 ==>等于 beq fixrel //第一次循环:跳转到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] //第一此循环:r1 = [r0] = [0x000020 ] = 000001a0 //此处的r0 为什么是0x000020 而不是 0x33f34020 //此处实际的[r0] 应当是0x33f34020.实际中 0x000020 和0x33f34020单元里边的内容值是一样的。都是取出来。然后进行修改里边的代码。 add r1, r1, r9 // 第一此循环: r1 = r1 + r9 = 0x000001a0 + 0x33f34000 = 0x33F341A0 fixnext: str r1, [r0] //第一此循环: [0x33f34020] = 0x33F341A0 add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ //第一此循环: r2 = r2 +8 = 0x00073b9c + 8 = 0x00073ba4 cmp r2, r3 // 第一此循环: 0x0x00073ba4 != 0x0007cb24 blo fixloop // 第一此循环: 小于继续跳转 到fixloop
00073b9c <__image_copy_end>: 73b9c: 00000020 andeq r0, r0, r0, lsr #32 //第一次循环 73ba0: 00000017 andeq r0, r0, r7, lsl r0 // 17 表示的是一个标号。 73ba4: 00000024 andeq r0, r0, r4, lsr #32 //第二次循环 73ba8: 00000017 andeq r0, r0, r7, lsl r0 73bac: 00000028 andeq r0, r0, r8, lsr #32 73bb0: 00000017 andeq r0, r0, r7, lsl r0 73bb4: 0000002c andeq r0, r0, ip, lsr #32
here: /* Set up final (full) environment */ bl c_runtime_cpu_setup /* we still call old routine here */ ldr r0, =__bss_start /* this is auto-relocated! */ ldr r1, =__bss_end__ /* this is auto-relocated! */ mov r2, #0x00000000 /* prepare zero to clear BSS */ clbss_l:cmp r0, r1 /* while not at end of BSS */ strlo r2, [r0] /* clear 32-bit BSS word */ addlo r0, r0, #4 /* move to next */ blo clbss_l
/* call board_init_r(gd_t *id, ulong dest_addr) */ mov r0, r8 /* gd_t */ ldr r1, [r8, #GD_RELOCADDR] /* dest_addr */ /* call board_init_r */ ldr pc, =board_init_r /* this is auto-relocated! */
7d8: e1a00008 mov r0, r8 7dc: e5981034 ldr r1, [r8, #52] ; 0x34 7e0: e59ff008 ldr pc, [pc, #8] ; 7f0 <clbss_l+0x30> pc = pc +8 +8 = 0x7f0
7f0: 000008ac andeq r0, r0, ip, lsr #17
000008ac <board_init_r>: 8ac: e5982004 ldr r2, [r8, #4] 8b0: e92d4008 push {r3, lr} 8b4: e59f30b4 ldr r3, [pc, #180] ; 970 <board_init_r+0xc4> 8b8: e3822001 orr r2, r2, #1 8bc: e5882004 str r2, [r8, #4] 8c0: e5932000 ldr r2, [r3] 8c4: e59f30a8 ldr r3, [pc, #168] ; 974 <board_init_r+0xc8> 8c8: e1a04001 mov r4, r1 8cc: e5832000 str r2, [r3] 8d0: eb0001ad bl f8c <__enable_caches> 8d4: eb01729f bl 5d358 <board_init>====board_init_r 调用第二阶段=======
12.u-boot2013.01 smdk2410 启动第一阶段分析.txt
标签:
原文地址:http://blog.csdn.net/u013377887/article/details/51915433