u-boot启动流程分析

上传人:飞*** 文档编号:35820280 上传时间:2018-03-20 格式:DOC 页数:34 大小:120.68KB
返回 下载 相关 举报
u-boot启动流程分析_第1页
第1页 / 共34页
u-boot启动流程分析_第2页
第2页 / 共34页
u-boot启动流程分析_第3页
第3页 / 共34页
u-boot启动流程分析_第4页
第4页 / 共34页
u-boot启动流程分析_第5页
第5页 / 共34页
点击查看更多>>
资源描述

《u-boot启动流程分析》由会员分享,可在线阅读,更多相关《u-boot启动流程分析(34页珍藏版)》请在金锄头文库上搜索。

1、先看 board/smsk2410/u-boot.lds 这个链接脚本,可以知道目标程序的各部分链接顺序。OUTPUT_FORMAT(“elf32-littlearm“, “elf32-littlearm“, “elf32-littlearm“)/*OUTPUT_FORMAT(“elf32-arm“, “elf32-arm“, “elf32-arm“)*/OUTPUT_ARCH(arm)ENTRY(_start)SECTIONS. = 0x00000000; /*指定可执行 image 文件的全局入口点,通常这个地址都放在 ROM(flash)0x0 位置。必须使编译器知道这个地址,通常都是修

2、改此处来完成*/. = ALIGN(4);.text :cpu/arm920t/start.o (.text)*(.text). = ALIGN(4);.rodata : *(.rodata) . = ALIGN(4);.data : *(.data) . = ALIGN(4);.got : *(.got) . = .;_u_boot_cmd_start = .;.u_boot_cmd : *(.u_boot_cmd) _u_boot_cmd_end = .;. = ALIGN(4);_bss_start = .;.bss : *(.bss) _end = .;第一个要链接的是 cpu/arm

3、920t/start.o,那么 U-Boot 的入口指令一定位于这个程序中。下面详细分析一下程序跳转和函数的调用关系以及函数实现。1Stage1:cpu/arm920t/start.S这个汇编程序是 U-Boot 的入口程序,开头就是复位向量的代码。U-Boot 启动代码流程图_start: b reset /复位向量 ;设置异常向量表ldr pc, _undefined_instructionldr pc, _software_interruptldr pc, _prefetch_abortldr pc, _data_abortldr pc, _not_usedldr pc, _irq /中

4、断向量ldr pc, _fiq /中断向量/* the actual reset code */reset: /复位启动子程序/* 设置 CPU 为 SVC32 模式 */mrs r0,cpsrbic r0,r0,#0x1f ;位清除,将某些位的值置 0:r0 = r0 AND ( !0x1f)orr r0,r0,#0xd3 ;逻辑或,将 r0 与立即数进行逻辑或,放在 r0 中(第一个)msr cpsr,r0/* 关闭看门狗 */* turn off the watchdog */#if defined(CONFIG_S3C2400)# define pWTCON 0x15300000# d

5、efine INTMSK 0x14400008 /* Interupt-Controller base addresses */# define CLKDIVN 0x14800014 /* clock divisor register */#elif defined(CONFIG_S3C2410)# define pWTCON 0x53000000# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */# define INTSUBMSK 0x4A00001C# define CLKDIVN 0x4C000014 /

6、* clock divisor register */#endif#if defined(CONFIG_S3C2400) | defined(CONFIG_S3C2410)ldr r0, =pWTCONmov r1, #0x0str r1, r0/* 禁止所有中断和设置 CPU 频率 */* mask all IRQs by setting all bits in the INTMR - default*/mov r1, #0xffffffffldr r0, =INTMSKstr r1, r0# if defined(CONFIG_S3C2410)ldr r1, =0x3ffldr r0, =

7、INTSUBMSKstr r1, r0# endif/* FCLK:HCLK:PCLK = 1:2:4 */ ;FCLK 用于 CPU,HCLK 用于AHB,PCLK 用于 APB/* default FCLK is 120 MHz ! */ldr r0, =CLKDIVN ;根据硬件手册来设置 CLKDIVN 寄存器mov r1, #3 ;用户手册的推荐值str r1, r0#endif /* CONFIG_S3C2400 | CONFIG_S3C2410 */* 这些初始化代码在系统重起的时候执行,运行时热复位从 RAM 中启动不执行 */* we do sys-critical init

8、s only at reboot,* not when booting from */#ifndef CONFIG_SKIP_LOWLEVEL_INITbl cpu_init_crit ;跳转去初始化 CPU#endif;#ifdef CONFIG_INIT_CRITICAL 原文中的,估计是 1.1.16 版本的; bl cpu_init_crit;#endif/* CPU 和 RAM 两个关键的初始化子程序 */* 初始化 CPU */cpu_init_crit:/* flush v4 I/D caches 设置 CP15*/mov r0, #0mcr p15, 0, r0, c7, c7

