七、Linux裸机开发7——Nand Falsh编程
记录遇到的问题
一、关于nor flash与nand flash的启动与重定向
问题重述
当bin文件超过4k的时候,发现代码无法运行,经检查发现以下原因:
1、只进行了nor的重定向,nand flash与CPU不存在地址映射不能直接访问,因此对0地址进行操作不能访问到nand flash
a:对nand进行重定向
2、sram只有4k,而我的bin文件已经大于4k,重定向失败,实际上我就只运行了内存上拷贝过来的nand的前4k代码
a:对nand进行重定向
3、经过查看反汇编文件,发现重定向代码在4k之后,因此当内存执行完前4k代码后还不能进行重定向
a:修改Makefile文件将重定向与其相关的代码放到前面
b:实际上Makefile的顺序只是函数地址的顺序
4、不存在utboot不能自动分辨nor与nand启动
a:编写分辨nor与nand启动的代码(使用nand可读可写,nor可读不可写的特性)
1、nor flash启动与重定向
1)nor启动时是通过地址映射,CPU对应的0地址即为nor的0地址
2)nor启动时直接访问nor flash上面的代码
3)对于mini2440开发板,nor里含有烧代码的代码,因此代码通过烧录软件烧到nand里面,当nor启动的时候,CPU直接读取nor上面的代码并运行,将nand的代码拷贝到sram(内存)里面
4)因此,nor的重定向就是将0地址开始的代码拷贝到SDRAM中,并运行
5)nor只读不可写,因此,当将应用程序烧录到nor上面时,需要重定向才可写(全局变量保存在代码段中)
2、nand flash启动与重定向
1)nand flash可读可写
2)nand启动时,utboot将nand的前4k复制到sram中
3)nand与CPU不存在直接的地址映射,因此不能直接访问nand,需要通过nand控制器
4)因此,nand的重定向需要设置并访问nand的控制器将nand flash中的代码读出来,并复制到SDRAM所在的地址上
3、utboot
启动过程:
1)复位
2)判断为nor 启动还是 nand 启动
3)执行相应操作
4、完善编写代码
1)重定向代码
void copy_by_c(void)
{
/* 要从lds文件中获得 __code_start, __bss_start
* 然后从0地址把数据复制到__code_start
*/
extern int __data_start, __bss_start;
volatile unsigned int *dest = (volatile unsigned int *)&__data_start;
volatile unsigned int *end = (volatile unsigned int *)&__bss_start;
volatile unsigned int *src = (volatile unsigned int *)0;
int len;
len = ((int)&__bss_start) - ((int)&__data_start);
//如果是nor启动执行以下代码
if (isBootFromNorFlash())
{
while (dest < end)
{
*dest++ = *src++;
}
puts("is nor on\r\n");
}
//如果是nand启动执行以下代码
else
{
nand_flash_init();
nand_flash_read_datas(src, dest, len);
puts("is nand on\r\n");
}
}
2)分辨nor与nand启动
int isBootFromNorFlash(void)
{
volatile unsigned int *p = (volatile unsigned int *)0;
unsigned int val = *p;
*p = 0x12345678;
if (*p == 0x12345678)
{
/* 写成功, 对应nand启动 */
*p = val;
return 0;
}
else
{
return 1;
}
}