TQ2440 学习一 启动代码的解释

来源:互联网 发布:51talk和vipkid 知乎 编辑:程序博客网 时间:2024/04/30 16:19

下面分析cpu/arm920t/start.S文件,分析之前请先阅读一下/board/EmbedSky/u-boot.lds文件,了解输出文件的格式,代码段,数据段,bss段,u_boot_cmd命令段的地址是怎么划分的,从这里我们看出第一个运行的函数才是cpu/arm920t/start.S

start.S所完成的任务(按顺序写):

  初始化中断向量表->初始化一些全局变量->设置cpu进入管理模式,关闭中断,32位arm指令集->关闭看门狗,一防止cpu不断重启->关闭中断和子中断->关闭I/D cache ->关闭MMU->初始化存储控制器,设置存储控制器的13个寄存器地址->初始化栈(在调用c函数之前一定要初始化相应栈)->clock_init(系统时钟初始化)(board/embedsky/boot_init.c下的clock_init函数)设置fclk=400MHZ,FCLK:HCLK:PCLK=1:4:8这样cpu的工作频率就可以达到400Mhz了,每秒4亿条arm指令哟!->重定位uboot到sdram中->初始化bss段->start_armboot;到这里bootloader第一阶段的任务完成,跳到stage2的c语言代码处start_armboot:

start_armboot()函数定义在:lib_arm/board.c文件中,我们根据TQ2440的uboot源码来进行分析:

首先是初始化全局数据区gd,初始化为0,里面的结构体指针内容并没有初始化,然后调用init_sequence[]初始化数组,这个数组可是大有文章,需要仔细看看哟,这也是stage2中主要完成的功能之一,然后就是初始化nor flash,环境变量初始化,网卡初始化,设备的初始化,时能异常,usb初始化,最后跳到main_loop()函数中,

        main_loop()函数定义在common/main.c文件中,函数的开始,也是一大堆的初始化,其中重要的是run_command("menu",0)和run_command("boot_zImage",0),这两个函数分别对应,当我们启动时是进入下载模式,还是进入启动模式;

        在这里我们看到,uboot对linux kernel的启动也是通过uboot命令来实现的,然后我们查看boot_zImage命令实现什么操作;

我们在lib_arm/boot_zImage.c文件中可以看到boot_zImage命令定义:U_BOOT_CMD(boot_zImage,3,0,do_boot_zImage,"string1","as"),这个命令的执行函数是do_boot_zImage,do_boot_zImage也是在该文件中定义:如果我们的屏不是10寸屏,则执行boot_zImage(0x200000,0x300000),在这个函数里调用call_linux(0,mach_type,to),分别代表r0,r1=机器ID,内核地址;这里,只是正常启动模式时的流程分析,如果进入下载模式,就要分析另一条U_BOOT_CMD命令了;

到此,整个uboot流程分析完毕;