啥子叫做‘重定位’ ,<包含函数copy_code_to_sdram >is_BootFrom_Flash(void)>nand_init>
就是把bootloader本身的代码从flash复制到他的链接地址去
/*4.重定位*/
ldr sp ,=0x34000000
mov r0 , #0 %src的地址 第一个参数
ldr r1 , = _start 33f80000 %目的地址 第二个参数
ldr r2 , = __bss_start %用__直接得到这个值 %长度
sub r2,r2,,r1
b1 copy_code_to_sdram
b1 clear_bss
init.c
void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
{
/***********若是NOR启动*******只能读不能存*****************/
if(is_BootFrom_Flash(void))
{
while(i<len)
{
*dest = *src;
dest[i] = src[i];
i++;
}
}
else
{
nand_init();
nand_read(src,dest,len);
}
}
//写出判断函数
int is_BootFrom_Flash(void)
{
volatile int *p = (volatile int *)0; //*P指向0地址
int val;
val = *p;
*p = 0x12345678;
if(*p = =0x12345678)
{
//写成功nand启动了
*p= val;
return 0;
}
else
{
return 1;
}
}
void nand_init(void)
{
#define TACLS 0
#defineTWRPH0 1
#define TWRPH1 0
//设置时序
NFCONF = (TACLS<<12) | (TWRPH1<<8) | (TWRPH1<<4) ;
//使能nandFlash 控制器,初始化ECL,禁止片选
NFCONF = (1<<4)|(1<<1)|(1<<1);
}
/*1.选中*/
/*2.发出读命令 00h*/
/*3.发出地址(分5部分)*/
/*4.发出读命令30h */
/*5.判断状态*/
/*6.读数据*/
/*7.取消选中*/
void nand_read(unsigned int addr , unsigned char*buf , unsigned int len )
{
/*1.选中*/
nand_select
/*2.发出读命令 00h*/
nand_cmd(0x00);
/*3.发出地址(分5部分)*/
nand_addr(addr);
/*4.发出读命令30h */
nand_cmd(0x30);
/*5.判断状态*/
nand_wait_read()
/*6.读数据*/
nand_date();
/*7.取消选中*/
nand_deselect();}
//1.选中
void nand_select(void)
{
NFCONT & = ~(1<<1);
}
//7.取消选中
void nand_deselect(void)
{
NFCONT | = (1<<1);
}
//1.读命宁void nand_cmd(unsigned char cmd)
{
NFCMMD = cmd;
volatate int i ;
for(i = 0;i<10;i++) //三星的2440芯片hclk 只有10来个ns
}
//3.发地址
nand_addr(unsigned int addr)
{
unsigned int col = addr/2048; //列地址,若编译不过则用移位
unsigned int page = addr%2048; //页地址
NFADDR = col & 0xff;
NFADDR = (col >>8) & 0xff;
NFADDR = page &0xff ; //------------>第0页
NFADDR = (page>>8 ) & 0xff ; // -------------->第一个
NFADDR = (page >>16) & 0xff ; // =----------------->第三页
}
//5.判断状态
void nand_wait_ready(void)
{
while(!(NFSTAT& 1 )) ;
}
//6.读数据
unsigned char nand_data(void)
{
return NFDATA;
}