diff options
author | David Chiu <dchiu@synaptics.com> | 2022-03-09 12:02:33 +0800 |
---|---|---|
committer | David Chiu <dchiu@synaptics.com> | 2022-03-09 12:02:33 +0800 |
commit | 2b62809429a73bad716e8d86fc483bc94e6f2a76 (patch) | |
tree | 6ecef68a93d63078ecfa8df3113e124e48f9455a | |
parent | e9115fa74a72e9a267ec6c08b8df8cd05d4f9085 (diff) | |
download | rmi4utils-2b62809429a73bad716e8d86fc483bc94e6f2a76.tar.gz |
Support writing signature
-rwxr-xr-x | rmi4update/firmware_image.cpp | 26 | ||||
-rwxr-xr-x | rmi4update/firmware_image.h | 26 | ||||
-rwxr-xr-x | rmi4update/rmi4update.cpp | 117 | ||||
-rwxr-xr-x | rmi4update/rmi4update.h | 2 |
4 files changed, 166 insertions, 5 deletions
diff --git a/rmi4update/firmware_image.cpp b/rmi4update/firmware_image.cpp index bfbbc54..d6c0f16 100755 --- a/rmi4update/firmware_image.cpp +++ b/rmi4update/firmware_image.cpp @@ -54,6 +54,15 @@ void FirmwareImage::ParseHierarchicalImg() unsigned int length; unsigned char *content; unsigned short container_id; + unsigned int sigature_size; + + if (m_bootloaderVersion == RMI_IMG_V10_SIGNATURE_VERSION_NUMBER) { + fprintf (stdout, "has signature\n"); + for (ii = 0; ii < BLv7_MAX; ii++) { + m_signatureInfo[ii].bExisted = false; + m_signatureInfo[ii].size = 0; + } + } m_cntrAddr = extract_long(&m_memBlock[RMI_IMG_V10_CNTR_ADDR_OFFSET]); descriptor = (struct container_descriptor *)(m_memBlock + m_cntrAddr); @@ -68,21 +77,37 @@ void FirmwareImage::ParseHierarchicalImg() descriptor->container_id[1] << 8; content = m_memBlock + extract_long(descriptor->content_address); length = extract_long(descriptor->content_length); + sigature_size = extract_long(descriptor->signature_size); switch (container_id) { case BL_CONTAINER: m_bootloaderVersion = *content; break; case UI_CONTAINER: case CORE_CODE_CONTAINER: + if (sigature_size != 0) { + fprintf(stdout, "CORE CODE signature size : 0x%x\n", sigature_size); + m_signatureInfo[BLv7_CORE_CODE].bExisted = true; + m_signatureInfo[BLv7_CORE_CODE].size = sigature_size; + } m_firmwareData = content; m_firmwareSize = length; break; case FLASH_CONFIG_CONTAINER: + if (sigature_size != 0) { + fprintf(stdout, "FLASH CONFIG signature size : 0x%x\n", sigature_size); + m_signatureInfo[BLv7_FLASH_CONFIG].bExisted = true; + m_signatureInfo[BLv7_FLASH_CONFIG].size = sigature_size; + } m_flashConfigData = content; m_flashConfigSize = length; break; case UI_CONFIG_CONTAINER: case CORE_CONFIG_CONTAINER: + if (sigature_size != 0) { + fprintf(stdout, "CORE CONFIG signature size : 0x%x\n", sigature_size); + m_signatureInfo[BLv7_CORE_CONFIG].bExisted = true; + m_signatureInfo[BLv7_CORE_CONFIG].size = sigature_size; + } m_configData = content; m_configSize = length; break; @@ -176,6 +201,7 @@ int FirmwareImage::Initialize(const char * filename) m_lockdownData = &m_memBlock[RMI_IMG_LOCKDOWN_V5_OFFSET]; break; case 16: + case RMI_IMG_V10_SIGNATURE_VERSION_NUMBER: ParseHierarchicalImg(); break; default: diff --git a/rmi4update/firmware_image.h b/rmi4update/firmware_image.h index b9dab84..c2ce512 100755 --- a/rmi4update/firmware_image.h +++ b/rmi4update/firmware_image.h @@ -45,16 +45,16 @@ // Leon add for BL_V7 #define RMI_IMG_V10_CNTR_ADDR_OFFSET 0x0C +#define RMI_IMG_V10_SIGNATURE_VERSION_NUMBER 0x11 +#define RMI_IMG_V10_SIGNATURE_LENGTH_OFFSET 0x8 +#define RMI_IMG_V10_SIGNATURE_LENGTH_SIZE 4 struct container_descriptor { unsigned char content_checksum[4]; unsigned char container_id[2]; unsigned char minor_version; unsigned char major_version; - unsigned char reserved_08; - unsigned char reserved_09; - unsigned char reserved_0a; - unsigned char reserved_0b; + unsigned char signature_size[4]; unsigned char container_option_flags[4]; unsigned char content_options_length[4]; unsigned char content_options_address[4]; @@ -88,13 +88,25 @@ enum container_id { UTILITY_CONTAINER, UTILITY_PARAMETER_CONTAINER, }; + +enum signature_BLv7 { + BLv7_CORE_CODE = 0, + BLv7_CORE_CONFIG, + BLv7_FLASH_CONFIG, + BLv7_MAX +}; + +struct signature_info { + bool bExisted; + unsigned short size; +}; // BL_V7 end class FirmwareImage { public: FirmwareImage() : m_firmwareBuildID(0), m_packageID(0), m_firmwareData(NULL), m_configData(NULL), m_lockdownData(NULL), - m_memBlock(NULL) + m_memBlock(NULL), m_hasSignature(false) {} int Initialize(const char * filename); int VerifyImageMatchesDevice(unsigned long deviceFirmwareSize, @@ -108,6 +120,7 @@ public: unsigned long GetFlashConfigSize() { return m_flashConfigSize; } unsigned long GetLockdownSize() { return m_lockdownSize; } unsigned long GetFirmwareID() { return m_firmwareBuildID; } + signature_info *GetSignatureInfo() { return m_signatureInfo; } int VerifyImageProductID(char* deviceProductID); bool HasIO() { return m_io; } @@ -138,6 +151,9 @@ private: unsigned char * m_lockdownData; unsigned char * m_memBlock; unsigned long m_cntrAddr; // BL_V7 + bool m_hasSignature; + + signature_info m_signatureInfo[BLv7_MAX]; }; #endif // _FIRMWAREIMAGE_H_ diff --git a/rmi4update/rmi4update.cpp b/rmi4update/rmi4update.cpp index fb34953..1995222 100755 --- a/rmi4update/rmi4update.cpp +++ b/rmi4update/rmi4update.cpp @@ -775,6 +775,16 @@ int RMI4Update::WriteFirmwareV7() } } + + if(m_device.GetDeviceType() == RMI_DEVICE_TYPE_TOUCHPAD) { + // Write signature. + rc = WriteSignatureV7(BLv7_CORE_CODE, m_firmwareImage.GetFirmwareData(), offset); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + return rc; + } + } + return UPDATE_SUCCESS; } @@ -886,6 +896,16 @@ int RMI4Update::WriteCoreConfigV7() } } + + if(m_device.GetDeviceType() == RMI_DEVICE_TYPE_TOUCHPAD) { + // Write signature. + rc = WriteSignatureV7(BLv7_CORE_CONFIG, m_firmwareImage.GetConfigData(), offset); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + return rc; + } + } + return UPDATE_SUCCESS; } @@ -1002,6 +1022,16 @@ int RMI4Update::WriteFlashConfigV7() } } + + if(m_device.GetDeviceType() == RMI_DEVICE_TYPE_TOUCHPAD) { + // Write signature. + rc = WriteSignatureV7(BLv7_FLASH_CONFIG, m_firmwareImage.GetFlashConfigData(), offset); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + return rc; + } + } + return UPDATE_SUCCESS; } @@ -1324,6 +1354,93 @@ int RMI4Update::WriteBlocks(unsigned char *block, unsigned short count, unsigned return UPDATE_SUCCESS; } +int RMI4Update::WriteSignatureV7(enum signature_BLv7 signature_partition, unsigned char* data, int offset) +{ + fprintf(stdout, "Write Signature...\n"); + int rc; + unsigned char off[2] = {0, 0}; + unsigned char cmd_buf[1]; + unsigned short dataAddr = m_f34.GetDataBase(); + int transfer_leng = 0; + signature_info signature = m_firmwareImage.GetSignatureInfo()[signature_partition]; + unsigned char trans_leng_buf[2]; + unsigned short left_bytes; + unsigned short write_size; + unsigned short max_write_size; + unsigned char *data_temp; + int retry = 0; + rc = m_device.Write(dataAddr + 2, off, sizeof(off)); + if (rc != sizeof(off)) + return UPDATE_FAIL_WRITE_INITIAL_ZEROS; + + // Set Transfer Length + transfer_leng = signature.size / m_blockSize; + trans_leng_buf[0] = (unsigned char)(transfer_leng & 0xFF); + trans_leng_buf[1] = (unsigned char)((transfer_leng & 0xFF00) >> 8); + + rc = m_device.Write(dataAddr + 3, trans_leng_buf, sizeof(trans_leng_buf)); + if (rc != sizeof(trans_leng_buf)) + return UPDATE_FAIL_WRITE_FLASH_COMMAND; + + // Set Command to Signature + cmd_buf[0] = (unsigned char)CMD_V7_SIGNATURE; + rc = m_device.Write(dataAddr + 4, cmd_buf, sizeof(cmd_buf)); + if (rc != sizeof(cmd_buf)) + return UPDATE_FAIL_WRITE_FLASH_COMMAND; + + max_write_size = 16; + if (max_write_size >= transfer_leng * m_blockSize) + max_write_size = transfer_leng * m_blockSize; + else if (max_write_size > m_blockSize) + max_write_size -= max_write_size % m_blockSize; + else + max_write_size = m_blockSize; + + left_bytes = transfer_leng * m_blockSize; + + do { + if (left_bytes / max_write_size) + write_size = max_write_size; + else + write_size = left_bytes; + + data_temp = (unsigned char *) malloc(sizeof(unsigned char) * write_size); + memcpy(data_temp, data + offset, sizeof(char) * write_size); + rc = m_device.Write(dataAddr + 5, data_temp, sizeof(char) * write_size); + if (rc != ((ssize_t)sizeof(char) * write_size)) { + fprintf(stdout, "err write_size = %d; rc = %d\n", write_size, rc); + return UPDATE_FAIL_WRITE_BLOCK; + } + + offset += write_size; + left_bytes -= write_size; + free(data_temp); + } while (left_bytes); + + // Wair for attention for touchpad only. + rc = WaitForIdle(RMI_F34_IDLE_WAIT_MS, false); + if (rc != UPDATE_SUCCESS) { + fprintf(stderr, "%s: %s\n", __func__, update_err_to_string(rc)); + return UPDATE_FAIL_TIMEOUT_WAITING_FOR_ATTN; + } + + //Wait for completion + do { + Sleep(20); + rmi4update_poll(); + if (m_flashStatus == SUCCESS){ + break; + } + retry++; + } while(retry < 20); + + if (m_flashStatus != SUCCESS) { + fprintf(stdout, "err flash_status = %d\n", m_flashStatus); + return UPDATE_FAIL_WRITE_F01_CONTROL_0; + } + return UPDATE_SUCCESS; +} + /* * This is a limited implementation of WaitForIdle which assumes WaitForAttention is supported * this will be true for HID, but other protocols will need to revert polling. Polling diff --git a/rmi4update/rmi4update.h b/rmi4update/rmi4update.h index b9de4ec..ee77228 100755 --- a/rmi4update/rmi4update.h +++ b/rmi4update/rmi4update.h @@ -62,6 +62,7 @@ enum v7_flash_command { CMD_V7_ERASE, CMD_V7_ERASE_AP, CMD_V7_SENSOR_ID, + CMD_V7_SIGNATURE, }; enum bl_version { @@ -179,6 +180,7 @@ private: int WaitForIdle(int timeout_ms, bool readF34OnSucess = true); int GetFirmwareSize() { return m_blockSize * m_fwBlockCount; } int GetConfigSize() { return m_blockSize * m_configBlockCount; } + int WriteSignatureV7(enum signature_BLv7 signature_partition, unsigned char* data, int offset); private: RMIDevice & m_device; |