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

📄 dloadarm.c

📁 在高通的手机平台下,一个下载手机.bin文件到手机的flash中的工具,包含PC端的程序代码和运行在基带处理器中的代码.
💻 C
📖 第 1 页 / 共 4 页
字号:
  word  cmd_len
    /* Number of bytes received in the command packet */
)
{
  extern unsigned long long chk_security_code_ptr;
  byte *security_code;
  int  i;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  if (cmd_len < UNLOCK_SIZ)       /* Make sure at least the header arrived  */
    {
    transmit_response(NAK_EARLY_END);        /* Nope, packet ended early   */
    return;
    }

  /* If secure functions are already unlocked, bypass
     validity check of received security code */
  if (sec_code_unlocked)
    {
      transmit_response(ACK);
      return;
    }

  /* Compare 64-bit security code in the received packet
     with the security code stored in flash */

  /* point to beginning of security code */
  security_code = (byte *) &chk_security_code_ptr;

  /* code is 64 bits long */

  /* scan through security code */

  for (i = 0; i < 8; i++)
    {
      /* received invalid security code */
      /* NAK the command and power-off the phone */
      if (security_code[i] != cmd_buf[i+1])
        {
          sec_code_unlocked = FALSE;
          transmit_response(NAK_BAD_SEC_CODE);

          /* now powerdown the phone */
          boot_hw_powerdown();

          return;
        }
    }

  /* The received security code matches the stored code, so
     set SECURITY_CODE_STATUS to unlock secure operations */
  sec_code_unlocked = TRUE;

} /* unlock_cmd() */



/*===========================================================================

FUNCTION nop_cmd

DESCRIPTION
  This function processes a no-op command packet.

DEPENDENCIES
  None.

RETURN VALUE
  None.

SIDE EFFECTS
  None.

===========================================================================*/

static void nop_cmd(void)
{

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /* (The whole packet must have arrived, since it's only one byte long.) */
  transmit_response(ACK);          /* Nothing can go wrong.  Send an ACK. */

} /* nop_cmd() */


/*===========================================================================

FUNCTION preq_cmd

DESCRIPTION
  This function processes a parameter request command packet.

DEPENDENCIES
  None.

RETURN VALUE
  None.

SIDE EFFECTS
  None.

===========================================================================*/

static void preq_cmd(void)
{

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /* Packet we'll build and send in response */
  pkt_buffer_type params_buf;

  /* Model number of the phone hardware */
  extern word boot_mob_model;
  word mob_model;

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /* (The whole packet must have arrived, since it's only one byte long.) */

  /* Copy the mob_model number out of flash */
  mob_model = boot_mob_model;

  /* If the real value can't be determined, we use the unknown value code */
  if ((mob_model == MOB_MODEL_NOP_VAL) || (mob_model == MOB_MODEL_ERASED_VAL))
    mob_model = MOB_MODEL_UNKNOWN_VAL;


  /* Build the packet. */
  START_BUILDING_PACKET(params_buf);
  ADD_BYTE_TO_PACKET(params_buf, CMD_PARAMS);
  ADD_BYTE_TO_PACKET(params_buf, PROTOCOL_ID);
  ADD_BYTE_TO_PACKET(params_buf, MIN_PROTOCOL_ID);
  ADD_WORD_TO_PACKET(params_buf, MAX_WRITE_SIZE);
  ADD_BYTE_TO_PACKET(params_buf, mob_model);
  ADD_BYTE_TO_PACKET(params_buf, DUMMY);
  ADD_BYTE_TO_PACKET(params_buf, DUMMY);
  FINISH_BUILDING_PACKET(params_buf);

  /* Send the requested parameters response */
  transmit_packet(&params_buf);

} /* preq_cmd() */


/*===========================================================================

FUNCTION reset_cmd

DESCRIPTION
  This function processes a reset command packet by resetting the
  phone (after the command is acknowledged).

DEPENDENCIES
  None.

RETURN VALUE
  Does not return.

SIDE EFFECTS
  None.

===========================================================================*/

static void reset_cmd(void)
{

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /* (The whole packet must have arrived, since it's only one byte long.) */

  transmit_response(ACK);          /* Nothing can go wrong.  Send an ACK. */

  uart_drain();                       /* Make sure the response gets out. */

  for (;;)           /* Do nothing until the watchdog resets the machine. */
     {
     }

} /* reset_cmd() */


/*===========================================================================

FUNCTION dload_str_len

DESCRIPTION
  This function returns the number of characters in the given string, not
  counting the terminating NULL character.  The returned length is never
  more than 20, to accomodate a limitation of the dload protocol.

DEPENDENCIES
  The string should be NULL terminated.  If it is not, only the first 20
  characters will matter.

RETURN VALUE
  The length of the string, not counting the terminating NULL.  The value
  never exceeds 20.

SIDE EFFECTS
  None.

===========================================================================*/

static byte dload_str_len(const char* str)
{
  byte count = 0;
  char* ptr;

  /* count every non-null character, but don't go beyond 20 characters */
  for (ptr = (char*)str; *ptr != '\0' && count < 20; ptr++)
    count++;

  return count;
}

/*===========================================================================

FUNCTION verreq_cmd

DESCRIPTION
  This function processes a software version request command packet.

DEPENDENCIES
  None.

RETURN VALUE
  None.

SIDE EFFECTS
  None.

===========================================================================*/

