Exemple #1
0
/*******************************************************************************
*函数名称: 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;
}