您的位置:首页 > 其它

U-BOOT第一阶段程序分析(1)

2014-04-27 18:46 387 查看
分析移植之前先介绍下我的软硬件环境:

开发板:JZ2440v2板

CPU :ARM920T

SOC :S3C2440

晶振freq:12MHz

NorFlash:2MB => Am29LV160DB

NandFlash:256MB => K9F2G08U0A

SDRAM:32MB X 2pieces => K4S561632H-T(U)C(16M X 16bit)

U-BOOT版本:u-boot-1.1.6.tar.bz2

我移植的uboot是基于nand启动的,所以代码的分析过程也是基于nand启动的情况,uboot一上电首先执行的是cpu/arm920t/start.s文件。下面我从该文件开始一步步按代码流程分析:

1. start.s中用到的头文件
#include <config.h>  // 等效包含#include <configs/MY_JZ2440.h>
#include <version.h> // 等效包含#include "version_autogenerated.h"
2. 加入LED灯调试宏定义,这个是我个人在移植的时候加的,在初始化串口之前你无法用printf调试,所以在uboot的第一阶段一般会用汇编点灯的手段去调试程序。
#define DEBUG_LED 0  //0表示该调试已经被我关闭了
3. 异常向量表,这个arm架构下的分布
.globl _start //声明全局标号供外部使用
系统一旦发生异常一定会进入相应的异常地址,比如上电复位时进入0x0地址,由于该地址上放置了"b reset",所以系统上电初始化的时候会进入到reset对应的标号处执行。
_start:
b      reset    		  //复位
ldr    pc, _undefined_instruction //未定义指令
ldr    pc, _software_interrupt    //软中断
ldr    pc, _prefetch_abort        //预取指中止
ldr    pc, _data_abort     	  //预取数据中止
ldr    pc, _not_used       	  //保留
ldr    pc, _irq        		  //IRQ
ldr    pc, _fiq        		  //FIQ
_undefined_instruction: .wordundefined_instruction
_software_interrupt:    .wordsoftware_interrupt
_prefetch_abort:       	.wordprefetch_abort
_data_abort:       	.worddata_abort
_not_used:       	.wordnot_used
_irq:           	.wordirq
_fiq:     		.wordfiq
/*just for match addr*/
.balignl 16,0xdeadbeef
4. 开发板上电复位后真正开始执行的代码
reset:
/*设置ARM芯片的工作模式*/
mrs r0, cpsr  	   //读cpsr
bic r0, r0,#0x1f   //清零bit[4:0]
orr r0, r0,#0xd3   //或指令,0xd3 = 11010011b
//=>设置bit[7:6]=11b,禁止FIQ和IRQ中断
//=>设置bit[4:0]=10011b,supervisor管理模式
msr cpsr, r0 	   //回写cpsr
5. 关闭看门狗(寄对看门狗寄存器写0),屏蔽所有中断,并且在这里把uboot中原来对时钟的设置先去掉,暂时无需配置直接使用默认的(板子上是使用的12M晶振)时钟频率就好了。
/* 在MY_JZ2440.h中定义了:CONFIG_MY_S3C2440 */
#if defined(CONFIG_MY_S3C2440)
#define pWTCON0x53000000
#define INTMOD    0x4A000004 //Interrupt mode register:0 = IRQ mode , 1 = FIQ mode
#define INTMSK    0x4A000008 //mask register:0=available , 1=masked
#define INTSUBMSK 0x4A00001C //mask register:0=available , 1=masked
#define CLKDIVN   0x4C000014
#endif  /* CONFIG_MY_S3C2440 */
#if defined(CONFIG_MY_S3C2440)
/*关看门狗*/
ldr  r0, =pWTCON //伪指令,加载看门狗寄存器的地址到r0
mov  r1, #0x0
str  r1, [r0] 	 //设置看门狗寄存器的值为0
/*屏蔽所有IRQ*/
mov  r1, #0xffffffff//bit[31:0]
ldr  r0, =INTMSK
str  r1, [r0]
ldr  r1, =0x7fff  //bit[14:0]
ldr  r0, =INTSUBMSK
str  r1, [r0]
#endif  /* CONFIG_MY_S3C2440 */
6. 在完成这次操作之后我加了一个LED灯的调试程序:全亮1s左右。一般只要你配置好的uboot能顺利编译出来,那么此处的LED调试输出信息一般是正常的,毕竟在这之前我们几乎什么也没有做。除非你uboot配置编译就出了问题。
//=============================>
#ifDEBUG_LED 	/*LED调试信息:0关闭1打开*/
#define  REG_GPFCON0x56000050  //GPIO控制寄存器
#define  REG_GPFDAT0x56000054  //GPIO控制数据器
#define  REG_GPFPUL0x56000058  //GPIO控制上拉器
ldr  r0, =REG_GPFCON
mov  r1, #0x00001500	//0000 0000 0000 0000 0001 0101 0000 0000
str  r1, [r0]		//设置GPF4/5/6为输出口, 位[13:8]=010101
ldr  r0, =REG_GPFDAT
mov  r1, #0x00000000	//xxxx xx[0(000)][0000]  (0亮1灭)
str  r1, [r0]
/*延时1s*/
mov  r0, #0x00100000
LHB_Delay_0:
subs r0, r0, #0x1
bne  LHB_Delay_0
#endif
//=============================>

暂时先分析到这里,敬请关注后续博文。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: