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

本文详细解析了U-Boot的启动过程,重点介绍了第二阶段代码分析,包括CPU及外围硬件初始化、malloc空间配置、环境变量初始化等关键步骤。

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

 

1)初始化CPU及外围硬件

 

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,这个宏也是定义了的,所以可以继续看,

 

                board_init:


 

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

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

 

       init_baudrate:


       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:


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

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

 

2)配置malloc空间 


这个函数的作用是记录堆栈空间的起始地址、结束地址、当前地址。 

 

4)环境变量初始化

5)网络初始化

6)设备列表初始化

7)配置功能函数表

8)终端完全初始化

9)开中断异常向量表

10)网卡芯片初始化

11)一些后续初始化

12)main_loop详解

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值