您的位置:首页 > 其它

移植u-boot-2012.04----支持NORFlash启动

2017-11-03 16:09 323 查看
上节修改支持nand启动,串口打印的信息

WARNING: Caches not enabled
Flash: *** failed ***
### ERROR ### Please RESET the board ###


arch\arm\lib\board.c中搜索 Flash

#if !defined(CONFIG_SYS_NO_FLASH)
puts("Flash: ");

flash_size = flash_init();
if (flash_size > 0) {
# ifdef CONFIG_SYS_FLASH_CHECKSUM
char *s = getenv("flashchecksum");

print_size(flash_size, "");
/*
* Compute and print flash CRC if flashchecksum is set to 'y'
*
* NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
*/
if (s && (*s == 'y')) {
printf("  CRC: %08X", crc32(0,
(const unsigned char *) CONFIG_SYS_FLASH_BASE,
flash_size));
}
putc('\n');
# else  /* !CONFIG_SYS_FLASH_CHECKSUM */
print_size(flash_size, "\n");
# endif /* CONFIG_SYS_FLASH_CHECKSUM */
} else {
puts(failed);
hang();
}

void hang(void)
{
puts("### ERROR ### Please RESET the board ###\n");
for (;;);
}


这就是串口打印的信息 :如果没有定义CONFIG_SYS_NO_FLASH,就输出 Flash

接着if (flash_size > 0),这里很明显没有设置,打印failed

hang()函数执行 ,打印### ERROR ### Please RESET the board ###

进入死循环…..

修改如下:

puts("0 KB\n\r");
//puts(failed);
//hang();


修改的目的是为了程序不进入hand()死循环,后面的nand初始化程序可以执行

#if defined(CONFIG_CMD_NAND)
puts("NAND:  ");
nand_init();        /* go init the NAND */
#endif


flash_size = flash_init();去flash_init的定义查看,检测flash的函数

if (!flash_detect_legacy(cfi_flash_bank_addr(i), i))
flash_get_size(cfi_flash_bank_addr(i), i);
size += flash_info[i].size;


linux下搜索 cfi_flash_bank_addr

grep  "cfi_flash_bank_addr"  *  -nR


结果


drivers/mtd/cfi_flash.c:100:static phys_addr_t __cfi_flash_bank_addr(int i)


cfi_flash_bank_addr 的定义

static phys_addr_t __cfi_flash_bank_addr(int i)
{
return ((phys_addr_t [])CONFIG_SYS_FLASH_BANKS_LIST)[i];
}




flash_detect_legacy的定义

#ifdef CONFIG_FLASH_CFI_LEGACY
static void flash_read_jedec_ids (flash_info_t * info)
...
#else
static inline int flash_detect_legacy(phys_addr_t base, int banknum)
{
return 0; /* use CFI */
}


如果定义了CONFIG_FLASH_CFI_LEGACY,执行flash_read_jedec_ids,否则

flash_detect_legacy。

这里CONFIG_FLASH_CFI_LEGACY是有定义的,旧的查询方法得不到flash的大小。

看看新的查询方法:flash_get_size

flash_get_size
debug
_DEBUG
#define _DEBUG  1


打印调试信息,drivers\mtd\cfi_flash.c的定义中加

#define  _DEBUG  1
#define  DEBUG   1


cfi_flash.c拷贝到linux,编译烧写到norflash

串口结果:

Flash: fwc addr (null) cmd f0 00f0 16bit x 16 bit
fwc addr 0000aaaa cmd aa 00aa 16bit x 16 bit
fwc addr 00005554 cmd 55 0055 16bit x 16 bit
fwc addr 0000aaaa cmd 90 0090 16bit x 16 bit
fwc addr (null) cmd f0 00f0 16bit x 16 bit
JEDEC PROBE: ID c2 2249 0
fwc addr (null) cmd ff 00ff 16bit x 16 bit
fwc addr (null) cmd 90 0090 16bit x 16 bit
fwc addr (null) cmd ff 00ff 16bit x 16 bit
JEDEC PROBE: ID 13 ea00 0
0 KB
*** Warning - bad CRC, using default environment


mx29lv160db norflash芯片手册

02



03



根据打印的信息,厂家ID设备ID都已经读到了。

接着分析:cfi_flash.c



在drivers\mtd\jedec_flash.c 的endif后添加一个table的项

/*JZ2440使用MT29LV160DB*/
{
.mfr_id     = (u16)MX_MANUFACT,/*厂家ID*/
.dev_id     = 0x2249,/*设备ID*/
.name       = " MXIC  MT29LV160DB",
.uaddr      = {/*NOR Flash 解锁地址*/
[1] = MTD_UADDR_0x0555_0x02AA /* x16 */
},
.DevSize    = SIZE_2MiB,/*总大小*/
.CmdSet     = CFI_CMDSET_AMD_LEGACY,
.NumEraseRegions= 4,/*图4 芯片手册上块的种类*/
.regions    = {/**/
ERASEINFO(16*1024, 1),
ERASEINFO(8*1024, 2),
ERASEINFO(32*1024, 1),
ERASEINFO(64*1024, 31),
}
}


drivers\mtd\jedec_flash.c 移到linux下编译烧写



too many flash sectors!修改: source insight 搜 too many flash sectors

drivers/mtd/cfi_flash.c下:

if (sect_cnt >= CONFIG_SYS_MAX_FLASH_SECT) {
printf("ERROR: too many flash sectors\n");
break;
}


#define CONFIG_SYS_MAX_FLASH_SECT (19)

修改:

#define CONFIG_SYS_MAX_FLASH_SECT (128)

去除

drivers\mtd\cfi_flash.c的定义中的

#define  _DEBUG   1
#define  DEBUG   1


结果:



测试:

protect off all

mw.b 30000000  12
erase 80000 8ffff
cp.b  30000000  80000  10000

md.b 30000000
cmp.b 30000000 80000  10000


结果:



protect off all

erase 80000 8ffff
cp.b  32000000  80000  10000

md.b 32000000
cmp.b 32000000 80000  10000


结果:



分析 地址30000000和32000000的区别

可能和内存gd_t的栈设置有关。start.s中一开始设置了栈

ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)/*sp =0x30000f80*/
bic    sp, sp, #7 /* 8-byte alignment for ABI compliance */


后面没有再次设置栈 去board_init_f的定义中搜索栈地址

addr_sp += 128;   /* leave 32 words for abort-stack   */
gd->irq_sp = addr_sp;

gd->start_addr_sp = addr_sp;


在board.c的unsigned int board_init_f(ulong bootflag)中添加

extern ulong   base_sp; //声明
base_sp=addr_sp;  //使用


start.s中第二阶段添加

/*定义*/
.globl base_sp
base_sp:
.long 0

ldr sp,base_sp  /*从新设置栈*/


board.c start.s 移动到linux下烧写 测试

protect off all
erase 80000 8ffff
cp.b  30000000 80000  10000  //拷到80000 拷贝64k
cmp.b 30000000 80000  10000


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: