@ -36,6 +36,8 @@
# include "crc32.h"
# include "crc32.h"
# define TRX_MAGIC 0x30524448 /* "HDR0" */
# define TRX_MAGIC 0x30524448 /* "HDR0" */
# define TRX_CRC32_DATA_OFFSET 12 /* First 12 bytes are not covered by CRC32 */
# define TRX_CRC32_DATA_SIZE 16
struct trx_header {
struct trx_header {
uint32_t magic ; /* "HDR0" */
uint32_t magic ; /* "HDR0" */
uint32_t len ; /* Length of file including header */
uint32_t len ; /* Length of file including header */
@ -148,8 +150,9 @@ trx_check(int imagefd, const char *mtd, char *buf, int *len)
# endif
# endif
int
int
mtd_fixtrx ( const char * mtd , size_t offset )
mtd_fixtrx ( const char * mtd , size_t offset , size_t data_size )
{
{
size_t data_offset ;
int fd ;
int fd ;
struct trx_header * trx ;
struct trx_header * trx ;
char * first_block ;
char * first_block ;
@ -166,10 +169,16 @@ mtd_fixtrx(const char *mtd, size_t offset)
exit ( 1 ) ;
exit ( 1 ) ;
}
}
data_offset = offset + TRX_CRC32_DATA_OFFSET ;
if ( data_size )
data_size + = TRX_CRC32_DATA_SIZE ;
else
data_size = erasesize - TRX_CRC32_DATA_OFFSET ;
block_offset = offset & ~ ( erasesize - 1 ) ;
block_offset = offset & ~ ( erasesize - 1 ) ;
offset - = block_offset ;
offset - = block_offset ;
if ( block_offset + erasesize > mtdsize ) {
if ( data_offset + data_ size > mtdsize ) {
fprintf ( stderr , " Offset too large, device size 0x%x \n " , mtdsize ) ;
fprintf ( stderr , " Offset too large, device size 0x%x \n " , mtdsize ) ;
exit ( 1 ) ;
exit ( 1 ) ;
}
}
@ -192,28 +201,28 @@ mtd_fixtrx(const char *mtd, size_t offset)
exit ( 1 ) ;
exit ( 1 ) ;
}
}
if ( trx - > len = = STORE32_LE ( erasesize - offset ) ) {
if ( trx - > len = = STORE32_LE ( data_size + TRX_CRC32_DATA_OFFSET ) ) {
if ( quiet < 2 )
if ( quiet < 2 )
fprintf ( stderr , " Header already fixed, exiting \n " ) ;
fprintf ( stderr , " Header already fixed, exiting \n " ) ;
close ( fd ) ;
close ( fd ) ;
return 0 ;
return 0 ;
}
}
buf = malloc ( erase size) ;
buf = malloc ( data_ size) ;
if ( ! buf ) {
if ( ! buf ) {
perror ( " malloc " ) ;
perror ( " malloc " ) ;
exit ( 1 ) ;
exit ( 1 ) ;
}
}
res = pread ( fd , buf , erasesize , block _offset) ;
res = pread ( fd , buf , data_size , data _offset) ;
if ( res ! = erase size) {
if ( res ! = data_ size) {
perror ( " pread " ) ;
perror ( " pread " ) ;
exit ( 1 ) ;
exit ( 1 ) ;
}
}
trx - > len = STORE32_LE ( erasesize - offset ) ;
trx - > len = STORE32_LE ( data_size + offsetof ( struct trx_header , flag_version ) ) ;
trx - > crc32 = STORE32_LE ( crc32buf ( ( char * ) & trx - > flag_version , erasesize - offset - 3 * 4 ) ) ;
trx - > crc32 = STORE32_LE ( crc32buf ( buf , data_size ) ) ;
if ( mtd_erase_block ( fd , block_offset ) ) {
if ( mtd_erase_block ( fd , block_offset ) ) {
fprintf ( stderr , " Can't erease block at 0x%x (%s) \n " , block_offset , strerror ( errno ) ) ;
fprintf ( stderr , " Can't erease block at 0x%x (%s) \n " , block_offset , strerror ( errno ) ) ;
exit ( 1 ) ;
exit ( 1 ) ;