知道程序的入口在cpu/arm920t/start.S上(现在U-boot中的该文件还保持着原有的风格) 查看该文件,知道整个程序的主要调用顺序为: cpu_init_crit-> memsetup(在board/mini2440/memsetup.S中) ->start_armboot (在common/board.c中) void start_armboot(void)进行了一系列的初始化工作,最后就进入 for (;;) { main_loop(&bd); } 主要是接受串口命令,分析并执行命令的循环中。************************************************************************************************************************************************* ** 各个相关文件的修改 (为了便于说明,代码加了行号(所有新修改的代码均有snallie字样的注释,以示区别,并在代码段的下方对应中文注释说明) *************************************************************************************************************************************************//////////////////////// cpu/arm920t/start.S的修改 1 /* 2 * armboot - Startup Code for ARM920 CPU-core 3 * 4 * Copyright (c) 2001 Marius Gr鰃er <mag@sysgo.de> 5 * Copyright (c) 2002 Alex Z黳ke <azu@sysgo.de> 6 * Copyright (c) 2002 Gary Jennejohn <gj@denx.de> 7 * 8 * See file CREDITS for list of people who contributed to this 9 * project. 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License as 13 * published by the Free Software Foundation; either version 2 of 14 * the License, or (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 24 * MA 02111-1307 USA 25 */ 26 27 28 29 #include "config.h" 30 #include "version.h" 31 32 33 /* 34 ************************************************************************* 35 * 36 * Jump vector table as in table 3.1 in [1] 37 * 38 ************************************************************************* 39 */ 40 41 42 .globl _start 43 _start: b reset 44 ldr pc, _undefined_instruction 45 ldr pc, _software_interrupt 46 ldr pc, _prefetch_abort 47 ldr pc, _data_abort 48 ldr pc, _not_used 49 ldr pc, _irq 50 ldr pc, _fiq 51 52 _undefined_instruction: .word undefined_instruction 53 _software_interrupt: .word software_interrupt 54 _prefetch_abort: .word prefetch_abort 55 _data_abort: .word data_abort 56 _not_used: .word not_used 57 _irq: .word irq 58 _fiq: .word fiq 59 60 .balignl 16,0xdeadbeef 61 62 63 /* 64 ************************************************************************* 65 * 66 * Startup Code (reset vector) 67 * 68 * do important init only if we don"t start from memory! 69 * relocate armboot to ram 70 * setup stack 71 * jump to second stage 72 * 73 ************************************************************************* 74 */ 75 76 /* 77 * CFG_MEM_END is in the board dependent config-file (configs/config_BOARD.h) 78 */ 79 _TEXT_BASE: 80 .word TEXT_BASE 81 82 .globl _armboot_start 83 _armboot_start: 84 .word _start 85 86 /* 87 * Note: armboot_end is defined by the (board-dependent) linker script 88 */ 89 .globl _armboot_end 90 _armboot_end: 91 .word armboot_end 92 93 // start of snallie 94 .globl _bss_start 95 _bss_start: 96 .word __bss_start 97 98 .globl _bss_end 99 _bss_end: 100 .word armboot_end 101 // end of snallie /* * 94~100行 为新加入的代码,定义了2个全局变量,_bss_start和_bss_end,记录未初始化段的起止地址,其中的 * __bss_start和armboot_end 是在连接脚本 board/mini2440/armboot.lds 中定义的,后面309~317行用_bss_start * 和_bss_end来进行未初始化段数据的初始清零工作。 */
102 103 /* 104 * _armboot_real_end is the first usable RAM address behind armboot 105 * and the various stacks 106 */ 107 .globl _armboot_real_end 108 _armboot_real_end: 109 .word 0x0badc0de 110 111 #ifdef CONFIG_USE_IRQ 112 /* IRQ stack memory (calculated at run-time) */ 113 .globl IRQ_STACK_START 114 IRQ_STACK_START: 115 .word 0x0badc0de 116 117 /* IRQ stack memory (calculated at run-time) */ 118 .globl FIQ_STACK_START 119 FIQ_STACK_START: 120 .word 0x0badc0de 121 #endif 122 123 124 /* 125 * the actual reset code 126 */ 127 128 reset: 129 /* 130 * set the cpu to SVC32 mode 131 */ 132 mrs r0,cpsr 133 bic r0,r0,#0x1f 134 orr r0,r0,#0xd3 135 msr cpsr,r0 136 137 /* turn off the watchdog */ 138 #if defined(CONFIG_S3C2400) 139 #define pWTCON 0x15300000 140 /* Interupt-Controller base addresses */ 141 #define INTMSK 0x14400008 142 /* clock divisor register */ 143 #define CLKDIVN 0x14800014 144 #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) // snallie /* 144行 S3C2410和S3C2440的Watchdog以及中断屏蔽寄存器的地址相同,所以加入 || defined(CONFIG_S3C2440) 的判断 */ 145 #define pWTCON 0x53000000 146 /* Interupt-Controller base addresses */ 147 #define INTMSK 0x4A000008 148 #define INTSUBMSK 0x4A00001C 149 /* clock divisor register */ 150 #define CLKDIVN 0x4C000014 151 #endif 152 153 // snallie 154 #define CLK_CTL_BASE 0x4C000000 /* tekkaman */ 155 #define MDIV_405 0x7f << 12 /* tekkaman */ 156 #define PSDIV_405 0x21 /* tekkaman */ 157 #define MDIV_200 0xa1 << 12 /* tekkaman */ 158 #define PSDIV_200 0x31 /* tekkaman */ 159 // end of snallie /* 154~158行引入tekkaman 的几个关于时钟除数因子的定义 */ 160 161 ldr r0, =pWTCON 162 mov r1, #0x0 163 str r1, [r0] 164 165 /* 166 * mask all IRQs by setting all bits in the INTMR - default 167 */ 168 mov r1, #0xffffffff 169 ldr r0, =INTMSK 170 str r1, [r0] 171 #if defined(CONFIG_S3C2410) 172 ldr r1, =0x3ff 173 ldr r0, =INTSUBMSK 174 str r1, [r0] 175 #endif 176 177 // start of snallie 178 #if defined(CONFIG_S3C2440) 179 ldr r1, =0x7ff 180 ldr r0, =INTSUBMSK 181 str r1, [r0] 182 #endif 183 // end of snallie /* * 178~183 为适应S3C2440中断屏蔽位寄存器的设置,事实上,S3C2440处理器复位后屏蔽全部的外部中断 * 168~183段的代码完全可以省略掉,为保持代码的完整行和历史风格,将其保留 */ 184 185 // start of snallie, SMDK2410 boot from NOR flash! 186 #if defined(CONFIG_S3C2410) 187 /* FCLK:HCLK:PCLK = 1:2:4 */ 188 /* default FCLK is 120 MHz ! */ 189 ldr r0, =CLKDIVN 190 mov r1, #3 191 str r1, [r0] 192 193 /* 194 * we do sys-critical inits only at reboot, 195 * not when booting from ram! 196 */ 197 #ifdef CONFIG_INIT_CRITICAL 198 bl cpu_init_crit 199 #endif 200 201 relocate: 202 /* 203 * relocate armboot to RAM 204 */ 205 adr r0, _start /* r0 <- current position of code */ 206 ldr r2, _armboot_start 207 ldr r3, _armboot_end 208 sub r2, r3, r2 /* r2 <- size of armboot */ 209 ldr r1, _TEXT_BASE /* r1 <- destination address */ 210 add r2, r0, r2 /* r2 <- source end address */ 211 212 /* 213 * r0 = source address 214 * r1 = target address 215 * r2 = source end address 216 */ 217 copy_loop: 218 ldmia r0!, {r3-r10} 219 stmia r1!, {r3-r10} 220 cmp r0, r2 221 ble copy_loop 222 223 #if 0 224 /* try doing this stuff after the relocation */ 225 ldr r0, =pWTCON 226 mov r1, #0x0 227 str r1, [r0] 228 229 /* 230 * mask all IRQs by setting all bits in the INTMR - default 231 */ 232 mov r1, #0xffffffff 233 ldr r0, =INTMR 234 str r1, [r0] 235 236 /* FCLK:HCLK:PCLK = 1:2:4 */ 237 /* default FCLK is 120 MHz ! */ 238 ldr r0, =CLKDIVN 239 mov r1, #3 240 str r1, [r0] 241 /* END stuff after relocation */ 242 #endif 243 244 /* set up the stack */ 245 ldr r0, _armboot_end 246 add r0, r0, #CONFIG_STACKSIZE 247 sub sp, r0, #12 /* leave 3 words for abort-stack */ 248 249 ldr pc, _start_armboot 250 251 _start_armboot: .word start_armboot 252 #endif 253 // end of snallie /* * 187~251 这段设置时钟和代码搬移即跳转的部分不适合MINI2440, 通过条件编译将其跳过:在 include/configs/config_mini2440.h * 中我们将取消CONFIG_S3C2410的宏定义,取而代之的是定义CONFIG_S3C2440这个宏,所以187~251将在预处理时候被视为空 */
/* * 257~323部分为新修改的代码,以适应S3C2440 ,在 include/configs/config_mini2440.h 定义了CONFIG_S3C2440这个宏, * 所以这段代码被编译 */ 254 255 // start of snallie, mini2440 boot from NAND flash 256 //#if defined(CONFIG_S3C2440) && defined(CONFIG_MINI2440) 257 #if defined(CONFIG_S3C2440) 258 /* FCLK:HCLK:PCLK = 1:4:8 */ 259 ldr r0, =CLKDIVN 260 mov r1, #5 261 str r1, [r0] 262 263 mrc p15, 0, r1, c1, c0, 0 264 orr r1, r1, #0xc0000000 265 mcr p15, 0, r1, c1, c0, 0 266 267 mov r1, #CLK_CTL_BASE 268 mov r2, #MDIV_405 /* MPLL=405MHZ */ 269 add r2, r2, #PSDIV_405 270 str r2, [r1, #0x04] /* MPLLCON tekkaman */ /* * 259~270部分为设定工作时钟频率 */ 271 272 /* 273 * we do sys-critical inits only at reboot, 274 * not when booting from ram! 275 */ 276 adr r0, _start /* r0 <- current position of code */ // snallie 277 ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ // snallie 278 cmp r0, r1 /* don"t reloc during debug */ // snallie 279 blne cpu_init_crit // snallie /* 判断代码的执行位置,以确定是否进行CPU的初始化: * 276行为伪指令,工作是取_start这个标号的运行时的地址,277行取_TEXT_BASE单元中的一个字的数据 * 278行判断二者是否相等,若是不等则跳转到cpu_init_crit,进行CPU的初始化工作。 * 说明:这四条指令主要是为了是代码可以同时适应烧写到Flash运行和下载绝对地址TEXT_BASE处运行: * (1)当烧写到Flash运行时候,这段代码的运行的起始地址为0x00000000,这时候_TEXT_BASE总是存储 * 常量TEXT_BASE(配置在board/mini2440/config.mk),比较后两者不等,表明是从Flash中启动的 * 所以要进行CPU等的初始化工作。 * (2)当代码是在下载绝对地址TEXT_BASE处运行时,_start的值和_TEXT_BASE中存放的值是相等的, * 表明是在代码测试阶段时下载运行的,所以不必进行CPU等的初始化工作。 */
280 281 /* set up the stack */ // snallie 282 ldr r0, _armboot_end // snallie 283 add r0, r0, #CONFIG_STACKSIZE // snallie 284 sub sp, r0, #12 /* leave 3 words for abort-stack */ // snallie /* * 在306行要调用C的函数 * int CopyCode2Ram(unsigned long start_addr, unsigned char *buf, int size) * 进行代码的读出工作,所以282~284设定了一段堆栈,位于代码的下方(即程序代码部分的高地址部分),参见后面的 * 内存映像图。 */
285 286 relocate: 287 /* 288 * relocate armboot to RAM 289 */ 290 adr r0, _start /* r0 <- current position of code */ 291 ldr r1, _TEXT_BASE /* r1 <- destination address */ 292 cmp r0, r1 /* test if we run from flash or RAM */ 293 beq call_start_armboot // snallie /* * 290~293行代码:在要搬移代码前,先判断代码是从Flash中开始运行的还是下载绝对地址TEXT_BASE处运行的,若是下载运行的,则 * 不必搬移,直接到call_start_armboot,否则进行代码的搬移。具体原因和对276行的注释相同。 */