u-boot-2009.11移植(适用于TQ2440和MINI2440)第四篇:完善目标
注意:红色标记为修改的地方 4.3修改NorFlash写入功能的代码 (1)针对EN29LV160AB芯片 具体参考:gongping11的《u-boot-2010.06移植到TQ2440过程2-nor Flash的移植》文章,网址:http://home.eeworld.com.cn/my/space-uid-67414-blogid-55044.htmlIT_114的csdn博客《u-boot-2011.03在TQ2440上的移植(3)--支持norflash启动》网址:http://www.voidcn.com/article/p-ossvrjnw-pg.html ? 为flash添加ID号,这个ID 号是一个固定的值,由于是采用了bottom boot block ,从低地址到高地址增长的形式。可知ID 号是2249。添加ID号的函数为: 打开include/flash.h文件194行增加下面两个宏定义 /*添加两种不同扇区方式的ID标号,标号在手册中可以找到*/ top boot sect 是第一个分区在最高位,bottom boot sect 是第一个分区在最低位 修改board/sunzl/sunzl2440/flash.c这个文件 //#defineMAIN_SECT_SIZE 0x10000 /* 64 KB */ #defineMAIN_SECT_SIZE 0x8000 /* 32 K Word */ ……………… ulong flash_init(void) { …………………. #elifdefined(CONFIG_AMD_LV800) ??????????????????????????? (AMD_MANUFACT &FLASH_VENDMASK) | ??????????????????????????? (AMD_ID_LV800B &FLASH_TYPEMASK); #elifdefined(CONFIG_EON_29LV160AB) ??????????????????????????? (EON_MANUFACT &FLASH_VENDMASK) |/*添加厂商*/ ??????????????????????????? (EON_ID_LV160AB_B& FLASH_TYPEMASK);/*添加芯片的ID号*/ #else #error "Unknownflash configured"? …………………. if (j <= 3) { ???????????????????????????????????? /* 1st one is 8 KB,第一分区的大小是8K字*/ ???????????????????????????????????? if (j == 0){ ?????????????????????????????????????????????? flash_info[i].start[j]= ??????????????????????????????????????????????????????? flashbase+ 0; ???????????????????????????????????? } ? ???????????????????????????????????? /* 2nd and 3rd are both 4 KB */ ???????????????????????????????????? if ((j ==1) || (j == 2)) { ?????????????????????????????????????????????? flash_info[i].start[j]= ??????????????????????????????????????????????????????? flashbase+ 0x2000 + (j - ?????????????????????????????????????????????????????????????????????????? ????? 1) * ??????????????????????????????????????????????????????? 0x1000; ???????????????????????????????????? } ? ???????????????????????????????????? /* 4th 16 KB */ ???????????????????????????????????? if (j == 3){ ?????????????????????????????????????????????? flash_info[i].start[j]= ??????????????????????????????????????????????????????? flashbase + 0x4000; ???????????????????????????????????? } ………………. void flash_print_info(flash_info_t * info) { ???????? int i; ? ???????? switch (info->flash_id &FLASH_VENDMASK) { ???????? case (AMD_MANUFACT &FLASH_VENDMASK): ?????????????????? printf ("AMD: "); ?????????????????? break; ???????? case(EON_MANUFACT & FLASH_VENDMASK): ?????????????????? printf("EON: ") ; ?????????????????? break; ???????? default: ?????????????????? printf ("Unknown Vendor"); ?????????????????? break; ???????? } ? ???????? switch (info->flash_id &FLASH_TYPEMASK) { ???????? case (AMD_ID_LV400B &FLASH_TYPEMASK): ?????????????????? printf ("1x Amd29LV400BB(4Mbit)n"); ?????????????????? break; ???????? case (AMD_ID_LV800B &FLASH_TYPEMASK): ?????????????????? printf ("1x Amd29LV800BB(8Mbit)n"); ?????????????????? break; ???????? case(EON_ID_LV160AB_B & FLASH_TYPEMASK): ?????????????????? printf ("1xEON_29LV160AB (16Mbit)n"); ?????????????????? break; ? ???????? default: ?????????????????? printf ("Unknown ChipTypen"); …………….. int flash_erase(flash_info_t * info,int s_first,int s_last) { …………………….. if ((s_first < 0)|| (s_first > s_last)) { ?????????????????? return ERR_INVAL; ???????? } ? ???????? if ((info->flash_id &FLASH_VENDMASK) != ?????????????????? /*(AMD_MANUFACT & FLASH_VENDMASK)) {*/ ???????? ???(EON_MANUFACT & FLASH_VENDMASK)) { ?????????????????? returnERR_UNKNOWN_FLASH_VENDOR; ???????? } ???????? prot = 0; (2)针对SST39VF1601芯片(芯片型号不同,移植有区别,请对应好自己板子上的芯片做相应的移植) 在虽然S3C2440 和S3C2410 对于Nor Flash 的链接都是一样的,但是SBC2410 使用的AMD 的Nor Flash 芯片,而mini2440 使用的SST 的Nor Flash。这两款芯片在写入时所使用的块大小、时序和指令代码有差别,所以必须根据芯片的数据手册进行修改。主要的差别请看数据手册的对比: SST39VF1601: Am29LV160: 除了上面的不同以外,SST39VF1601 每个SECTOR 的大小都是一样的,而 Am29LV160 的头几块比较小。需要做的修改集中在board/sunzl/sunzl2440/flash.c这个文件上,修改如下: #define CMD_READ_ARRAY????? 0x000000F0 #define CMD_UNLOCK1 ??? 0x000000AA #define CMD_UNLOCK2???? 0x00000055 #define CMD_ERASE_SETUP???? 0x00000080 //#define CMD_ERASE_CONFIRM 0x00000030 #define CMD_ERASE_CONFIRM?? 0x00000050 #define CMD_PROGRAM???? 0x000000A0 #define CMD_UNLOCK_BYPASS?? 0x00000020 ? #ifdef?CONFIG_SST_VF1601 #define MEM_FLASH_ADDR1???? (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE +(0x000005555 << 1))) #define MEM_FLASH_ADDR2???? (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE +(0x000002AAA << 1))) #else #define MEM_FLASH_ADDR1???? (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 <<1))) #define MEM_FLASH_ADDR2???? (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA <<1))) #endif ? ………….. ulong flash_init (void) { ………….. #elif defined(CONFIG_AMD_LV800) ??????????? (AMD_MANUFACT& FLASH_VENDMASK) | ??????????? (AMD_ID_LV800B& FLASH_TYPEMASK); #elif defined(CONFIG_SST_VF1601) ??????????? (SST_MANUFACT& FLASH_VENDMASK) | ??????????? (SST_ID_xF1601& FLASH_TYPEMASK); #else #error "Unknown flash configured" ………… panic ("configured too many flashbanks!n"); ??????? for (j =0; j < flash_info[i].sector_count; j++) { #ifndef CONFIG_SST_VF1601 ??????????? if (j<= 3) { ??????????????? /*1st one is 16 KB */ ??????????????? if(j == 0) { ??????????????????? flash_info[i].start[j]= ??????????????????????? flashbase+ 0; ??????????????? } ? ??????????????? /*2nd and 3rd are both 8 KB */ ??????????????? if((j == 1) || (j == 2)) { ??????????????????? flash_info[i].start[j]= ??????????????????????? flashbase+ 0x4000 + (j -1) *0x2000; ??????????????? } ? ??????????????? /*4th 32 KB */ ??????????????? if(j == 3) { ??????????????????? flash_info[i].start[j]= ??????????????????????? flashbase+ 0x8000; ??????????????? } ??????????? }else { ??????????????? flash_info[i].start[j]= ??????????????????? flashbase+ (j - 3) * MAIN_SECT_SIZE; ??????????? } #else ??????????????? flash_info[i].start[j]= ??????????????????? flashbase+ (j) * MAIN_SECT_SIZE; #endif ? ??????? } ??????? size +=flash_info[i].size; ??? } ………… void flash_print_info (flash_info_t * info) { …………… case (AMD_MANUFACT & FLASH_VENDMASK): ??????? printf("AMD: "); ??????? break; ??? case (SST_MANUFACT & FLASH_VENDMASK): ??????? printf("SST: "); ??????? break; ??? default: ??????? printf("Unknown Vendor "); ??????? break; ??? } ………… case (AMD_ID_LV800B & FLASH_TYPEMASK): ??????? printf("1x Amd29LV800BB (8Mbit)n"); ??????? break; ??? case (SST_ID_xF1601 & FLASH_TYPEMASK): ??????? printf("1x SST39VF1601 (2MB)n"); ??????? break; ? ??? default: ??????? printf("Unknown Chip Typen"); ??????? gotoDone; …………… int flash_erase (flash_info_t * info,ints_last) { //? ushortresult; ??? int iflag,cflag,prot,sect; ??? int rc =ERR_OK; //? intchip; …………… if ((s_first < 0) || (s_first > s_last)) { ??????? returnERR_INVAL; ??? } #ifdef CONFIG_SST_VF1601 ??? if((info->flash_id & FLASH_VENDMASK) != ??? ??? (SST_MANUFACT & FLASH_VENDMASK)) { ??????? returnERR_UNKNOWN_FLASH_VENDOR; ??? } #else ??? if((info->flash_id & FLASH_VENDMASK) != ??? ??? (AMD_MANUFACT & FLASH_VENDMASK)) { ??????? returnERR_UNKNOWN_FLASH_VENDOR; ??? } #endif??? ??? prot = 0; ………………. MEM_FLASH_ADDR1= CMD_UNLOCK1; ??????????? MEM_FLASH_ADDR2= CMD_UNLOCK2; ??????????? *addr= CMD_ERASE_CONFIRM; ? #if 0 ??????????? /*wait until flash is ready */ ??????????? chip= 0; …………… printf("protected!n"); ??????? } ??? } #endif ???????????????????????/* waituntil flash is ready */ ???????????????????? while(1){ ??????????????????????????? unsigned short i; ??????????????????????????? i = *((volatileunsigned short *)addr) & 0x40; ??????????????? ????????????if(i != (*((volatile unsigned short*)addr) & 0x40)) ?????????????????????????????????? continue; ??????????????????????????? if((*((volatileunsigned short *)addr)) & 0x80) ?????????????????????????????????? break; ???????????????????? } ???? ????????????????printf ("ok.n"); ? ?????????????} else {?? /* it was protected */ ???????????????????? printf("protected!n"); ?????????????} ??????} if (ctrlc ()) ??????? printf("User Interrupt!n"); ? //?????outahere: ………………. static int write_hword (flash_info_t * info,ulongdest,ushort data) { …………… ??? int cflag,iflag; //? intchip; ……….. MEM_FLASH_ADDR1 = CMD_UNLOCK1; ??? MEM_FLASH_ADDR2= CMD_UNLOCK2; //? MEM_FLASH_ADDR1= CMD_UNLOCK_BYPASS; //? *addr= CMD_PROGRAM; ??? MEM_FLASH_ADDR1= CMD_PROGRAM; ? ??? *addr = data; ? ??? /* armsimple,non interrupt dependent timer */ ??? reset_timer_masked(); #if 0 ??? /* wait untilflash is ready */ ??? chip = 0; …………. if (chip == ERR || *addr != data) ??????? rc =ERR_PROG_ERROR; #endif ? ?????????? /* wait until flash is ready */ ??????while(1){ ?????????????unsigned short i = *(volatile unsigned short *)addr & 0x40; ?????????????if(i != (*(volatile unsigned short *)addr & 0x40))?? //D6 == D6 ???????????????????? continue; ?????????????if((*(volatile unsigned short *)addr & 0x80) == (data & 0x80)){ ???????????????????? rc = ERR_OK; ???????????????????? break;???? //D7 == D7 ?????????????} ??????} if (iflag) ??????? enable_interrupts(); ? ??? if (cflag) ??????? icache_enable(); ? ??? return rc; } ? (3)针对S29AL016芯片 具体参考yuesichiu的csdn博客《S3C2440U-Boot移植--Norflash驱动支持- S29AL016》,网址http://blog.csdn.net/yuesichiu/article/details/8267015 AM29LV160B与S29AL016J的厂商id和芯片id相同,那我们就可以直接根据AM29LV160B来移植。 修改board/sunzl/sunzl2440/flash.c这个文件 一:flash_init(void) 函数中 #if defined(CONFIG_AMD_LV400) 之后?加入 ? 二:flash_print_info(flash_info_t *info)函数中 ? case (AMD_ID_LV400B&FLASH_TYPEMASK): 之后加入????
三种芯片剩下的修改都在最后include/configs/sunzl2440.h配置文件中修改 ??具体参考? u-boot-2009.11移植(适用于TQ2440和MINI2440)第五篇:修改配置文件 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |