说明:一下的uboot分析是基于AM335x的devkit8600板子而说明的
reset:
bl save_boot_params //保存当前的启动模式进变量里(可以是nand启动,tf启动等)
/*
139 * set the cpu to SVC32 mode
140 */
141 mrs r0, cpsr
142 bic r0, r0, #0x1f
143 orr r0, r0, #0xd3
144 msr cpsr,r0
176 call_board_init_f:
177 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
178 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
179 ldr r0,=0x00000000
180 bl board_init_f
函数board_init_f在arch/arm/lib/board.c里定义,如下:
void board_init_f(ulong bootflag)
263 {
264 bd_t *bd;
265 init_fnc_t **init_fnc_ptr;
266 gd_t *id;
267 ulong addr, addr_sp;
268
269 /* Pointer is writable since we allocated a register for it */
270 gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);
271 /* compiler optimization barrier needed for GCC >= 3.4 */
272 __asm__ __volatile__("": : :"memory");
273
274 memset((void *)gd, 0, sizeof(gd_t));
275
276 gd->mon_len = _bss_end_ofs;
277
278 for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
279 if ((*init_fnc_ptr)() != 0) {
280 hang ();
281 }
282 }
283
284 debug("monitor len: %08lX\n", gd->mon_len);
其中init_fnc_ptr函数指针数组如下:
233 init_fnc_t *init_sequence[] = {
234 #if defined(CONFIG_ARCH_CPU_INIT)
235 arch_cpu_init, /* basic arch cpu dependent setup */ //为空函数
236 #endif
237 #if defined(CONFIG_BOARD_EARLY_INIT_F)
238 board_early_init_f, //空
239 #endif
240 timer_init, /* initialize timer */ @/arch/arm/cpu/armv7/omap-common/timer.c
241 #ifdef CONFIG_FSL_ESDHC
242 get_clocks,//空
243 #endif
244 env_init, /* initialize environment */ //在common下对应的启动方式的.c文件里
(该函数是
74 /* use default */
75 gd->env_addr = (ulong)&default_environment[0];
76 gd->env_valid = 1;
)
245 init_baudrate, /* initialze baudrate settings *///初始化gd->baudrate=115200
246 serial_init, /* serial communications setup */ //串口驱动设置
247 console_init_f, /* stage 1 init of console *///
248 display_banner, /* say that we are here */
249 #if defined(CONFIG_DISPLAY_CPUINFO)
250 print_cpuinfo, /* display cpu info (and speed) */
251 #endif
252 #if defined(CONFIG_DISPLAY_BOARDINFO)
253 checkboard, /* display board info */
254 #endif
255 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
256 init_func_i2c,
257 #endif
258 dram_init, /* configure available RAM banks */
259 NULL,
260 };
int getenv_f(const char *name, char *buf, unsigned len)//9 * Look up variable from environment for restricted C runtime env. 查找环境变量*name的值保存在*buf里,失败返回-1
512 {
513 int i, nxt;
514
515 for (i = 0; env_get_char(i) != '\0'; i = nxt+1) {
516 int val, n;
517
518 for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) {
519 if (nxt >= CONFIG_ENV_SIZE)
520 return -1;
521 }
522
523 val = envmatch((uchar *)name, i);
524 if (val < 0)
525 continue;
526
527 /* found; copy out */
528 for (n = 0; n < len; ++n, ++buf) {
529 if ((*buf = env_get_char(val++)) == '\0')
530 return n;
531 }
532
533 if (n)
534 *--buf = '\0';
535
536 printf("env_buf [%d bytes] too small for value of \"%s\"\n",
537 len, name);
538
539 return n;
540 }
541 return -1;
542 }
getenv():
函数说明:getenv()用来取得参数envvar环境变量的内容。参数envvar为环境变量的名称,如果该变量存在则会返回指向该内容的指针。环境变量的格式为envvar=value。getenv函数的返回值存储在一个全局二维数组里,当你再次使用getenv函数时不用担心会覆盖上次的调用结果。
返回值: 执行成功则返回指向该内容的指针,找不到符合的环境变量名称则返回NULL。如果变量存在但无关联值,它将运行成功并返回一个空字符串,即该字符的第一个字节是null。
152 uchar env_get_char (int index)
153 {
154 uchar c;
155
156 /* if relocated to RAM */
157 if (gd->flags & GD_FLG_RELOC)
158 c = env_get_char_memory(index);
159 else
160 c = env_get_char_init(index);
161
162 return (c);
163 }
134 static uchar env_get_char_init (int index)
135 {
136 uchar c;
137
138 /* if crc was bad, use the default environment */
139 if (gd->env_valid )//true
140 c = env_get_char_spec(index);
141 else
142 c = default_environment[index];
143
144 return (c);
145 }
7 uchar env_get_char_spec(int index)
68 {
69 return *((uchar *)(gd->env_addr + index));
70 }
环境变量数组:
const uchar default_environment[] = { 在common/env_common.c里,注意该数组所有的都是字符串,没有数字,环境变量的值在include/configs/devkit8600.h里定义
51 #ifdef CONFIG_BOOTARGS
52 "bootargs=" CONFIG_BOOTARGS "\0" //CONFIG_BOOTARGS 这是环境变量的值
53 #endif
54 #ifdef CONFIG_BOOTCOMMAND
55 "bootcmd=" CONFIG_BOOTCOMMAND "\0"
66 #if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
67 "baudrate=" MK_STR(CONFIG_BAUDRATE) "\0" //MK_STR(x)将数字量转为字符串
68 #endif
129 "\0"
130 };
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)//将字符串数字,eg“0xa10”,“152”,"0741"转为数字ulong数字,其中base有10,16,8三种可能性