aboutsummaryrefslogtreecommitdiffstats
path: root/tool/mbed/lpc-vector-checksum.c
blob: 316a1253a0e0fe68c5493e0018cc2bc575b123c2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/***************************************************************************
* https://github.com/dhylands/projects/blob/master/lpc/lpc-vector-checksum/lpc-vector-checksum.c
*
*     Copyright (c) 2012 by Dave Hylands
*           All Rights Reserved
*
*	Permission is granted to any individual or institution to use, copy,
*  modify, or redistribute this file so long as it is not sold for profit,
*  and that this copyright notice is retained.
*
***************************************************************************
*
*  This program calculates the vector checksum used in LPC17xx binary
*  images.
*
*  Usage:   lpc-vector-checksum file
*
***************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>

/***************************************************************************/
/**
*   update_vector_checksum
*  
*   The algorithim is to write the checksum such that the checksum of the
*   first 8 words is equal to zero.
*  
*   The LPC1768 uses little-endian, and this particular routine assumes
*   that it's running on a little-endian architecture.
*/
static int update_vector_checksum( const char *filename )
{
    uint32_t    sum;
    uint32_t    header[8];
    FILE       *fs;
    int         i;

    if (( fs = fopen( filename, "r+b" )) == NULL )
    {
        fprintf( stderr, "Unable to open '%s' for reading/writing (%d): %s\n", 
                 filename, errno, strerror( errno ));
        return 0;
    }

    if ( fread( header, sizeof( header ), 1, fs ) != 1 )
    {
        fprintf( stderr, "Failed to read header from '%s' (perhaps the file is too small?)",
                 filename );
        fclose( fs );
        return 0;
    }

    sum = 0;
    for ( i = 0; i < 7; i++ )
    {
        sum += header[i];
    }
    printf( "sum = 0x%08x, value to write = 0x%08x\n", sum, -sum );

    /* write back the checksum to location 7
     * http://sigalrm.blogspot.jp/2011/10/cortex-m3-exception-vector-checksum.html
     */
    fseek(fs, 0x1c, SEEK_SET);
    sum = -sum;
    fwrite(&sum, 4, 1, fs);

    fclose( fs );

    return 1;
}

/***************************************************************************/
/**
*   main
*/
int main( int argc, char **argv )
{
    int arg;

    if ( argc < 2)
    {
        fprintf( stderr, "Usage: lpc-vector-checksum file ...\n" );
        exit( 1 );
    }

    for ( arg = 1; arg < argc; arg++ )
    {
        update_vector_checksum( argv[ arg ]);
    }

    exit( 0 );
    return 0;
}