/******************************************************************************* *函数名称: load_in_many_blks *函数原型:int32 load_in_many_blks( __u32 start_blk, __u32 last_blk_num, void *buf, * __u32 size, __u32 blk_size, __u32 *blks ) *函数功能: 从nand flash的某一块start_blk开始,载入file_length长度的内容到内存中。 *入口参数: start_blk 待访问的nand flash起始块号 * last_blk_num 最后一个块的块号,用来限制访问范围 * buf 内存缓冲区的起始地址 * size 文件尺寸 * blk_size 待访问的nand flash的块大小 * blks 所占据的块数,包括坏块 *返 回 值: ADV_NF_OK 操作成功 * ADV_NF_OVERTIME_ERR 操作超时 * ADV_NF_LACK_BLKS 块数不足 *备 注: 1. 本函数只载入,不校验 *******************************************************************************/ __s32 load_in_many_blks( __u32 start_blk, __u32 last_blk_num, void *buf, __u32 size, __u32 blk_size, __u32 *blks ) { __u32 buf_base; __u32 buf_off; __u32 size_loaded; __u32 cur_blk_base; __u32 rest_size; __u32 blk_num; __u32 blk_size_load; __u32 lsb_page_type; lsb_page_type = NAND_Getlsbpage_type(); if(lsb_page_type!=0) blk_size_load = NAND_GetLsbblksize(); else blk_size_load = blk_size; for( blk_num = start_blk, buf_base = (__u32)buf, buf_off = 0; blk_num <= last_blk_num && buf_off < size; blk_num++ ) { printf("current block is %d and last block is %d.\n", blk_num, last_blk_num); if( NF_read_status( blk_num ) == NF_BAD_BLOCK ) // 如果当前块是坏块,则进入下一块 continue; cur_blk_base = blk_num * blk_size; rest_size = size - buf_off ; // 未载入部分的尺寸 size_loaded = ( rest_size < blk_size_load ) ? rest_size : blk_size_load ; // 确定此次待载入的尺寸 if( NF_read( cur_blk_base >> NF_SCT_SZ_WIDTH, (void *)buf_base, size_loaded >> NF_SCT_SZ_WIDTH ) == NF_OVERTIME_ERR ) return ADV_NF_OVERTIME_ERR; buf_base += size_loaded; buf_off += size_loaded; } *blks = blk_num - start_blk; // 总共涉及的块数 if( buf_off == size ) return ADV_NF_OK; // 成功,返回OK else { printf("lack blocks with start block %d and buf size %x.\n", start_blk, size); return ADV_NF_LACK_BLKS; // 失败,块数不足 } }
/******************************************************************************* *函数名称: load_Boot1_from_nand *函数原型:int32 load_Boot1_from_nand( void ) *函数功能: 将一份好的Boot1从nand flash中载入到SRAM中。 *入口参数: void *返 回 值: OK 载入并校验成功 * ERROR 载入并校验失败 *备 注: *******************************************************************************/ __s32 load_Boot1_from_nand( void ) { __u32 i; __s32 status; __u32 length; __u32 read_blks; struct spare_boot_head_t *bfh = (struct spare_boot_head_t *) CONFIG_SYS_TEXT_BASE;; if(NF_open( ) == NF_ERROR) // 打开nand flash { printf("fail in opening nand flash\n"); return -1; } //printf("Succeed in opening nand flash.\n"); //printf("block from %d to %d\n", BOOT1_START_BLK_NUM, BOOT1_LAST_BLK_NUM); for( i = BOOT1_START_BLK_NUM; i <= BOOT1_LAST_BLK_NUM; i++ ) { if( NF_read_status( i ) == NF_BAD_BLOCK ) // 如果当前块是坏块,则进入下一块 { printf("nand block %d is bad\n", i); continue; } /* 载入当前块最前面512字节的数据到SRAM中,目的是获取文件头 */ if( NF_read( i << ( NF_BLK_SZ_WIDTH - NF_SCT_SZ_WIDTH ), (void *)CONFIG_SYS_TEXT_BASE, 1 ) == NF_OVERTIME_ERR ) { printf("the first data is error\n"); continue; } //printf("Succeed in reading Boot1 file head.\n"); /* 察看是否是文件头 */ if( check_magic( (__u32 *)CONFIG_SYS_TEXT_BASE, UBOOT_MAGIC ) != 0 ) { printf("ERROR! block %u doesn't store head of Boot1 copy.\n", i ); continue; } length = bfh->boot_head.length; //printf("The size of Boot1 is %x.\n", length ); //printf("The align size of Boot1 is %x.\n", NF_SECTOR_SIZE ); if( ( length & ( NF_SECTOR_SIZE - 1 ) ) != 0 ) // length必须是NF_SECTOR_SIZE对齐的 { printf("the boot1 is not aligned by %x\n", bfh->boot_head.align_size); continue; } //printf("The size of Boot1 is %x.\n", length ); if( 1==load_uboot_in_one_block_judge(length) ) { /* 从一个块中载入Boot1的备份 */ status = load_and_check_in_one_blk( i, (void *)CONFIG_SYS_TEXT_BASE, length, NF_BLOCK_SIZE ); if( status == ADV_NF_OVERTIME_ERR ) // 块数不足 continue; else if( status == ADV_NF_OK ) { //printf("Check is correct.\n"); bfh->boot_data.storage_type = 0; NF_close( ); // 关闭nand flash return 0; } } else { /* 从多个块中载入一份Boot1的备份 */ status = load_in_many_blks( i, BOOT1_LAST_BLK_NUM, (void*)CONFIG_SYS_TEXT_BASE, length, NF_BLOCK_SIZE, &read_blks ); if( status == ADV_NF_LACK_BLKS ) // 块数不足 { printf("ADV_NF_LACK_BLKS\n"); NF_close( ); // 关闭nand flash return -1; } else if( status == ADV_NF_OVERTIME_ERR ) { printf("mult block ADV_NF_OVERTIME_ERR\n"); continue; } if( check_sum( (__u32 *)CONFIG_SYS_TEXT_BASE, length ) == 0 ) { printf("The file stored in start block %u is perfect.\n", i ); bfh->boot_data.storage_type = 0; NF_close( ); // 关闭nand flash return 0; } } } printf("Can't find a good Boot1 copy in nand.\n"); NF_close( ); // 关闭nand flash printf("Ready to quit \"load_Boot1_from_nand\".\n"); return -1; }
/******************************************************************************* *函数名称: load_Boot1_from_nand *函数原型:int32 load_Boot1_from_nand( void ) *函数功能: 将一份好的Boot1从nand flash中载入到SRAM中。 *入口参数: void *返 回 值: 0 载入并校验成功 * -1 载入并校验失败 *备 注: *******************************************************************************/ int load_toc1_from_nand( void ) { __u32 i; __s32 status; __u32 length; __u32 read_blks; sbrom_toc1_head_info_t *toc1_head; if(NF_open( ) == NF_ERROR) // 打开nand flash { printf("fail in opening nand flash\n"); return -1; } for( i = BOOT1_START_BLK_NUM; i <= BOOT1_LAST_BLK_NUM; i++ ) { if( NF_read_status( i ) == NF_BAD_BLOCK ) // 如果当前块是坏块,则进入下一块 { printf("nand block %d is bad\n", i); continue; } /* 载入当前块最前面512字节的数据到SRAM中,目的是获取文件头 */ if( NF_read( i << ( NF_BLK_SZ_WIDTH - NF_SCT_SZ_WIDTH ), (void *)CONFIG_TOC1_STORE_IN_DRAM_BASE, 1 ) == NF_OVERTIME_ERR ) { printf("the first data is error\n"); continue; } /* 察看是否是文件头 */ toc1_head = (sbrom_toc1_head_info_t *) CONFIG_TOC1_STORE_IN_DRAM_BASE; if(toc1_head->magic != TOC_MAIN_INFO_MAGIC) { printf("%s err: the toc1 head magic is invalid\n", __func__); continue; } length = toc1_head->valid_len; if( ( length & ( ALIGN_SIZE - 1 ) ) != 0 ) // length必须是NF_SECTOR_SIZE对齐的 { printf("the boot1 is not aligned by 0x%x\n", ALIGN_SIZE); continue; } if( length <= NF_BLOCK_SIZE ) { /* 从一个块中载入Boot1的备份 */ status = load_and_check_in_one_blk( i, (void *)CONFIG_TOC1_STORE_IN_DRAM_BASE, length, NF_BLOCK_SIZE ); if( status == ADV_NF_OVERTIME_ERR ) // 块数不足 { continue; } else if( status == ADV_NF_OK ) { printf("Check is correct.\n"); NF_close( ); // 关闭nand flash return 0; } } else { /* 从多个块中载入一份Boot1的备份 */ status = load_in_many_blks( i, BOOT1_LAST_BLK_NUM, (void*)CONFIG_TOC1_STORE_IN_DRAM_BASE, length, NF_BLOCK_SIZE, &read_blks ); if( status == ADV_NF_LACK_BLKS ) // 块数不足 { printf("ADV_NF_LACK_BLKS\n"); NF_close( ); // 关闭nand flash return -1; } else if( status == ADV_NF_OVERTIME_ERR ) { printf("mult block ADV_NF_OVERTIME_ERR\n"); continue; } if( verify_addsum( (__u32 *)CONFIG_TOC1_STORE_IN_DRAM_BASE, length ) == 0 ) { printf("The file stored in start block %u is perfect.\n", i ); NF_close( ); // 关闭nand flash return 0; } } } printf("Can't find a good Boot1 copy in nand.\n"); NF_close( ); // 关闭nand flash printf("Ready to quit \"load_Boot1_from_nand\".\n"); return -1; }
/******************************************************************************* *函数名称: load_Boot1_from_nand *函数原型:int32 load_Boot1_from_nand( void ) *函数功能: 将一份好的Boot1从nand flash中载入到SRAM中。 *入口参数: void *返 回 值: OK 载入并校验成功 * ERROR 载入并校验失败 *备 注: *******************************************************************************/ __s32 load_Boot1_from_nand( void ) { __u32 i; __s32 status; __u32 length; __u32 read_blks; boot_file_head_t *bfh; if(NF_ERROR==NF_open( )) // 打开nand flash { msg("can't open nand flash.\n"); return ERROR; } msg("Succeed in opening nand flash.\n"); msg("block from %d to %d\n", BOOT1_START_BLK_NUM, BOOT1_LAST_BLK_NUM); for( i = BOOT1_START_BLK_NUM; i <= BOOT1_LAST_BLK_NUM; i++ ) { msg("deal block %d\n", i); if( NF_read_status( i ) == NF_BAD_BLOCK ) // 如果当前块是坏块,则进入下一块 { msg("nand block %d is bad\n", i); continue; } /* 载入当前块最前面512字节的数据到SRAM中,目的是获取文件头 */ if( NF_read( i << ( NF_BLK_SZ_WIDTH - NF_SCT_SZ_WIDTH ), (void *)BOOT1_BASE, 1 ) == NF_OVERTIME_ERR ) { msg("the first data is error\n"); continue; } msg("Succeed in reading Boot1 file head.\n"); /* 察看是否是文件头 */ if( check_magic( (__u32 *)BOOT1_BASE, BOOT1_MAGIC ) != CHECK_IS_CORRECT ) { msg("ERROR! block %u doesn't store head of Boot1 copy.\n", i ); continue; } bfh = (boot_file_head_t *) BOOT1_BASE; length = bfh->length; // msg("The size of Boot1 is %x.\n", length ); // msg("The align size of Boot1 is %x.\n", bfh->align_size); if( ( length & ( NF_SECTOR_SIZE - 1 ) ) != 0 ) // length必须是NF_SECTOR_SIZE对齐的 { msg("the boot1 is not aligned by %x\n", NF_SECTOR_SIZE); continue; } msg("The size of Boot1 is %x.\n", length ); if( length <= NF_BLOCK_SIZE ) { /* 从一个块中载入Boot1的备份 */ status = load_and_check_in_one_blk( i, (void *)BOOT1_BASE, length, NF_BLOCK_SIZE, BOOT1_MAGIC ); if( status == ADV_NF_OVERTIME_ERR ) // 块数不足 { msg("one block ADV_NF_OVERTIME_ERR\n"); continue; } else if( status == ADV_NF_OK ) { msg("Check is correct.\n"); bfh->eGON_vsn[2] = 0; NF_close( ); // 关闭nand flash return OK; } } else { /* 从多个块中载入一份Boot1的备份 */ status = load_in_many_blks( i, BOOT1_LAST_BLK_NUM, (void*)BOOT1_BASE, length, NF_BLOCK_SIZE, &read_blks ); if( status == ADV_NF_LACK_BLKS ) // 块数不足 { msg("ADV_NF_LACK_BLKS\n"); NF_close( ); // 关闭nand flash return ERROR; } else if( status == ADV_NF_OVERTIME_ERR ) { msg("mult block ADV_NF_OVERTIME_ERR\n"); continue; } if( check_sum( (__u32 *)BOOT1_BASE, length ) == CHECK_IS_CORRECT ) { msg("The file stored in start block %u is perfect.\n", i ); bfh->eGON_vsn[2] = 0; NF_close( ); // 关闭nand flash return OK; } } } msg("Can't find a good Boot1 copy in nand.\n"); NF_close( ); // 关闭nand flash msg("Ready to quit \"load_Boot1_from_nand\".\n"); return ERROR; }