六、uboot 代碼流程分析---start.S
阿新 • • 發佈:2018-05-03
保護 rom 開始 sdram AS n) right can SM
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