1.初始化
关看门狗
初始化时钟
初始化SDRAM
2.把程序从Nand flash 拷贝到 SDAM
3.设置SP,sp指向某块内存(因为要调用c函数,就要使用栈)
4.c函数就是读出内核,启动内核
1.起始位置
2.跳转到reset
3.关闭看门狗
4.关中断
5.
6.cpu init
关MMU,
初始化lowlevel_init(初始化存储控制器),
7.设置栈
栈
设置好栈就可以调用c函数
clock_init()
把uboot从falsh读到RAM中去
清bss段
uboot第一阶段
1.设置svc(超级用户)模式
2.关闭看门狗
3.屏蔽中断
4.初始化SDRM
5.设置栈
6.时钟初始化
7.将uboot代码从flash拷贝到SDARM中去
8.清bss段(BSS(Block Started by Symbol)通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域。特点是:可读写的,在程序执行之前BSS段会自动清0。所以,未初始的全局变量在程序执行之前已经成0了。)
9.调用C语言接口_start_armboot
拷贝代码到ram的函数
#if 1
bl CopyCode2Ram /* r0: source, r1: dest, r2: size */
#else
add r2, r0, r2 /* r2 <- source end address */
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
#endif
int CopyCode2Ram(unsigned long start_addr, unsigned char *buf, int size)
{
unsigned int *pdwDest;
unsigned int *pdwSrc;
int i;
if (bBootFrmNORFlash())//判断是从nand启动的还是从nor启动的,如果条件成立,表示是从nor启动的
{
pdwDest = (unsigned int *)buf;
pdwSrc = (unsigned int *)start_addr;
/* 从 NOR Flash启动 */
for (i = 0; i < size / 4; i++)//4字节的写入,所以需要size / 4 by andy
{
pdwDest[i] = pdwSrc[i];//norfalsh可以在配置完内存管理单元后,读数据可以像内存一样操作
}
return 0;
}
else
{
/* 初始化NAND Flash */
nand_init_ll();
/* 从 NAND Flash启动 */
nand_read_ll_lp(buf, start_addr, (size + NAND_BLOCK_MASK_LP)&~(NAND_BLOCK_MASK_LP));
return 0;
}
}
//判断是否从0地址启动
int bBootFrmNORFlash(void)
{
volatile unsigned int *pdw = (volatile unsigned int *)0;
unsigned int dwVal;
/*
* 无论是从NOR Flash还是从NAND Flash启动,
* 地址0处为指令"b Reset", 机器码为0xEA00000B,
* 对于从NAND Flash启动的情况,其开始4KB的代码会复制到CPU内部4K内存中,
* 对于从NOR Flash启动的情况,NOR Flash的开始地址即为0。
* 对于NOR Flash,必须通过一定的命令序列才能写数据,
* 所以可以根据这点差别来分辨是从NAND Flash还是NOR Flash启动:
* 向地址0写入一个数据,然后读出来,如果没有改变的话就是NOR Flash
*/
dwVal = *pdw;
*pdw = 0x12345678;
if (*pdw != 0x12345678)
{
return 1;//从nor启动
}
else
{
*pdw = dwVal;//复原原先0地址处的数据
return 0;//从nand启动
}
}