uboot执行流程

 说明:一下的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三种可能性

你可能感兴趣的:(uboot执行流程)