⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loader.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
            }
            if ( (type == '2') || (type == '8') )
            {
                offset_data = OFFSET_DATA_S28;  /* Only relevant for S2/S8 records */
            }
            if ( (type == '1') || (type == '9') )
            {
                offset_data = OFFSET_DATA_S19;  /* Only relevant for S1/S9 records */
            }
	    checksum    = 0;

            /* Convert line */
            odd  = TRUE ;
	    while (TRUE)
	    {
                /* get next character */
                ch = sdata[sid++] ;
                odd = !odd;
		
                /* convert character */
                ch_val = char2val[ch] ;

                /* check for invalid chars */
                if ( ch_val == INVALID_CHAR )
                {
                    // printf("1 %d\n", ch) ;
                    *raw_error = ERROR_LOAD_ILLEGAL_CHARACTER ;
		    return ERROR_LOAD_ILLEGAL_CHARACTER ;
                }

                /* check for valid "space" chars to terminate */
                if ( ch_val == VALID_SPACE )
                {
		    if( odd )
		    {
                        // printf("2 %d\n", ch) ;
                        *raw_error = ERROR_LOAD_ILLEGAL_FORMAT ;
		        return ERROR_LOAD_ILLEGAL_FORMAT;
		    }

                    /* check rest of line, must contain VALID_SPACE only */
                    do 
                    {
                       /* get char */
                       ch = sdata[sid++] ;
                       ch_val = char2val[ch] ;

                       /* check for invalid format */
                       if ( ch_val != VALID_SPACE )
                       {
                            // printf("3 %d\n", ch) ;
                            *raw_error = ERROR_LOAD_ILLEGAL_FORMAT ;
		            return ERROR_LOAD_ILLEGAL_FORMAT;
                       }
                    } while( ch ) ;
		    break;
                }

		if( odd )
		{
                    /* Store value */
		    val          <<= 4;
		    val           |= ch_val ;
                    data[offset++] = val;
                    checksum       += val;
                }
                else
                {
		    val = ch_val ;
                }
	    }

	    /* Do various checks (don't perform checks for S0/S5 since
	     * they are discarded anyway.
	     */

	    if( (type != '0') && (type != '5') )
	    {
	        /* Check that enough data is available */
		if( offset < offset_data + 1 )
		{
	            /* Something missing */
                    // printf("4 %d\n", type) ;
                    *raw_error = ERROR_LOAD_ILLEGAL_FORMAT ;
		    return ERROR_LOAD_ILLEGAL_FORMAT;
	        }

		/* Check count */
		if( offset - (OFFSET_COUNT + 1) != data[OFFSET_COUNT] )
	        {
                    // printf("5 %d\n", offset) ;
                    *raw_error = ERROR_LOAD_ILLEGAL_FORMAT ;
	            return ERROR_LOAD_ILLEGAL_FORMAT;
		}

	        /* Check checksum */
		if( checksum != 0xFF)
                {
                    *raw_error = ERROR_LOAD_CHECKSUM ;
	            return ERROR_LOAD_CHECKSUM ;
                }
            }

	    /* Address */
            if ( (type == '3') || (type == '7') )
            {
                /* 4-byte address is kept in 4-7 */
                addr[0] = (void *)(*(UINT32 *)(&data[OFFSET_ADDRESS]));
            }
            if ( (type == '2') || (type == '8') )
            {
                /* 3-byte address is kept in 4-6 */
                data[0] = 0 ;
                data[1] = data[OFFSET_ADDRESS+0] ;
                data[2] = data[OFFSET_ADDRESS+1] ;
                data[3] = data[OFFSET_ADDRESS+2] ;

                addr[0] = (void *)(*(UINT32 *)(&data[0]));
            }
            if ( (type == '1') || (type == '9') )
            {
                /* 2-byte address is kept in 4-5 */
                data[0] = 0 ;
                data[1] = 0 ;
                data[2] = data[OFFSET_ADDRESS+0] ;
                data[3] = data[OFFSET_ADDRESS+1] ;

                addr[0] = (void *)(*(UINT32 *)(&data[0]));
            }
#ifdef EL
	    addr[0] = (void *)SWAPEND32( (UINT32)(addr[0]) );
