首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

smdkc100之u-boot 2010.03代码的分析三

2013-01-04 
smdkc100之u-boot 2010.03代码的分析32.第二阶段代码分析(代码在lib_arm目录下的board.c里面,start_armboo

smdkc100之u-boot 2010.03代码的分析3

2.第二阶段代码分析(代码在lib_arm目录下的board.c里面,start_armboot函数)

 

1)初始化CPU及外围硬件

 smdkc100之u-boot 2010.03代码的分析三

voidstart_armboot (void)

{

       init_fnc_t **init_fnc_ptr;

       char *s;

#ifdefined(CONFIG_VFD) || defined(CONFIG_LCD)

       unsigned long addr;

#endif

 

       /* Pointer is writable since we allocateda register for it */

       gd = (gd_t*)(_armboot_start -CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));

       /* compiler optimization barrier neededfor GCC >= 3.4 */

       __asm__ __volatile__("": ::"memory");

 

       memset ((void*)gd, 0, sizeof (gd_t));

       gd->bd = (bd_t*)((char*)gd -sizeof(bd_t));

       memset (gd->bd, 0, sizeof (bd_t));

 

       gd->flags |= GD_FLG_RELOC;

 

       monitor_flash_len = _bss_start -_armboot_start;

 

       for (init_fnc_ptr = init_sequence;*init_fnc_ptr; ++init_fnc_ptr) {

              if((*init_fnc_ptr)() != 0) {

                     hang ();

              }

       }

 

解释:定义二级指针init_fnc_ptr指向一个存放函数指针的数组,init_fnc_ptr是typedef int (init_fnc_t) (void)类型,即函数类型,init_fnc_ptr可以指向一个没有参数,返回值为int型的函数指针的地址,我们看上面代码最后的for循环init_fnc_ptr = init_sequence,if中会使用(*init_fnc_ptr)()方式调用init_sequence中的函数(函数名可以看为一个地址),如果返回值不是0,则执行hang报错。gd = (gd_t*)(_armboot_start -CONFIG_SYS_MALLOC_LEN - sizeof(gd_t)); 我们知道,malloc区域、stack区域、bdinfo数据、gd_t在内存的位置是放在upper of uboot。__asm__ __volatile__("":: :"memory");这条是内嵌汇编,请查看另一篇介绍内嵌汇编的博文。

       gd->bd指针指向数据类型为bd_t的结构体,bd_t结构体记录开发板的参数,例如串口波特率、ip地址、机器类型、启动参数、环境变量位置等。

monitor_flash_len= _bss_start - _armboot_start; bss段是u-boot最后一个段,bss最终需要清零,这时候不再需要搬移,可以参考链接脚本u-boot.lds。

       下面分析for循环执行的函数:

#ifdefined(CONFIG_ARCH_CPU_INIT)

       arch_cpu_init,        /* basic arch cpudependent setup */

#endif

这里我们定义了CONFIG_ARCH_CPU_INIT,所以执行函数arch_cpu_init。跳到这里,又有一个宏,CONFIG_ARCH_CPU_INIT,这个宏也是定义了的,所以可以继续看,

 smdkc100之u-boot 2010.03代码的分析三

                board_init:

smdkc100之u-boot 2010.03代码的分析三

 

30,31行一个是记录机器类型,一个是指定向内核传参的地址。

继续分析,宏CONFIG_USE_IRQ),函数interrupt_init不执行

 

       init_baudrate:

smdkc100之u-boot 2010.03代码的分析三

       139行使用getenv_r函数在default_environment里找baudrate关键字,找到后把“=”号后面的值赋值给gd->baudrate,然后

        再放到gd->bd->bi_baudrate里面。simple_strtoul是uboot实现的字符串转UL类型。

       serial_init:什么都没做,保持默认的8位数据、无奇偶校验、1 停止位、无开始位。

       console_init_f:gd->have_console = 1就这一句话

       display_banner:串口打印uboot信息,就是uboot启动的时候我们看到的信息,这里使用的是printf,但是我们追进去后,关注的函数

       应该是serial_putc,它是真实向串口输出一个字符的函数,这个函数会递归调用,应该说自己调用自己,遇到\n结束。

       print_cpuinfo:打印CPU信息,CPU型号和速度 CPU:...

       checkboard:打印开发板信息 BOARD:...

       dram_init:

smdkc100之u-boot 2010.03代码的分析三

       记录dram的起始地址,0x30000000,size为256M(smdkc100的)

       display_dram_config:因为没有定义DEBUG,所以打印DRAM:256M

 

2)配置malloc空间 

smdkc100之u-boot 2010.03代码的分析三

这个函数的作用是记录堆栈空间的起始地址、结束地址、当前地址。smdkc100之u-boot 2010.03代码的分析三 

 

4)环境变量初始化

5)网络初始化

6)设备列表初始化

7)配置功能函数表

8)终端完全初始化

9)开中断异常向量表

10)网卡芯片初始化

11)一些后续初始化

12)main_loop详解

等有时间,会针对这些问题在新的文章中深入浅出说明上述问题


热点排行