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的主要内容,如果未能解决你的问题,请参考以下文章

uboot启动流程

展讯平台uboot启动流程

S5PV210-uboot源码分析-第一阶段

uboot启动第一阶段详解——汇编代码部分start.S

uboot启动流程

uboot移植之start.S分析