#endif

	    /* Decode line */

            /* Set offset to the number of data bytes */
            offset -= (offset_data + 1);
	    
  	    switch( type )
	    {
              case '1' :
              case '2' :
	      case '3' :
	        /**** S1, S2 or S3 record ****/	
	        if(offset)
	        {
		    /* Write data to RAM/FLASH
		     *   
		     * dst addr  = (UINT32)*addr
		     * bytecount = offset
		     * src addr  = &data[offset_data]
		     */

                    /* check range context to return this at load end */
                    if ( (UINT32)addr[0] < (UINT32)addr[1] ) 
                        (UINT32)addr[1] = (UINT32)addr[0]  ;
                    if ( ((UINT32)addr[0]+offset-1) > (UINT32)addr[2] ) 
                        (UINT32)addr[2] = (UINT32)addr[0]+offset-1  ;

		    /* Validate address */
		    rc = sys_validate_range( 
		             (UINT32)addr[0],
			     offset,
			     sizeof(UINT8),
			     TRUE );

		    if (rc != OK)
		    {
		        *raw_error = rc;
		        return rc;	
		    }

                    flash_write.adr     = (UINT32)addr[0];
                    flash_write.length  = offset ;
                    flash_write.buffer  = &data[offset_data] ;
                    //printf(" adr=%08x\n", flash_write.adr ) ;
                    rc = IO_write( SYS_MAJOR_FLASH_STRATA, 0, &flash_write ) ;
                    if (rc != OK)
                    {
                        *raw_error = rc ;
                        return ERROR_LOAD_STORE;
                    }

                    /* PBUpdate indicate address in alpha-display */
                  /*  DISP( (UINT32)addr[0] ) ; */
	        }
	        break;
	      case '7' :
              case '8' :
              case '9' :
	        /* S7, S8 or S9 record (end record) */
                *raw_error = ERROR_LOAD_NONE ;
                if (offset != 0 )
                {
                    // printf("6 %d\n", offset) ;
                    *raw_error = ERROR_LOAD_ILLEGAL_FORMAT ;
                }
	        if( port == PORT_NET )
	        {
                    /* This just to guarantee proper report */
                    printf("\n") ;
	        }
		return offset ? ERROR_LOAD_ILLEGAL_FORMAT : ERROR_LOAD_NONE;
	        break;
	      default :  /* Ignore S0/S5 records */
	        break;
	    }
        }
	else
	{
            // printf("7 %d\n", type) ;
            *raw_error = ERROR_LOAD_ILLEGAL_FORMAT ;
	    return ERROR_LOAD_ILLEGAL_FORMAT;
	}


        /* read next line */
        *raw_error = loader_readline( port ) ;
        *error_pos = failing_line_no ;
        if ( *raw_error != OK ) return( *raw_error ) ;
        ch = sdata[sid++] ;
	if( ch != 'S' )
	{
            // printf("8 %d\n", ch) ;
            *raw_error = ERROR_LOAD_ILLEGAL_FORMAT ;
	    return ERROR_LOAD_ILLEGAL_FORMAT;
	}
    }
}

/************************************************************************
 *                          loader_readline
 ************************************************************************/
static UINT32 loader_readline( UINT32  port ) 
{
    bool   empty_line ;
    signed char ch ;

    /* set default */ 
    empty_line = TRUE ;

    /* adjust line number counter */
    failing_line_no = failing_line_no - failing_line_no_adjust ; 

    /* do read lines until any not empty found */
    while ( empty_line )
    {
        /* clear actual line */
        sid = 0 ;
        do
        {
            while( !GETCHAR( port, &ch ) )
            {
                /* check for user break */
                if (port != DEFAULT_PORT )
                {
                    if (GETCHAR_CTRLC( DEFAULT_PORT ))
                       return( ERROR_LOAD_BREAK ) ;
                }
            }
    
            /* check for user break */
            if ( ch == CTRL_C )
                    return( ERROR_LOAD_BREAK ) ;

            if ( ch == EOF_SREC )
            {
                /* check for End Of File; used by TFTP */
                sid      = 0 ; /* clear current line */
                sdata[0] = 0 ;
                return ERROR_LOAD_NO_S7_RECORD ;
            }

            if ( ch == UART_ERROR )
            {
                /* UART communication error */
                failing_line_no++ ;
                sdata[sid] = 0 ;
                return ERROR_LOAD_UART_COMM_ERROR ;
            }

            /* check line size */
            if (sid < MAX_LINE_SIZE)
            {
                /* save character, in upper case */
                sdata[sid++] = toupper(ch) ;
            }
            else
            {
                /* terminate line and return error */
                failing_line_no++ ;
                sdata[sid] = 0 ;
                return ERROR_LOAD_LINE_TOO_LONG;
            }
             
            /* check until any none space character found */
            if ( empty_line )
            {
                if ( ( ch != SP ) && ( ch != TAB ) && ( ch != CR ) && ( ch != LF ) )
                    empty_line = FALSE ;
            }
        }
        while( (ch != LF) && (ch != CR) ) ;

        /* adjust line counter */
        if (ch == LF) 
        {
            if (!line_termination_is_linefeed)
            {
                /* Toggle termination criteria */
                line_termination_is_linefeed = TRUE ;

                /* Reset line count */
                failing_line_no = 0 ; 
            }

            /* Count line */
            failing_line_no++ ; 
        }
        else
        {
            if (!line_termination_is_linefeed)
            {
                /* Count line */
                failing_line_no++ ; 
            }
        }
    }

    if (line_termination_is_linefeed)
    {
        if (ch != LF)
        {
            failing_line_no_adjust = 1 ; 
            failing_line_no++ ; 
        }
        else
        {
            failing_line_no_adjust = 0 ; 
        }
    }

    sdata[sid] = 0 ; /* remember to allocate space for the NUL-termination */
    sid        = 0 ;
    return(OK) ;
}


static
INT32 loader_error_lookup( t_sys_error_string *p_param )
{
    UINT32 t, i ;

    i = 0 ;
    p_param->count = 0 ;
    t = SYSERROR_ID( p_param->syserror ) ;
    /* check for recognized error code */
    if (t < sizeof(loader_error_string)/sizeof(char*) )
    {
        /* fill in mandatory error message string */
        p_param->strings[SYSCON_ERRORMSG_IDX] = loader_error_string[t] ;
        i++ ;

        /* check for diagnose message */
        if ( sdata[0] != 0 )
        {
            /* fill in optional diagnose message string */
            sprintf( loader_diag_msg,"Line %d, %s", failing_line_no, sdata ) ;
            p_param->strings[SYSCON_DIAGMSG_IDX] = loader_diag_msg ;
            i++ ;
        }

        /* check for hint message */
        if ( loader_error_hint_string[t] != NULL)
        {
            /* fill in optional hint message string */
            p_param->strings[SYSCON_HINTMSG_IDX] = loader_error_hint_string[t] ;
            i++ ;
        }
    }
    p_param->count      = i ;

    /* delete context */
    loader_last_error  = OK ;
    return(OK) ;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -