Ejemplo n.º 1
0
/*
	写入实际地址add重复写值x,times次后赋值flash_error,
	或者在规定重读次数前写入正确的值。*/
void repeat_write(unsigned int add,unsigned char x,unsigned char times)
{
	unsigned char i=0;
	do
	{
		if(i>times)
			break;
		flashwrite(add,x);
		i++;
	}
	while(flash_error&write_error);
}
Ejemplo n.º 2
0
int main (void) {
    register unsigned i;
    P1DIR |= BIT4;

    P1OUT |= BIT4;
    for (i = 0; i < 50; ++i);
    P1OUT &= ~BIT4;

    /* time between two GPIO spikes is the time for flashwrite */
    flashwrite();

    P1OUT |= BIT4;
    for (i = 0; i < 50; ++i);
    P1OUT &= ~BIT4;
}
Ejemplo n.º 3
0
void checkAutoFlashing(unsigned long startAddr, int len)
{
	int i=0;
	unsigned long head_offset=0, srcAddr, burnLen;
	unsigned short sum=0;
	unsigned char sum1=0;
	int skip_header=0;
	int reboot=0;
	IMG_HEADER_T Header ; //avoid unalign problem
	int skip_check_signature=0;
	unsigned long burn_offset =0; //mark_dual
	
#ifdef CONFIG_RTL_FLASH_DUAL_IMAGE_ENABLE	
	check_dualbank_setting(0); //must do check image to get current boot_bank.......
#endif		
	while( (head_offset + sizeof(IMG_HEADER_T)) <  len){
		sum=0; sum1=0;
		memcpy(&Header, ((char *)startAddr + head_offset), sizeof(IMG_HEADER_T));
		
		if (!skip_check_signature) {
			for(i=0 ;i < MAX_SIG_TBL ; i++) {
			
				if(!memcmp(Header.signature, (char *)sign_tbl[i].signature, sign_tbl[i].sig_len))
					break;			
				
		
			}
			if(i == MAX_SIG_TBL){
				head_offset += Header.len + sizeof(IMG_HEADER_T);
				continue ;
			}
#ifdef CONFIG_BOOT_CODE_SIZE_CHECK
			if(!memcmp(Header.signature, BOOT_SIGNATURE, SIG_LEN)){
				// - checksum len
				if((Header.len-2) > CONFIG_BOOT_CODE_SIZE){	
					prom_printf("bootcode is too big\n");
					return;
				}
			}
#endif			
			skip_header = sign_tbl[i].skip ;
			if(skip_header){
				srcAddr = startAddr + head_offset + sizeof(IMG_HEADER_T);
					burnLen = Header.len; // +checksum
			}else{
				srcAddr = startAddr + head_offset ;
				burnLen = Header.len + sizeof(IMG_HEADER_T) ;
			}	
			reboot |= sign_tbl[i].reboot;
			prom_printf("\n%s upgrade.\n", sign_tbl[i].comment);
		}
		else {
			if(!memcmp(Header.signature, BOOT_SIGNATURE, SIG_LEN)){
#ifdef CONFIG_BOOT_CODE_SIZE_CHECK
				// - checksum len
				if((Header.len-2) > CONFIG_BOOT_CODE_SIZE){	
					prom_printf("bootcode is too big\n");
					return;
				}
#endif
				skip_header = 1;
			}else {
				unsigned char *pRoot =((unsigned char *)startAddr) + head_offset + sizeof(IMG_HEADER_T);
				if (!memcmp(pRoot, SQSH_SIGNATURE, SIG_LEN))
					skip_header = 1;
				else				
					skip_header = 0;
			}				
			if(skip_header){
				srcAddr = startAddr + head_offset + sizeof(IMG_HEADER_T);
				burnLen = Header.len ; // +checksum

			}else{
				srcAddr = startAddr + head_offset ;
				burnLen = Header.len + sizeof(IMG_HEADER_T) ;
			}			
		}		

		if(skip_check_signature || 
			memcmp(Header.signature, WEB_SIGNATURE, 3)){
			//calculate checksum
			if(!memcmp(Header.signature, ALL1_SIGNATURE, SIG_LEN) ||
					!memcmp(Header.signature, ALL2_SIGNATURE, SIG_LEN)) {										
				for (i=0; i< Header.len+sizeof(IMG_HEADER_T); i+=2) {
					sum += *((unsigned short *)(startAddr+ head_offset + i));
				}				
			}	
				else 
				{
					unsigned char x=0,y=0;
					unsigned short temp=0;
					
					for (i=0; i< Header.len; i+=2) 
					{
						
#if defined(RTL8196B) || defined(RTL8198)																		
#if 1				
						//sum +=*((unsigned short *)(startAddr+ head_offset + sizeof(IMG_HEADER_T) + i));
						memcpy(&temp, (startAddr+ head_offset + sizeof(IMG_HEADER_T) + i), 2); // for alignment issue
						sum+=temp;
#else						
						x=*((unsigned char *)(startAddr+ head_offset + sizeof(IMG_HEADER_T) + i));						
						y=*((unsigned char *)(startAddr+ head_offset + sizeof(IMG_HEADER_T) + i+1));
						sum+=(y|x<<8)&0xFFFF;
#endif
#else
				sum += *((unsigned short *)(startAddr+ head_offset + sizeof(IMG_HEADER_T) + i));
#endif	//#if defined(RTL8196B) || defined(RTL8198)
				}
			}
			if ( sum ) {
				prom_printf("%s imgage checksum error at %X!\n"
				, Header.signature, startAddr+head_offset);
				return ;
			}
			if(!memcmp(Header.signature, ALL1_SIGNATURE, SIG_LEN)){
				head_offset += sizeof(IMG_HEADER_T);
				continue;		
			}		
			if(!memcmp(Header.signature, ALL2_SIGNATURE, SIG_LEN)){
				skip_check_signature = 1;
				head_offset += sizeof(IMG_HEADER_T);			
				continue;		
			}						
		}else
		{  //web page use different checksum algorimth

			for (i=0; i< Header.len; i++)
			       sum1 += *((unsigned char *)(startAddr+ head_offset + sizeof(IMG_HEADER_T) + i));
			if ( sum1 ) {
				prom_printf("%s imgage checksum error at %X!\n"
				, Header.signature, startAddr+head_offset);
				return ;
			}
		}
		prom_printf("checksum Ok !\n");
		
		prom_printf("burn Addr =0x%x! srcAddr=0x%x len =0x%x \n", Header.burnAddr, srcAddr, burnLen);

#ifdef CONFIG_RTL_FLASH_DUAL_IMAGE_ENABLE				
		if(!memcmp(Header.signature, FW_SIGNATURE, SIG_LEN) || !memcmp(Header.signature, FW_SIGNATURE_WITH_ROOT, SIG_LEN))
		{
			IMG_HEADER_T header_t, *header_p;
			header_p = &header_t;
			burn_offset = sel_burnbank_offset();
			prom_printf("burn_offset = %x !\n",burn_offset);
			memcpy(header_p, ((char *)srcAddr), sizeof(IMG_HEADER_T));			
			header_p->burnAddr = get_next_bank_mark();
			//prom_printf("2 header_p->burn = 0x%x \n", header_p->burnAddr);
			memcpy(((char *)srcAddr), header_p, sizeof(IMG_HEADER_T));			
		}
		else if(!memcmp(Header.signature, ROOT_SIGNATURE, SIG_LEN))
		{
			burn_offset = sel_burnbank_offset();
			prom_printf("burn_offset = %x !\n",burn_offset);
		}
#endif
int trueorfaulse = 0;
#ifdef CONFIG_SPI_FLASH
		#ifdef SUPPORT_SPI_MIO_8198_8196C
			if(Header.burnAddr+burn_offset+burnLen > spi_flash_info[0].chip_size)
				{
				if(spi_flw_image_mio_8198(0,Header.burnAddr+burn_offset, srcAddr, spi_flash_info[0].chip_size-(Header.burnAddr+burn_offset))&&
					spi_flw_image_mio_8198(1,0, srcAddr+spi_flash_info[0].chip_size-(Header.burnAddr+burn_offset), Header.burnAddr+burn_offset+burnLen-spi_flash_info[0].chip_size))
					trueorfaulse = 1;
				}
			else
				if(spi_flw_image_mio_8198(0,Header.burnAddr+burn_offset, srcAddr, burnLen))
					trueorfaulse = 1;
		#else
			if(spi_flw_image(0,Header.burnAddr+burn_offset, srcAddr, burnLen))
		#endif
#else
		if (flashwrite(Header.burnAddr+burn_offset, srcAddr, burnLen))
#endif
		if(trueorfaulse)
			prom_printf("\nFlash Write Successed!\n%s", "<RealTek>");
		else{
			prom_printf("\nFlash Write Failed!\n%s", "<RealTek>");
			return ;
		}

		head_offset += Header.len + sizeof(IMG_HEADER_T);
	} //while
	if(reboot){
	    	autoreboot();
	}
		
}