1 /* 2 * Copyright (C) 2012 Samsung Electronics 3 * 4 * See file CREDITS for list of people who contributed to this 5 * project. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of 10 * the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 20 * MA 02111-1307 USA 21 */ 22 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <unistd.h> 26 #include <fcntl.h> 27 #include <errno.h> 28 #include <string.h> 29 #include <sys/stat.h> 30 #include <compiler.h> 31 32 #define CHECKSUM_OFFSET (14*1024-4) 33 #define BUFSIZE (14*1024) 34 #define FILE_PERM (S_IRUSR | S_IWUSR | S_IRGRP \ 35 | S_IWGRP | S_IROTH | S_IWOTH) 36 /* 37 * Requirement: 38 * IROM code reads first 14K bytes from boot device. 39 * It then calculates the checksum of 14K-4 bytes and compare with data at 40 * 14K-4 offset. 41 * 42 * This function takes two filenames: 43 * IN "u-boot-spl.bin" and 44 * OUT "$(BOARD)-spl.bin as filenames. 45 * It reads the "u-boot-spl.bin" in 16K buffer. 46 * It calculates checksum of 14K-4 Bytes and stores at 14K-4 offset in buffer. 47 * It writes the buffer to "$(BOARD)-spl.bin" file. 48 */ 49 50 int main(int argc, char **argv) 51 { 52 unsigned char buffer[BUFSIZE]; 53 int i, ifd, ofd; 54 uint32_t checksum = 0; 55 off_t len; 56 ssize_t count; 57 struct stat stat; 58 59 if (argc != 3) { 60 fprintf(stderr, "Usage: %s <infile> <outfile>\n", argv[0]); 61 exit(EXIT_FAILURE); 62 } 63 64 ifd = open(argv[1], O_RDONLY); 65 if (ifd < 0) { 66 fprintf(stderr, "%s: Can't open %s: %s\n", 67 argv[0], argv[1], strerror(errno)); 68 exit(EXIT_FAILURE); 69 } 70 71 ofd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, FILE_PERM); 72 if (ifd < 0) { 73 fprintf(stderr, "%s: Can't open %s: %s\n", 74 argv[0], argv[2], strerror(errno)); 75 close(ifd); 76 exit(EXIT_FAILURE); 77 } 78 79 if (fstat(ifd, &stat)) { 80 fprintf(stderr, "%s: Unable to get size of %s: %s\n", 81 argv[0], argv[1], strerror(errno)); 82 close(ifd); 83 close(ofd); 84 exit(EXIT_FAILURE); 85 } 86 87 len = stat.st_size; 88 89 count = (len < CHECKSUM_OFFSET) ? len : CHECKSUM_OFFSET; 90 91 if (read(ifd, buffer, count) != count) { 92 fprintf(stderr, "%s: Can't read %s: %s\n", 93 argv[0], argv[1], strerror(errno)); 94 95 close(ifd); 96 close(ofd); 97 98 exit(EXIT_FAILURE); 99 } 100 101 for (i = 0, checksum = 0; i < CHECKSUM_OFFSET; i++) 102 checksum += buffer[i]; 103 104 checksum = cpu_to_le32(checksum); 105 106 memcpy(&buffer[CHECKSUM_OFFSET], &checksum, sizeof(checksum)); 107 108 if (write(ofd, buffer, BUFSIZE) != BUFSIZE) { 109 fprintf(stderr, "%s: Can't write %s: %s\n", 110 argv[0], argv[2], strerror(errno)); 111 112 close(ifd); 113 close(ofd); 114 115 exit(EXIT_FAILURE); 116 } 117 118 close(ifd); 119 close(ofd); 120 121 return EXIT_SUCCESS; 122 } 123