背景:
AK3761D + SPI NAND
文件系统: YAFFS2
ECC方式: 硬件ECC
NAND批量烧录工具:希尔特,硕飞等等
思路: 编译所有镜像,按照分区大小及起始位置拼接,之后烧录一个完整的镜像burn.bin。
简单记录调试关键历程
问题1: 安凯自带的烧录工具burntool烧录uboot后,会写一些配置信息到nand特定位置,
修改区间就是uboot分区里面前512字节。因此实际上NAND里面的uboot程序与编译的
uboot镜像有差异。需要用NAND里面的uboot。 通过burntool回读uboot镜像, 替换编译
镜像的前512字节。
// Uboot 512 Header
uboot = fopen("SPL.bin", "rb");
if (uboot == NULL) {
printf
("\033[1m\033[45;33m 512 uboot.bin burn file not ..... \033[0m\n");
return 1;
}
fread((char *) ubootbuf, sizeof(char), 512, uboot);
for (j = 0; j < 512; j++) {
printf("0x%02X,", ubootbuf[j]);
}
问题2: 编译出来yaffs2文件系统是带OOB数据的,而普通镜像不带OOB数据。
因此我们需要把所有非文件系统镜像,以每2k自节填充64自节0XFF(根据NAND规格)
memset(inp, 0xff, burnimg[i].size);
memset(outp, 0xff, tmpsize);
fread(inp, sizeof(char), burnimg[i].size, burnimg[i].old);
/* 0x800 fix 64byte 0xff */
for (j = 0; j < burnimg[i].size - 2048; j += 2048) {
memcpy(&outp[j + 64 * j / 2048], &inp[j], 2048);
}
// uboot replace 512 header
if (burnimg[i].index == 1) {
memcpy(&outp[0], &ubootbuf[0], 512);
}
问题3: 编译出来yaffs2文件系统与实际烧片yaffs2 oob数据仍有差异,安凯烧录工具会自己跳转特定位置。
fread(outp, sizeof(char), burnimg[i].size, burnimg[i].old);
/* 0x800 replace 4byte 0xff */
for (j = 0; j < burnimg[i].size - 0x1000; j += (2048 + 64)) {
memcpy(&inp[0], &outp[2048 + j], 28);
outp[2048 + j] = 0xff;
outp[2048 + j + 1] = 0xff;
outp[2048 + j + 2] = 0xff;
outp[2048 + j + 3] = 0xff;
memcpy(&outp[2048 + j + 4], &inp[0], 28);
}
问题4:默认SDK默认uboot env dtb分区都没有做坏块预留。建议修改下,需要修改
uboot源码及env分区参数。
include/configs/anycloud_ak37d.h
先初步记录到这