static void verreq_cmd(void)
{

  pkt_buffer_type    verrsp_buf;
    /* Buffer where we'll build the response packet. */

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /* (The whole packet must have arrived, since it's only one byte long.) */

  START_BUILDING_PACKET(verrsp_buf);
  ADD_BYTE_TO_PACKET(verrsp_buf, CMD_VERRSP);

  /* mob_sw_rev is defined in mobile.c */
  ADD_BYTE_TO_PACKET(verrsp_buf, dload_str_len(mob_sw_rev));
  ADD_STRING_TO_PACKET(verrsp_buf, mob_sw_rev);
  FINISH_BUILDING_PACKET(verrsp_buf);

  transmit_packet(&verrsp_buf);
                                /* Send the requested version response */

} /* verreq_cmd() */


/*===========================================================================

FUNCTION pwroff_cmd

DESCRIPTION
  This function processes a Turn Phone Power Off command packet by
  turning off power to the phone (after the command is acknowledged).

DEPENDENCIES
  None.

RETURN VALUE
  Does not return.

SIDE EFFECTS
  None.

===========================================================================*/
void pwroff_cmd(void)
{

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /* (The whole packet must have arrived, since it's only one byte long.) */

  transmit_response(ACK);          /* Nothing can go wrong.  Send an ACK. */

  uart_drain();                       /* Make sure the response gets out. */

  /* now powerdown the phone */
  boot_hw_powerdown();

} /* pwroff_cmd() */


/*===========================================================================

FUNCTION process_packets

DESCRIPTION
  This function is the main loop implementing the DMSS Async Download
  Protocol.  It loops forever, processing packets as they arrive.

DEPENDENCIES
  All necessary initialization for normal CPU operation must have
  been performed, and the UART must have been initialized, before
  entering this function.

RETURN VALUE
  This function does not return.

SIDE EFFECTS
  None.

===========================================================================*/

void process_packets(void)
{
  byte  *pkt_buf;
    /* pointer to buffer for receiving a packet */
  word  len;
    /* Length of the packet received.  Guaranteed to be at least
       MIN_PACKET_LEN. */

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  /* set pointer to base of buffer area */
  pkt_buf = (byte*)PKT_BUFFER_BASE;

  /* Loop forever processing packets */
  for (;;)
    {
    len = rcv_packet(pkt_buf);         /* Get a packet from the UART */

    /* Process the packet according to its command code */
    switch(pkt_buf[0])
      {
      case  CMD_WRITE:
        write_cmd(pkt_buf, len);
        break;

      case  CMD_ERASE:
        erase_cmd(pkt_buf, len);
        break;

      case  CMD_GO:
        go_cmd(pkt_buf, len);
        break;

      case  CMD_NOP:
        nop_cmd();
        break;

      case  CMD_PREQ:
        preq_cmd();
        break;

      case  CMD_RESET:
        reset_cmd();
        break;

      case  CMD_UNLOCK:
        unlock_cmd(pkt_buf, len);
        break;

      case  CMD_VERREQ:
        verreq_cmd();
        break;

      case  CMD_PWROFF:
        pwroff_cmd();
        break;

      default:
        transmit_response(NAK_INVALID_CMD);
        break;
      }/* switch on packet command code */

    /* we've processed the command - reset pointer to base of buffer area */
    pkt_buf = (byte*)PKT_BUFFER_BASE;

    }/* for (;;) */

}/* process_packets() */


/*============================================================================

 FUNCTION SECURITY CODE INIT

 DESCRIPTION
   Initialize the phone security code status.  If erased, there is no security
   code, and all operations are unlocked.  If a security code exists, an unlock
   packet with matching security code must be received, prior to performing
   any protected operations (read/write/go).

 FORMAL ARGUMENTS
   None

 DEPENDENCIES
   None

 RETURN VALUE
   None

 SIDE EFFECTS
   Sets the security code status.  If locked, an unlock command with correct
   security code must be received.
============================================================================*/


void security_code_init()
{
  extern unsigned long long chk_security_code_ptr;
  byte *security_code;
  int i;

  /* point to beginning of security code */
  security_code = (byte*) &chk_security_code_ptr;

  /* scan through security code */
  for (i = 0; i < 8; i++)
    /* if the security code is not the erased value */
    if (security_code[i] != 0xFF)
      {
        /* then the code was written, and so we're currently locked */
        sec_code_unlocked = FALSE;
        return;
      }
  
  /* part is erased, so unlock for all protected operations */
  sec_code_unlocked = TRUE;
}


/*============================================================================

 FUNCTION BOOT_DOWNLOADER

 DESCRIPTION
   Do a bootstrap download.  Initialize the UART and perform memory
   operations at the direction of an external agent via the UART.

 FORMAL ARGUMENTS
   None

 DEPENDENCIES
   Called from the Diagnostic Task during offline mode, or as a part of
   the Boot modules error recovery.

 RETURN VALUE
   This routine does not return.  It may branch to a new program loaded
   into RAM.

 SIDE EFFECTS
   The watchdog timer is reset, interrupts are disabled.  The timeout
   counter is initialized and timeout checking is enabled/disabled.

============================================================================*/
void
boot_downloader(void)
{

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /* Turn of the PAs */
  outpw( PA_ON_CTL_WB, 0x0000 );

  /* Armprog expects TCXO so switch MCLK source to TCXO */
  #if defined(FEATURE_MCLK_43TCXO)  
  MCLK_SWITCH_TO_NORM();
  #elif defined(T_MSM_5100)    
#error code not present
  #endif /*FEATURE_MCLK_43TCXO*/

  //boot_hw_ctrl_init();          /* restore clock and memory config to original setting */
  uart_drain();				    /* drain UART */
  dload_uart_init(UART_1152K_BPS);			/* Hardware initialization */
  security_code_init();			/* initialize the security code */
  process_packets();			/* Process the protocol (forever) */
}

⌨️ 快捷键说明

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