summaryrefslogtreecommitdiff
path: root/src/mts_hdr_copy.c
blob: 2f1da3ec670cf1c4dfce02582d224d36cea2c218 (plain)
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
100
101
102
103
104
105
/*
 * Read in the 1st 52 4 byte words, and if over half
 * match, write the majority value to stdout.
 * This is intended to look at the ROMBOOT header for
 * bootstrap that sets the NAND flash parameters
 * for ATMEL's ROMBOOT to load bootstrap.
 */
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

#ifdef DEBUG
    #define DBGPRT(fmt,...) fprintf(stderr,fmt,##__VA_ARGS__)
#else
    #define DBGPRT(fmt,...)
#endif

int
compare(const void *a, const void *b)
{
	unsigned int a1 = *((const unsigned int *)a);
	unsigned int b1 = *((const unsigned int *)b);
	if(a1 < b1) return -1;
	if(a1 > b1) return 1;
	return 0;
}

#define NMEMB 52
int
main(int argc, char *argv)
{
	unsigned int header[NMEMB];
	int i,count;
        int nmax, lastmax;
        unsigned int previous, lastmaxval;
        
        if(argc > 1) {
            fprintf(stderr,
                "Usage:\n"
                "   cat /dev/mtd1 | mts_hdr_copy >/tmp/hdr.bin\n"
                "       This comand reads standard input, and if over\n"
                "       half the 32 bit words for the first 52 words\n"
                "       are in agreement, 52 copies of the 32 bit word\n"
                "       are written to stdout.  Otherwise we exit with\n"
                "       status 1.  This command is intended to read the\n"
                "       existing bootstrap in /dev/mtd1, to create a\n"
                "       new bootstrap\n"
            );
            exit(0);
        }

	count = read(0,header,sizeof header);

	if (count != sizeof header) {
		DBGPRT("Could not read complete input\n");
		exit(1);
	}
	qsort(header,NMEMB,sizeof(header[0]),compare);
	
	for (i=0;i<NMEMB;i++)
		DBGPRT("0x%8.8x\n",header[i]);
        
        nmax = 0, lastmax = -1;
        lastmaxval = 0;
        previous = header[0]+1;
        
        for (i=0;i<NMEMB;i++) {
            DBGPRT("Considering 0x%x, previous 0x%x\n",header[i],previous);
            if (previous == header[i]) {
                nmax++;
                DBGPRT("Matches, i=%d 0x%x, nmax=%d\n",i,header[i],nmax);
            } else {
                if (nmax > lastmax) {
                    lastmax = nmax;
                    DBGPRT("nmax > lastmax, lastmax %d\n",lastmax);
                    lastmaxval = previous;
                }
                previous = header[i];
                nmax = 1;
            }
        }
        if (nmax > lastmax) {
                lastmax = nmax;
                lastmaxval = previous;
        }
        DBGPRT("lastmax=%d\n",lastmax);
        if (lastmax > NMEMB/2) {
            for (i=0; i< NMEMB; i++)
                header[i] = lastmaxval;
            fprintf(stderr,"Attempting to write 52 copies of 0x%8.8x\n",lastmaxval);
            if ((count = write(1,header,sizeof header)) == sizeof header)
                exit(0);
            else {
                if(count >= 0)
                    fprintf(stderr,"ERROR: Wrote only %d of %llu bytes\n",count,(unsigned long long)(sizeof header));
                else
                    perror("Error writing header");
            }
        }
        fprintf(stderr,"ERROR: Found value 0x%x %d times out of 52 possible\n",lastmaxval,lastmax);
	return 1;
}