注意:重定位时要保证编译后的二进制文件中,操作 flash 和初始化 SDRAM 的程序必须在前4K中。否则会出错。
一、判断启动flash:
int isBootFromNorFlash(void) {
volatile unsigned int *p = (volatile unsigned int *)0;
unsigned int val = *p; // 读出0地址存放的值
*p = 0x66;
if (*p == 0x66) { // 写成功, 对应nand启动
*p = val; // 回写
return 0;
}
else {
return 1;
}
}
二、重定位:
void copy2sdram(void) {
extern int __code_start, __bss_start; // 从链接脚本中获得起始结束地址
volatile unsigned int *dest = (volatile unsigned int *)&__code_start;
volatile unsigned int *end = (volatile unsigned int *)&__bss_start;
volatile unsigned int *src = (volatile unsigned int *)0;
int len = ((int)&__bss_start) - ((int)&__code_start);
if (isBootFromNorFlash()) {
while (dest < end) {
*dest++ = *src++;
}
}
else {
nand_init();
nand_read(src, dest, len);
}
}
三、清除bss段:
void clean_bss(void) {
extern int _end, __bss_start;
volatile unsigned int *start = (volatile unsigned int *)&__bss_start;
volatile unsigned int *end = (volatile unsigned int *)&_end;
while (start <= end) {
*start++ = 0;
}
}