/* Checksum computing for DG834 * * Checksum is computed by adding bytes from 0 to 0x3dfffb. * The 16 bit sum must be equal to the little endian 16 bit word stored at * 0x3dfffc-03dfffd. */ #include #include /* load a file in memory */ static int read_file(const char *filename, long *size, void **buffer) { FILE *fp; /* open file for reading */ fp = fopen(filename, "rb"); if (fp == NULL) { fprintf(stderr, "Could not open <%s>\n", filename); return 1; } /* compute file size */ if (fseek(fp, 0, SEEK_END) != 0) { fprintf(stderr, "Could not open <%s>\n", filename); fclose(fp); return 1; } *size = ftell(fp); fseek(fp, 0, SEEK_SET); if (*size == -1) { fprintf(stderr, "Could not get size of file <%s>\n", filename); fclose(fp); return 1; } /* allocate memory to read the file */ *buffer = malloc(*size); if (*buffer == NULL) { fprintf(stderr, "Could not alloc mem to read file <%s>\n", filename); fclose(fp); return 1; } /* read the file */ if (fread(*buffer, 1, *size, fp) != *size) { fprintf(stderr, "Could not read file <%s>\n", filename); fclose(fp); return 1; } /* we're done */ fclose(fp); return 0; } /* read 8 bit */ static unsigned short read_8(unsigned char *mem, unsigned int addr) { return mem[addr]; } /* read a 16 bit word in little endian */ static unsigned short read_16l(unsigned char *mem, unsigned int addr) { return mem[addr] | (mem[addr+1] << 8); } /* compute check sum */ static unsigned short compute_checksum(unsigned char *mem) { unsigned int addr; unsigned short word; unsigned short checksum; checksum = 0; for (addr = 0; addr < 0x3dfffc; addr++) { word = read_8(mem, addr); checksum += word; } return checksum; } int main(int argc, const char *argv[]) { const char *filename; long size; void *mem; unsigned short checksum; /* command line */ if (argc != 2) { fprintf(stderr, "Usage: %s firmware\n", argv[0]); return 1; } filename = argv[1]; /* read file in memory */ if (read_file(filename, &size, &mem) != 0) { return 2; } if (size != 0x3e0000) { fprintf(stderr, "File <%s> has wrong size\n", filename); return 3; } /* compute checksum */ checksum = compute_checksum(mem); /* check it's OK */ printf("Computed checksum is %04x\n", checksum); printf("Stored checksum is %04x\n", read_16l(mem, 0x3dfffc)); if (checksum != read_16l(mem, 0x3dfffc)) { printf("WARNING: checksum does not match!\n"); } /* time to leave */ free(mem); return 0; }