uboot 代码流程分析---start.S
Posted kele-dad
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了uboot 代码流程分析---start.S相关的知识,希望对你有一定的参考价值。
6.1 _start 入口函数
6.1.1 vectors.S (arch\arm\lib)
从上一节可以知道,uboot 的入口函数为 _start 。此 函数定义在 vectors.S (arch\arm\lib) 中。
在此文件中,定义了异常向量表,及其操作函数。_start 开始后,直接跳入 reset 复位中执行启动。
1 /* 头文件包含,包含架构和配置相关的头文件,自动生成的 */
2 #include <config.h>
3
4 /*
5 * A macro to allow insertion of an ARM exception vector either
6 * for the non-boot0 case or by a boot0-header.
7 * 这里定义了异常向量表 ARM_VECTORS
8 */
9 /* 当异常发生的时候,由硬件机制处理器自动的跳到一个固定地址去执行相关异常处理程序,而这个固定地址就是所谓的异常向量。 */
10 .macro ARM_VECTORS
11 b reset /* 跳转到reset执行 0x00000000 复位异常*/
12 /* LDR{条件} 目的寄存器 <存储器地址> */
13 ldr pc, _undefined_instruction /* 未定义指令终止模式,当未定义指令执行时进入该模式,可用于支持硬件协处理器的软件仿真 */
14 ldr pc, _software_interrupt /* 软中断异常 */
15 ldr pc, _prefetch_abort /* 预取异常 */
16 ldr pc, _data_abort /* 数据访问终止模式,当数据或指令预取终止时进入该模式,可用于虚拟存储及存储保护 */
17 ldr pc, _not_used /* 未使用异常,多余的指令 */
18 ldr pc, _irq /* 中断模式,用于通用的中断处理 */
19 ldr pc, _fiq /* 快速中断模式,用于高速数据传输或通道处理 */
20 .endm
21
22
23 /*
24 *************************************************************************
25 *
26 * Symbol _start is referenced elsewhere, so make it global
27 *
28 *************************************************************************
29 */
30 /* 定义全局函数 _start,为 uboot 代码的起始函数 */
31 .globl _start
32
33 /*
34 *************************************************************************
35 *
36 * Vectors have their own section so linker script can map them easily
37 *
38 *************************************************************************
39 */
40
41 .section ".vectors", "ax"
42
43 /*
44 *************************************************************************
45 *
46 * Exception vectors as described in ARM reference manuals
47 *
48 * Uses indirect branch to allow reaching handlers anywhere in memory.
49 *
50 *************************************************************************
51 */
52 /* uboot 的起始位置 */
53 _start:
54 ARM_VECTORS
6.1.2 start.S (arch\arm\cpu\arm920t)
在此汇编中,主要执行 reset 函数,主要是做一些重要的硬件初始化、重定向arm启动到 ram,设置栈、跳转到第二阶段去执行启动、
1 /* 头文件包含 */ 2 #include <asm-offsets.h> 3 #include <common.h> 4 #include <config.h> 5 6 /* 7 ************************************************************************* 8 * 9 * Startup Code (called from the ARM reset exception vector) 10 * 11 * do important init only if we don‘t start from memory! 12 * relocate armboot to ram 13 * setup stack 14 * jump to second stage 15 * 16 ************************************************************************* 17 */ 18 19 .globl reset 20 21 reset: 22 /* 23 * set the cpu to SVC32 mode 24 * 将 CPU 设置为管理员(SVC)模式 25 */ 26 mrs r0, cpsr //将状态寄存器的内容传送至通用寄存器,将CPSR中的内容传送至R0 27 bic r0, r0, #0x1f //位清除指令 将R0最低5位清零,其余位不变 工作模式位清零 28 orr r0, r0, #0xd3 //工作模式位设置为“10011”(管理模式),并将中断禁止位和快中断禁止位置1 "1101 0011" 指令用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中 29 msr cpsr, r0 //将通用寄存器的内容传送至状态寄存器,将中的内容R0传送至CPSR 30 31 /* 32 * we do sys-critical inits only at reboot, 33 * not when booting from ram! 34 * 未从 ram 启动的时候,所做的CPU 关键初始化工作 35 */ 36 #ifndef CONFIG_SKIP_LOWLEVEL_INIT 37 /* CPU 关键初始化 */ 38 bl cpu_init_crit 39 #endif 40 41 bl _main /* 跳转到 _main 开始执行,进行初始化C环境 和进行第二阶段 */ 42 43 /*------------------------------------------------------------------------------*/ 44 45 .globl c_runtime_cpu_setup 46 c_runtime_cpu_setup: 47 48 mov pc, lr 49 50 /* 51 ************************************************************************* 52 * 53 * CPU_init_critical registers 54 * 55 * setup important registers 56 * setup memory timing 57 * CPU 关键初始化 58 ************************************************************************* 59 */ 60 61 62 #ifndef CONFIG_SKIP_LOWLEVEL_INIT 63 cpu_init_crit: 64 /* 65 * flush v4 I/D caches 66 * 刷新L1 cache的icache和dcache 67 */ 68 mov r0, #0 /* 置零r0通用寄存器 */ 69 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache 向c7写入0将使ICache与DCache无效 "0"表示省略opcode_2 MCR{<cond>} p15, 0, <Rd>, <CRn>, <CRm>{,<opcode_2>}*/ 70 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB MCR{条件} 协处理器编码,协处理器操作码1,源寄存器,目的寄存器1,目的寄存器2,协处理器操作码2*/ 71 72 /* 73 * disable MMU stuff and caches 74 * 关闭 MMU 及其 caches 75 */ 76 mrc p15, 0, r0, c1, c0, 0 77 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) 78 bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) 79 orr r0, r0, #0x00000002 @ set bit 1 (A) Align 80 orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache 81 mcr p15, 0, r0, c1, c0, 0 82 83 #ifndef CONFIG_SKIP_LOWLEVEL_INIT_ONLY 84 /* 85 * before relocating, we have to setup RAM timing 86 * because memory timing is board-dependend, you will 87 * find a lowlevel_init.S in your board directory. 88 */ 89 mov ip, lr /* 保存当前程序地址到 ip 寄存器 */ 90 91 bl lowlevel_init /* 执行 SDRAM 初始化 */ 92 mov lr, ip 93 #endif 94 mov pc, lr /* 返回 */ 95 #endif /* CONFIG_SKIP_LOWLEVEL_INIT */
6.1.3 内存控制器初始化
lowlevel_init.S (board\samsung\jz2440)
主要是为了初始化 SDRAM
1 #include <config.h> 2 #include <version.h> 3 4 5 /* some parameters for the board */ 6 7 /* 8 * 9 * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S 10 * 11 * Copyright (C) 2002 Samsung Electronics SW.LEE <[email protected]> 12 * 这里主要是为了初始化 SDRAM 13 */ 14 15 #define BWSCON 0x48000000 /* 总线宽度和等待控制寄存器 */ 16 17 /* BWSCON 总线宽度和等待控制寄存器 */ 18 #define DW8 (0x0) /* 数据总线宽度为 8位 */ 19 #define DW16 (0x1) /* 数据总线宽度为 16位 */ 20 #define DW32 (0x2) /* 数据总线宽度为 32位 */ 21 #define WAIT (0x1<<2) /* BANKn WAIT 状态使能 */ 22 #define UBLB (0x1<<3) /* BANKn UB/LB 使能 */ 23 24 /* 这里不设置 BANK0,BANK0(nGCS0)的数据总线应当配置为 16 位或 32 位的宽度。因为 BANK0 是作为引导 ROM 的 bank(映射到 0x0000_0000), 25 应当在第一个 ROM 访问前决定 BANK0 的总线宽度,其依赖于复位时 OM[1:0]的逻辑电平。 */ 26 /* 原理图中,SDRAM 连接在GCS6上,因此关注 BANK6 */ 27 #define B1_BWSCON (DW32) /* BANK1 设置为 32 位的宽度 */ 28 #define B2_BWSCON (DW16) /* BANK2 设置位 16 位的宽度 */ 29 #define B3_BWSCON (DW16 + WAIT + UBLB) /* BANK2 设置位 16 位的宽度,使能 WEIT 和UBLB */ 30 #define B4_BWSCON (DW16) /* BANK2 设置位 16 位的宽度 */ 31 #define B5_BWSCON (DW16) /* BANK2 设置位 16 位的宽度 */ 32 #define B6_BWSCON (DW32) /* BANK6 设置为 32 位的宽度 */ 33 #define B7_BWSCON (DW32) /* BANK7 设置为 32 位的宽度 */ 34 35 /* BANK 控制寄存器 */ 36 /* BANK0CON */ 37 #define B0_Tacs 0x0 /* 0clk */ 38 #define B0_Tcos 0x0 /* 0clk */ 39 #define B0_Tacc 0x7 /* 14clk */ 40 #define B0_Tcoh 0x0 /* 0clk */ 41 #define B0_Tah 0x0 /* 0clk */ 42 #define B0_Tacp 0x0 43 #define B0_PMC 0x0 /* normal */ 44 45 /* BANK1CON */ 46 #define B1_Tacs 0x0 /* 0clk */ 47 #define B1_Tcos 0x0 /* 0clk */ 48 #define B1_Tacc 0x7 /* 14clk */ 49 #define B1_Tcoh 0x0 /* 0clk */ 50 #define B1_Tah 0x0 /* 0clk */ 51 #define B1_Tacp 0x0 52 #define B1_PMC 0x0 53 54 #define B2_Tacs 0x0 55 #define B2_Tcos 0x0 56 #define B2_Tacc 0x7 57 #define B2_Tcoh 0x0 58 #define B2_Tah 0x0 59 #define B2_Tacp 0x0 60 #define B2_PMC 0x0 61 62 #define B3_Tacs 0x0 /* 0clk */ 63 #define B3_Tcos 0x3 /* 4clk */ 64 #define B3_Tacc 0x7 /* 14clk */ 65 #define B3_Tcoh 0x1 /* 1clk */ 66 #define B3_Tah 0x0 /* 0clk */ 67 #define B3_Tacp 0x3 /* 6clk */ 68 #define B3_PMC 0x0 /* normal */ 69 70 #define B4_Tacs 0x0 /* 0clk */ 71 #define B4_Tcos 0x0 /* 0clk */ 72 #define B4_Tacc 0x7 /* 14clk */ 73 #define B4_Tcoh 0x0 /* 0clk */ 74 #define B4_Tah 0x0 /* 0clk */ 75 #define B4_Tacp 0x0 76 #define B4_PMC 0x0 /* normal */ 77 78 #define B5_Tacs 0x0 /* 0clk */ 79 #define B5_Tcos 0x0 /* 0clk */ 80 #define B5_Tacc 0x7 /* 14clk */ 81 #define B5_Tcoh 0x0 /* 0clk */ 82 #define B5_Tah 0x0 /* 0clk */ 83 #define B5_Tacp 0x0 84 #define B5_PMC 0x0 /* normal */ 85 86 /* BANK6 SDRAM配置 */ 87 #define B6_MT 0x3 /* 配置BANK6的存器类型为 SDRAM */ 88 #define B6_Trcd 0x1 /* RAS 到 CAS 的延迟为 3 个时钟 */ 89 #define B6_SCAN 0x1 /* 列地址数为 9bit */ 90 91 #define B7_MT 0x3 /* SDRAM */ 92 #define B7_Trcd 0x1 /* 3clk */ 93 #define B7_SCAN 0x1 /* 9bit */ 94 95 /* REFRESH parameter */ 96 #define REFEN 0x1 /* Refresh enable */ 97 #define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */ 98 #define Trp 0x0 /* 2clk */ 99 #define Trc 0x3 /* 7clk */ 100 #define Tchr 0x2 /* 3clk */ 101 #define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */ 102 /**************************************/ 103 104 .globl lowlevel_init 105 lowlevel_init: 106 /* memory control configuration */ 107 /* make r0 relative the current location so that it */ 108 /* reads SMRDATA out of FLASH rather than memory ! */ 109 ldr r0, =SMRDATA 110 ldr r1, =CONFIG_SYS_TEXT_BASE 111 sub r0, r0, r1 /* 计算内存控制器的偏移值 */ 112 ldr r1, =BWSCON /* Bus Width Status Controller */ 113 add r2, r0, #13*4 /* 将SMRDATA这一块地址赋值给r2中 */ 114 /* 此处遍历赋值表 */ 115 0: 116 ldr r3, [r0], #4 117 str r3, [r1], #4 118 cmp r2, r0 119 bne 0b 120 121 /* everything is fine now */ 122 mov pc, lr 123 124 .ltorg 125 /* the literal pools origin */ 126 127 /* 存储器控制器寄存器赋值表 */ 128 SMRDATA: 129 .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) 130 .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) 131 .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) 132 .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) 133 .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) 134 .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) 135 .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) 136 .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) 137 .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) 138 .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) 139 .word 0x32 140 .word 0x30 141 .word 0x30
以上是关于uboot 代码流程分析---start.S的主要内容,如果未能解决你的问题,请参考以下文章