下面的start_armboot中,去掉一些被预编译包含的代码。如我的板子上没有LCD、VFD、NOR FLASH等,
所以在分析时就直接将它们略过了。
314 /* Pointer is writable since we allocated a register for it */
315 gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
316 /* compiler optimization barrier needed for GCC >= 3.4 */
317 __asm__ __volatile__("": : :"memory");
318
319 memset ((void*)gd, 0, sizeof (gd_t));
320 gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
321 memset (gd->bd, 0, sizeof (bd_t));
322
323 monitor_flash_len = _bss_start - _armboot_start;
|
关于gd_t和bd_t结构体,见
http://blog.chinaunix.net/u3/93566/showart_2097710.html
_armboot_start 定义代码段的起始地址,定义在start.S中
_armboot_start:
.word _start
可见其中保存的是第一条指令_start的地址。编译的时候指定了TEXT_BASE为0x33f80000,所以
_armboot_start中的值也为0x33f80000。
CONFIG_SYS_MALLOC_LEN -> include/configs/smdk2410.h
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128*1024)
#define CONFIG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
=> CONFIG_SYS_MALLOC_LEN = 0x10000 + 128 * 1024 = 0x10000 + 0x20000 = 0x30000
即 192k
sizeof(gd_t) = 9 * 4 = 36 = 0x24 (这里没有VDF和LCD)
上面这些代码就是定义gd 和 bd的位置,并将这两个结构体先清零,大致的布局如下
+---------+ -> 0x34000000 _armboot_start
| 512k |
+---------+ -> 0x33f80000
| 192k | CONFIG_SYS_MALLOC_LEN = CONFIG_ENV_SIZE(0x1000) + 128*1024 = 0x30000
+---------+ -> 0x33f50000
| | sizeof(gd_t) = 0x24 uboot配置信息
+---------+ -> gd
| | sizeof(bd_t) 板级相关信息
+---------+ -> bd
| |
+---------+
上面317行 __asm__ __volatile__("": : :"memory"); 是内嵌汇编的知识
,* __asm__用于指示编译器在此插入汇编语句
__volatile__用于告诉编译器,严禁将此处的汇编语句与其它的语句重组合优化。即:原原本本按原来的样子处理这这里的汇编。
* memory强制gcc编译器假设RAM所有内存单元均被汇编指令修改,这样cpu中的registers和cache中已缓存的内存单元中的数据将作
废。cpu将不得不在需要的时候重新读取内存中的数据。这就阻止了cpu又将registers,cache中的数据用于去优化指令,而避免去访问内存。
* "":::表示这是个空指令。barrier()不用在此插入一条串行化汇编指令。在后文将讨论什么叫串行化指令。
* __asm__,__volatile__,memory在前面已经解释
323行,计算代码段的长度monitor_flash_len 是指代码段的长度
在cpu/arm920t/u-boot.lds中定义了程序链接后的各段地址
+-----------+ -> _end
| .bss (ZI) |
+-----------+-> __bss_start
| .data(RW) |
+-----------+
| .text(RO) |
+-----------+ -> _armboot_start 0x33f80000
325 for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
326 if ((*init_fnc_ptr)() != 0) {
327 hang ();
328 }
329 }
|
见
http://blog.chinaunix.net/u3/93566/showart_2097507.html 366 /* armboot_start is defined in the board-specific linker script */
367 mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);
368
369 #if defined(CONFIG_CMD_NAND)
370 puts ("NAND: ");
371 nand_init(); /* go init the NAND */
372 #endif
|
367行,将整个192k的heap区清零
371行,初始化nand flash,要在configs/下的配置头文件里定义CONFIG_CMD_NADN,开启nand相关的
操作。 nand_init()在dreiver/mtd/nand/nand.c中。
383 /* initialize environment */
384 env_relocate ();
395 /* IP Address */
396 gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
397
398 /* MAC Address */
399 {
400 int i;
401 ulong reg;
402 char *s, *e;
403 char tmp[64];
404
405 i = getenv_r ("ethaddr", tmp, sizeof (tmp));
406 s = (i > 0) ? tmp : NULL;
407
408 for (reg = 0; reg < 6; ++reg) {
409 gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
410 if (s)
411 s = (*e) ? e + 1 : e;
412 }
413
424 }
426 devices_init (); /* get the devices list going. */
432 jumptable_init ();
433
434 console_init_r (); /* fully init console as a device */
440
441 /* enable exceptions */
442 enable_interrupts ();
443
444 /* Perform network card initialisation if necessary */
445
451
452 #ifdef CONFIG_DRIVER_CS8900
453 cs8900_get_enetaddr (gd->bd->bi_enetaddr);
454 #endif
455
456 #if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)
457 if (getenv ("ethaddr")) {
458 smc_set_mac_addr(gd->bd->bi_enetaddr);
459 }
460 #endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */
461
462 /* Initialize from environment */
463 if ((s = getenv ("loadaddr")) != NULL) {
464 load_addr = simple_strtoul (s, NULL, 16);
465 }
查找环境变量中是否有loadaddr这一项,有的话,就将它的值写入load_addr中 load_addr是加载地址,这在bootm的分析中仍会见到。它表示kernel image 将被 uboot加载到内存的地址。
466 #if defined(CONFIG_CMD_NET)
467 if ((s = getenv ("bootfile")) != NULL) {
468 copy_filename (BootFile, s, sizeof (BootFile));
469 }
470 #endif
471
485 /* main_loop() can return to retry autoboot, if so just run it again. */
486 for (;;) {
487 main_loop ();
488 }
489
490 /* NOTREACHED - no way out of command loop except booting */
491 }
|
阅读(4756) | 评论(0) | 转发(3) |