29
29
#define EXPECTED_SIG_TLV IMAGE_TLV_ED25519
30
30
#endif
31
31
32
+ #define DECOMP_BUF_SIZE CONFIG_BOOT_DECOMPRESSION_BUFFER_SIZE
33
+ #if defined(CONFIG_NRF_COMPRESS_ARM_THUMB )
34
+ #define DECOMP_BUF_EXTRA_SIZE 2
35
+ #else
36
+ #define DECOMP_BUF_EXTRA_SIZE 0
37
+ #endif
38
+ #define DECOMP_BUF_ALLOC_SIZE (DECOMP_BUF_SIZE + DECOMP_BUF_EXTRA_SIZE)
39
+
32
40
/* Number of times that consumed data by decompression system can be 0 in a row before aborting */
33
41
#define OFFSET_ZERO_CHECK_TIMES 3
34
42
@@ -317,11 +325,6 @@ int bootutil_img_hash_decompress(struct enc_key_data *enc_state, int image_index
317
325
BOOT_LOG_ERR ("Decompression error: %d" , rc );
318
326
rc = BOOT_EBADSTATUS ;
319
327
goto finish ;
320
- } else if (current_size != offset_arm_thumb ) {
321
- BOOT_LOG_ERR ("Decompression expected offset mismatch: %d vs %d" ,
322
- current_size , offset_arm_thumb );
323
- rc = BOOT_EBADSTATUS ;
324
- goto finish ;
325
328
}
326
329
327
330
bootutil_sha_update (& sha_ctx , output_arm_thumb , output_size_arm_thumb );
@@ -863,7 +866,7 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl
863
866
struct nrf_compress_implementation * compression_lzma = NULL ;
864
867
struct nrf_compress_implementation * compression_arm_thumb = NULL ;
865
868
struct image_header * hdr ;
866
- TARGET_STATIC uint8_t decomp_buf [CONFIG_BOOT_DECOMPRESSION_BUFFER_SIZE ] __attribute__((aligned (4 )));
869
+ TARGET_STATIC uint8_t decomp_buf [DECOMP_BUF_ALLOC_SIZE ] __attribute__((aligned (4 )));
867
870
TARGET_STATIC struct image_header modified_hdr ;
868
871
869
872
hdr = boot_img_hdr (state , BOOT_SECONDARY_SLOT );
@@ -950,6 +953,10 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl
950
953
while (pos < hdr -> ih_img_size ) {
951
954
uint32_t copy_size = hdr -> ih_img_size - pos ;
952
955
uint32_t tmp_off = 0 ;
956
+ #if defined(CONFIG_NRF_COMPRESS_ARM_THUMB )
957
+ uint8_t excess_data_buffer [DECOMP_BUF_EXTRA_SIZE ];
958
+ bool excess_data_buffer_full = false;
959
+ #endif
953
960
954
961
if (copy_size > buf_size ) {
955
962
copy_size = buf_size ;
@@ -985,8 +992,8 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl
985
992
last_packet = true;
986
993
}
987
994
988
- rc = compression_lzma -> decompress (NULL , & buf [tmp_off ], chunk_size , last_packet , & offset ,
989
- & output , & output_size );
995
+ rc = compression_lzma -> decompress (NULL , & buf [tmp_off ], chunk_size , last_packet ,
996
+ & offset , & output , & output_size );
990
997
991
998
if (rc ) {
992
999
BOOT_LOG_ERR ("Decompression error: %d" , rc );
@@ -996,42 +1003,55 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl
996
1003
997
1004
/* Copy data to secondary buffer for writing out */
998
1005
while (output_size > 0 ) {
999
- uint32_t data_size = (sizeof ( decomp_buf ) - decomp_buf_size );
1006
+ uint32_t data_size = (DECOMP_BUF_SIZE - decomp_buf_size );
1000
1007
1001
1008
if (data_size > output_size ) {
1002
1009
data_size = output_size ;
1003
1010
}
1004
1011
1005
- memcpy (& decomp_buf [decomp_buf_size ], & output [compression_buffer_pos ], data_size );
1012
+ #if defined(CONFIG_NRF_COMPRESS_ARM_THUMB )
1013
+ if (hdr -> ih_flags & IMAGE_F_COMPRESSED_ARM_THUMB_FLT ) {
1014
+ memcpy (& decomp_buf [decomp_buf_size + DECOMP_BUF_EXTRA_SIZE ],
1015
+ & output [compression_buffer_pos ], data_size );
1016
+ } else
1017
+ #endif
1018
+ {
1019
+ memcpy (& decomp_buf [decomp_buf_size ], & output [compression_buffer_pos ],
1020
+ data_size );
1021
+ }
1022
+
1006
1023
compression_buffer_pos += data_size ;
1007
1024
1008
1025
decomp_buf_size += data_size ;
1009
1026
output_size -= data_size ;
1010
1027
1011
1028
/* Write data out from secondary buffer when it is full */
1012
- if (decomp_buf_size == sizeof (decomp_buf )) {
1029
+ if (decomp_buf_size == DECOMP_BUF_SIZE ) {
1030
+ #if defined(CONFIG_NRF_COMPRESS_ARM_THUMB )
1013
1031
if (hdr -> ih_flags & IMAGE_F_COMPRESSED_ARM_THUMB_FLT ) {
1014
- /* Run this through the ARM thumb filter */
1015
- uint32_t offset_arm_thumb = 0 ;
1016
- uint32_t output_size_arm_thumb = 0 ;
1032
+ uint32_t filter_writeback_pos = 0 ;
1017
1033
uint32_t processed_size = 0 ;
1018
- uint8_t * output_arm_thumb = NULL ;
1019
1034
1020
- while (processed_size < sizeof (decomp_buf )) {
1021
- uint32_t current_size = sizeof (decomp_buf );
1035
+ /* Run this through the ARM thumb filter */
1036
+ while (processed_size < DECOMP_BUF_SIZE ) {
1037
+ uint32_t offset_arm_thumb = 0 ;
1038
+ uint32_t output_size_arm_thumb = 0 ;
1039
+ uint8_t * output_arm_thumb = NULL ;
1040
+ uint32_t current_size = DECOMP_BUF_SIZE ;
1022
1041
bool arm_thumb_last_packet = false;
1023
1042
1024
1043
if (current_size > CONFIG_NRF_COMPRESS_CHUNK_SIZE ) {
1025
1044
current_size = CONFIG_NRF_COMPRESS_CHUNK_SIZE ;
1026
1045
}
1027
1046
1028
- if (last_packet && (processed_size + current_size ) ==
1029
- sizeof ( decomp_buf ) ) {
1047
+ if (last_packet && (processed_size + current_size ) == DECOMP_BUF_SIZE
1048
+ && output_size == 0 ) {
1030
1049
arm_thumb_last_packet = true;
1031
1050
}
1032
1051
1033
1052
rc = compression_arm_thumb -> decompress (NULL ,
1034
- & decomp_buf [processed_size ],
1053
+ & decomp_buf [processed_size +
1054
+ DECOMP_BUF_EXTRA_SIZE ],
1035
1055
current_size ,
1036
1056
arm_thumb_last_packet ,
1037
1057
& offset_arm_thumb ,
@@ -1044,25 +1064,70 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl
1044
1064
goto finish ;
1045
1065
}
1046
1066
1047
- memcpy (& decomp_buf [processed_size ], output_arm_thumb , current_size );
1067
+ memcpy (& decomp_buf [filter_writeback_pos ], output_arm_thumb ,
1068
+ output_size_arm_thumb );
1069
+ filter_writeback_pos += output_size_arm_thumb ;
1048
1070
processed_size += current_size ;
1049
1071
}
1050
- }
1051
1072
1052
- rc = flash_area_write (fap_dst , (off_dst + hdr -> ih_hdr_size + write_pos ),
1053
- decomp_buf , sizeof (decomp_buf ));
1073
+ if (excess_data_buffer_full == true)
1074
+ {
1075
+ /* Restore extra data removed from previous iteration to the write
1076
+ * buffer
1077
+ */
1078
+ memmove (& decomp_buf [DECOMP_BUF_EXTRA_SIZE ], decomp_buf ,
1079
+ filter_writeback_pos );
1080
+ memcpy (decomp_buf , excess_data_buffer , DECOMP_BUF_EXTRA_SIZE );
1081
+ excess_data_buffer_full = false;
1082
+ filter_writeback_pos += DECOMP_BUF_EXTRA_SIZE ;
1083
+ }
1054
1084
1055
- if (rc != 0 ) {
1056
- BOOT_LOG_ERR (
1057
- "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d" ,
1058
- (off_dst + hdr -> ih_hdr_size + write_pos ), sizeof (decomp_buf ),
1059
- fap_dst -> fa_id , rc );
1060
- rc = BOOT_EFLASH ;
1061
- goto finish ;
1062
- }
1085
+ if ((filter_writeback_pos % sizeof (uint32_t )) != 0 )
1086
+ {
1087
+ /* Since there are an extra 2 bytes here, remove them and stash for
1088
+ * later usage to prevent flash write issues with non-word boundary
1089
+ * writes
1090
+ */
1091
+ memcpy (excess_data_buffer , & decomp_buf [filter_writeback_pos -
1092
+ DECOMP_BUF_EXTRA_SIZE ],
1093
+ DECOMP_BUF_EXTRA_SIZE );
1094
+ excess_data_buffer_full = true;
1095
+ filter_writeback_pos -= DECOMP_BUF_EXTRA_SIZE ;
1096
+ }
1097
+
1098
+ rc = flash_area_write (fap_dst , (off_dst + hdr -> ih_hdr_size + write_pos ),
1099
+ decomp_buf , filter_writeback_pos );
1100
+
1101
+ if (rc != 0 ) {
1102
+ BOOT_LOG_ERR (
1103
+ "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d" ,
1104
+ (off_dst + hdr -> ih_hdr_size + write_pos ), DECOMP_BUF_SIZE ,
1105
+ fap_dst -> fa_id , rc );
1106
+ rc = BOOT_EFLASH ;
1107
+ goto finish ;
1108
+ }
1109
+
1110
+ write_pos += filter_writeback_pos ;
1111
+ decomp_buf_size = 0 ;
1112
+ filter_writeback_pos = 0 ;
1113
+ } else
1114
+ #endif
1115
+ {
1116
+ rc = flash_area_write (fap_dst , (off_dst + hdr -> ih_hdr_size + write_pos ),
1117
+ decomp_buf , DECOMP_BUF_SIZE );
1118
+
1119
+ if (rc != 0 ) {
1120
+ BOOT_LOG_ERR (
1121
+ "Flash write failed at offset: 0x%x, size: 0x%x, area: %d, rc: %d" ,
1122
+ (off_dst + hdr -> ih_hdr_size + write_pos ), DECOMP_BUF_SIZE ,
1123
+ fap_dst -> fa_id , rc );
1124
+ rc = BOOT_EFLASH ;
1125
+ goto finish ;
1126
+ }
1063
1127
1064
- write_pos += sizeof (decomp_buf );
1065
- decomp_buf_size = 0 ;
1128
+ write_pos += DECOMP_BUF_SIZE ;
1129
+ decomp_buf_size = 0 ;
1130
+ }
1066
1131
}
1067
1132
}
1068
1133
@@ -1072,6 +1137,27 @@ int boot_copy_region_decompress(struct boot_loader_state *state, const struct fl
1072
1137
pos += copy_size ;
1073
1138
}
1074
1139
1140
+ #if defined(CONFIG_NRF_COMPRESS_ARM_THUMB )
1141
+ if (hdr -> ih_flags & IMAGE_F_COMPRESSED_ARM_THUMB_FLT && decomp_buf_size > 0 ) {
1142
+ /* Extra data that has not been written out that needs ARM thumb filter applied */
1143
+ uint32_t offset_arm_thumb = 0 ;
1144
+ uint32_t output_size_arm_thumb = 0 ;
1145
+ uint8_t * output_arm_thumb = NULL ;
1146
+
1147
+ rc = compression_arm_thumb -> decompress (NULL , & decomp_buf [DECOMP_BUF_EXTRA_SIZE ],
1148
+ decomp_buf_size , true, & offset_arm_thumb ,
1149
+ & output_arm_thumb , & output_size_arm_thumb );
1150
+
1151
+ if (rc ) {
1152
+ BOOT_LOG_ERR ("Decompression error: %d" , rc );
1153
+ rc = BOOT_EBADSTATUS ;
1154
+ goto finish ;
1155
+ }
1156
+
1157
+ memcpy (decomp_buf , output_arm_thumb , output_size_arm_thumb );
1158
+ }
1159
+ #endif
1160
+
1075
1161
/* Clean up decompression system */
1076
1162
(void )compression_lzma -> deinit (NULL );
1077
1163
(void )compression_arm_thumb -> deinit (NULL );
0 commit comments