/* zImage_util.c * * Copyright 2003 Robert Whaley * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #define CMDLINE_LIMIT 1024 #define REGISTERS_LIMIT 8192 typedef struct _file_header { unsigned long Size; unsigned long CheckSum; unsigned long Date; unsigned long Version; unsigned long Count; unsigned long BootStatus; char cmdline[CMDLINE_LIMIT]; char registers[REGISTERS_LIMIT]; } FileHeader; #define BUF_SIZE (2*1024*1024) char buf[BUF_SIZE]; int fix_cmdline_end(char *cmdline, int end) { while (end && (cmdline[end] == 0 || cmdline[end] == ' ' || cmdline[end] == '\n' || cmdline[end] == '\r' || cmdline[end] == '\t')) { cmdline[end--] = 0; } return end; } unsigned long checksum(char *data, unsigned long len) { unsigned long result; int i; result = 0; for (i=0; itm_sec) / 2; result |= 0x000007e0 & (dt->tm_min << 5); result |= 0x0000f100 & (dt->tm_hour << 11); result |= 0x001f0000 & (dt->tm_mday << 16); result |= 0x01e00000 & ((dt->tm_mon + 1) << 21); result |= 0xfe000000 & ((dt->tm_year - 80) << 25); return result; } struct tm * convert_from_dos_date_time(unsigned long dos_dt) { static struct tm result; result.tm_sec = (0x0000001f & dos_dt) * 2; result.tm_min = (0x000007e0 & dos_dt) >> 5; result.tm_hour = (0x0000f100 & dos_dt) >> 11; result.tm_mday = (0x001f0000 & dos_dt) >> 16; result.tm_mon = ((0x01e00000 & dos_dt) >> 21) - 1; result.tm_year = ((0xfe000000 & dos_dt) >> 25) + 80; return &result; } void list_zImage_partition(int partition_fd) { FileHeader fh; int zImage_size; int res; int computed_checksum = 0; res = read(partition_fd, (char *)&fh, sizeof(fh)); if (res != sizeof(fh)) { perror("Error reading partition\n"); exit(-1); } res = read(partition_fd, buf, fh.Size); if (res != fh.Size) { perror("Error reading partition\n"); printf("Error expected zImage of %d bytes but only read %d bytes\n", fh.Size, res); exit(-1); } computed_checksum = checksum(buf, fh.Size); printf("zImage size: %d\n", fh.Size); printf("header checksum: %#x, zImage checksum: %#x, %s\n", fh.CheckSum, computed_checksum, fh.CheckSum == computed_checksum ? "Match" : "No Match!"); printf("header date: %s\n", asctime(convert_from_dos_date_time(fh.Date))); } void write_zImage_partition(int partition_fd, int zImage_fd, int cmdline_fd, int register_fd) { FileHeader fh; int zImage_size; int res; struct stat st; zImage_size = read(zImage_fd, buf, sizeof(buf)); if (zImage_size < 0) { perror("Error reading zImage file.\n"); exit(-1); } fstat(zImage_fd, &st); bzero(&fh, sizeof(fh)); fh.Size = zImage_size; fh.CheckSum = checksum(buf, zImage_size); fh.Version = 0xFFFFFFFF; fh.Date = convert_to_dos_date_time(st.st_mtime); res = read(cmdline_fd, fh.cmdline, sizeof(fh.cmdline)); if (res < 0) { perror("Error reading cmdline file.\n"); exit(-1); } fix_cmdline_end(fh.cmdline, res); if (register_fd != -1) { if (res < 0) { perror("Error reading register file\n"); exit(-1); } res = read(register_fd, fh.registers, sizeof(fh.registers)); } res = write(partition_fd, (char *)&fh, sizeof(fh)); if (res != sizeof(fh)) { perror("Error writing partition\n"); exit(-1); } res = write(partition_fd, buf, zImage_size); if (res != zImage_size) { perror("Error writing partition\n"); exit(-1); } } void read_zImage_partition(int partition_fd, int zImage_fd, int cmdline_fd, int register_fd) { FileHeader fh; int zImage_size; int res; res = read(partition_fd, (char *)&fh, sizeof(fh)); if (res != sizeof(fh)) { perror("Error reading partition\n"); exit(-1); } res = read(partition_fd, buf, fh.Size); if (res != fh.Size) { perror("Error reading partition\n"); printf("Error expected zImage of %d bytes but only read %d bytes\n", fh.Size, res); exit(-1); } zImage_size = write(zImage_fd, buf, fh.Size); if (zImage_size < 0) { perror("Error writing zImage file.\n"); exit(-1); } res = write(cmdline_fd, fh.cmdline, strlen(fh.cmdline)); if (res < 0) { perror("Error writing cmdline file.\n"); exit(-1); } res = write(register_fd, fh.registers, strlen(fh.registers)); if (res < 0) { perror("Error writing register file.\n"); exit(-1); } } #define USAGE "Usage: %s [-l] [-r] [-w] [-p ] [-d ] [-z ] [-c ] [-R ]\n" int main(int argc, char *argv[]) { char erase_command[100] = "eraseall "; char *zImage_filename; int zImage_fd; char *cmdline_filename; int cmdline_fd; char *register_filename; int register_fd; char *partition_filename; int partition_number; int partition_fd; int list_it=0, read_it=0, write_it=0; int partition_flag = O_RDONLY; int file_flag = O_RDONLY; int k; partition_filename = "/dev/mtdc2"; zImage_filename = "zImage"; cmdline_filename = "cmdline.txt"; register_filename = "register.txt"; for (k=1; k /dev/null 2>&1", sizeof(erase_command)); if (system(erase_command)) { printf("\nErase failed.\n"); exit(-1); } printf("done.\nWriting zImage partition %s ... ", partition_filename); fflush(stdout); write_zImage_partition(partition_fd, zImage_fd, cmdline_fd, register_fd); printf("done.\n"); } exit(0); }