9、, 0 /* flush v3/v4 cache */ ;使 I/D cache 失效:将寄存器 r0 的数据传送到协处理器 p15 的 c7 中。C7 寄存器位对应 cp15 中的 cache 控制寄存器mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ ;使 TLB 操作寄存器失效:将 r0 数据送到 cp15 的 c8、c7 中。C8 对应 TLB 操作寄存器/* disable MMU stuff and caches 禁止 MMU 和 caches*/mrc p15, 0, r0, c1, c0, 0 ;先把 c1 和 c0 寄存器的各位置 0(

10、r0 = 0)bic r0, r0, #0x00002300 clear bits 13, 9:8 (-V- -RS)bic r0, r0, #0x00000087 clear bits 7, 2:0 (B- -CAM) ;这里我本来有个疑问:为什么要分开设置。因为 arm 汇编要求的立即数格式所决定的orr r0, r0, #0x00000002 set bit 2(?) (A) Align ;上一条已经设置 bit1 为 0,这一条又设置为 1?orr r0, r0, #0x00001000 set bit 12 (I) I-Cachemcr p15, 0, r0, c1, c0, 0 ;

11、用上面(见下面)设定的 r0 的值设置c1?(cache 类型寄存器)和 c0(control 字寄存器),以下为 c0 的位定义;bit8: 0 = Disable System protection;bit9: 0 = Disable ROM protection;bit0: 0 = MMU disabled;bit1: 0 = Fault checking disabled 禁止纠错;bit2: 0 = Data cache disabled;bit7: 0 = Little-endian operation;bit12: 1 = Instruction cache enabled/*

12、配置内存区控制寄存器 ?有待分析,是 1.1.4 版本的* 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, lrbl lowlevel_init ;位于 board/smdk2410/lowlevel_init.S:用于完成芯片存储器的初始化,执行完成后返回mov lr, ipmov pc, lrrelocate: /* 把 U-B

13、oot 重新定位到 RAM */adr r0, _start /* r0 是代码的当前位置 */ ;adr 伪指令,汇编器自动通过当前 PC 的值算出 如果执行到_start 时 PC 的值,放到 r0 中:当此段在 flash 中执行时 r0 = _start = 0;当此段在 RAM 中执行时_start = _TEXT_BASE(在 board/smdk2410/config.mk 中指定的值为0x33F80000,即 u-boot 在把代码拷贝到 RAM 中去执行的代码段的开始)ldr r1, _TEXT_BASE /* 测试判断是从 Flash 启动,还是 RAM */ ;此句执行的

14、结果 r1 始终是 0x33FF80000,因为此值是又编译器指定的(ads 中设置,或-D 设置编译器参数)cmp r0, r1 /* 比较 r0 和 r1,调试的时候不要执行重定位 */beq stack_setup /* 如果 r0 等于 r1,跳过重定位代码 */* 准备重新定位代码 */ ;以上确定了复位启动代码是在 flash 中执行的(是系统重启,而不是软复位),就需要把代码拷贝到 RAM 中去执行,以下为计算即将拷贝的代码的长度ldr r2, _armboot_start ;前面定义了,就是_startldr r3, _bss_start ;所谓 bss 段,就是未被初始化的静

15、态变量存放的地方,这个地址是如何的出来的?根据 board/smsk2410/u-boot.lds 内容?sub r2, r3, r2 /* r2 得到 armboot 的大小 */add r2, r0, r2 /* r2 得到要复制代码的末尾地址 */copy_loop: /* 重新定位代码 */ ;开始循环拷贝启动的代码到 RAM 中ldmia r3-r10 /*从源地址r0复制 */ ;r0 指向_start(=0)stmia r3-r10 /* 复制到目的地址r1 */ ;r1 指向_TEXT_BASE(=0x33F80000)cmp r0, r2 /* 复制数据块直到源数据末尾地址r

16、2 */ble copy_loop;这里附上 u-boot 各存储区域的映射图,从网上找的,这下对于这几个地址的位置就一目了然了,对于我这种菜鸟真的是好图啊!/* 初始化堆栈等 */stack_setup:ldr r0, _TEXT_BASE /* 上面是 128 KiB 重定位的 u-boot */sub r0, r0, #CFG_MALLOC_LEN /* 向下是内存分配空间 */ sub r0, r0, #CFG_GBL_DATA_SIZE /* 然后是 bdinfo 结构体地址空间 */#ifdef CONFIG_USE_IRQsub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)#endif ;这些宏定义在/include/configs/smdk2410.h 中:#define CFG

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 商业/管理/HR > 项目/工程管理

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号