1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2011 Samsung Electronics
4 */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <fcntl.h>
10 #include <errno.h>
11 #include <string.h>
12 #include <sys/stat.h>
13
14 #define CHECKSUM_OFFSET (14*1024-4)
15 #define BUFSIZE (16*1024)
16 #define FILE_PERM (S_IRUSR | S_IWUSR | S_IRGRP \
17 | S_IWGRP | S_IROTH | S_IWOTH)
18 /*
19 * Requirement:
20 * IROM code reads first 14K bytes from boot device.
21 * It then calculates the checksum of 14K-4 bytes and compare with data at
22 * 14K-4 offset.
23 *
24 * This function takes two filenames:
25 * IN "u-boot-spl.bin" and
26 * OUT "u-boot-mmc-spl.bin" as filenames.
27 * It reads the "u-boot-spl.bin" in 16K buffer.
28 * It calculates checksum of 14K-4 Bytes and stores at 14K-4 offset in buffer.
29 * It writes the buffer to "u-boot-mmc-spl.bin" file.
30 */
31
main(int argc,char ** argv)32 int main(int argc, char **argv)
33 {
34 int i, len;
35 unsigned char buffer[BUFSIZE] = {0};
36 int ifd, ofd;
37 unsigned int checksum = 0, count;
38
39 if (argc != 3) {
40 printf(" %d Wrong number of arguments\n", argc);
41 exit(EXIT_FAILURE);
42 }
43
44 ifd = open(argv[1], O_RDONLY);
45 if (ifd < 0) {
46 fprintf(stderr, "%s: Can't open %s: %s\n",
47 argv[0], argv[1], strerror(errno));
48 exit(EXIT_FAILURE);
49 }
50
51 ofd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, FILE_PERM);
52 if (ofd < 0) {
53 fprintf(stderr, "%s: Can't open %s: %s\n",
54 argv[0], argv[2], strerror(errno));
55 if (ifd)
56 close(ifd);
57 exit(EXIT_FAILURE);
58 }
59
60 len = lseek(ifd, 0, SEEK_END);
61 lseek(ifd, 0, SEEK_SET);
62
63 count = (len < CHECKSUM_OFFSET) ? len : CHECKSUM_OFFSET;
64
65 if (read(ifd, buffer, count) != count) {
66 fprintf(stderr, "%s: Can't read %s: %s\n",
67 argv[0], argv[1], strerror(errno));
68
69 if (ifd)
70 close(ifd);
71 if (ofd)
72 close(ofd);
73
74 exit(EXIT_FAILURE);
75 }
76
77 for (i = 0, checksum = 0; i < CHECKSUM_OFFSET; i++)
78 checksum += buffer[i];
79
80 memcpy(&buffer[CHECKSUM_OFFSET], &checksum, sizeof(checksum));
81
82 if (write(ofd, buffer, BUFSIZE) != BUFSIZE) {
83 fprintf(stderr, "%s: Can't write %s: %s\n",
84 argv[0], argv[2], strerror(errno));
85
86 if (ifd)
87 close(ifd);
88 if (ofd)
89 close(ofd);
90
91 exit(EXIT_FAILURE);
92 }
93
94 if (ifd)
95 close(ifd);
96 if (ofd)
97 close(ofd);
98
99 return EXIT_SUCCESS;
100 }
101