summaryrefslogtreecommitdiff
path: root/src/mts_hdr_copy.c
blob: dfd6472ae744ae61d8f2688463a375e85cdff62d (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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * 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 <getopt.h>
#include <string.h>
#include <errno.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;
}

void
usage(void)
{
    fprintf(stderr,
        "Usage:\n"
        "   mts-hdr-copy /dev/mtd1 >/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(1);
}

#define NMEMB 52
int
main(int argc, char *argv[])
{
	unsigned int header[NMEMB];
	int i,count,opt;
        int nmax, lastmax, fd;
        unsigned int previous, lastmaxval;
        
        fclose(stdin);
        
        while((opt = getopt(argc,argv,"")) != -1) switch(opt){
        case 'h':
            usage();
            break;
        default:
            usage();
            break;
        }
        if(argc - optind != 1) {
            fprintf(stderr,"Missing device parameter\n");
            usage();
            exit(0);
        }

        fd = open(argv[optind],O_RDONLY);
        
        if (fd == -1) {
            fprintf(stderr,"mts-hdr-copy: File argument \"%s\" could not be opened: %s\n",
                    argv[optind],strerror(errno));
            usage();
        }
        
	count = read(fd,header,sizeof header);
        close(fd);

	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 for the bootstrap header\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;
}