分析移植之前先介绍下我的软硬件环境:
开发板: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 //=============================>
暂时先分析到这里,敬请关注后续博文。
U-BOOT第一阶段程序分析(1),码迷,mamicode.com
时间: 2024-11-09 00:47:24