📄 mkcasfw.c
字号:
voidcsum_init(struct csum_state *css, int size){ css->val = 0; css->tmp = 0; css->odd = 0; css->size = size;}voidcsum_update(uint8_t *p, uint32_t len, struct csum_state *css){ switch (css->size) { case CSUM_TYPE_8: csum8_update(p,len,css); break; case CSUM_TYPE_16: csum16_update(p,len,css); break; case CSUM_TYPE_32: csum32_update(p,len,css); break; }}uint32_tcsum_get(struct csum_state *css){ uint32_t ret; switch (css->size) { case CSUM_TYPE_8: ret = csum8_get(css); break; case CSUM_TYPE_16: ret = csum16_get(css); break; case CSUM_TYPE_32: ret = csum32_get(css); } return ret;}/* * routines to write data to the output file */intwrite_out_data(FILE *outfile, uint8_t *data, size_t len, struct csum_state *css){ errno = 0; fwrite(data, len, 1, outfile); if (errno) { ERRS("unable to write output file"); return ERR_FATAL; } if (css) { csum_update(data, len, css); } return 0;}intwrite_out_padding(FILE *outfile, size_t len, uint8_t padc, struct csum_state *css){ uint8_t buf[512]; size_t buflen = sizeof(buf); int err; memset(buf, padc, buflen); while (len > 0) { if (len < buflen) buflen = len; err = write_out_data(outfile, buf, buflen, css); if (err) return err; len -= buflen; } return 0;}intimage_stat_file(struct image_desc *desc){ struct stat st; int err; if (desc->file_name == NULL) return 0; err = stat(desc->file_name, &st); if (err){ ERRS("stat failed on %s", desc->file_name); return ERR_FATAL; } if (st.st_size > desc->out_size) { WARN("file %s is too big, will be truncated to %d bytes\n", desc->file_name, desc->out_size); desc->file_size = desc->out_size; return ERR_INVALID_IMAGE; } desc->file_size = st.st_size; desc->out_size = align(desc->file_size,1); return 0;}intimage_writeout_file(FILE *outfile, struct image_desc *desc, struct csum_state *css){ char buf[FILE_BUF_LEN]; size_t buflen = sizeof(buf); FILE *f; size_t len; int res; if (desc->file_name == NULL) return 0; if (desc->file_size == 0) return 0; errno = 0; f = fopen(desc->file_name,"r"); if (errno) { ERRS("unable to open file: %s", desc->file_name); return ERR_FATAL; } len = desc->file_size; while (len > 0) { if (len < buflen) buflen = len; /* read data from source file */ errno = 0; fread(buf, buflen, 1, f); if (errno != 0) { ERRS("unable to read from file: %s", desc->file_name); res = ERR_FATAL; break; } res = write_out_data(outfile, buf, buflen, css); if (res) break; len -= buflen; } fclose(f); return res;}intimage_writeout(FILE *outfile, struct image_desc *desc){ int res; struct csum_state css; size_t padlen; res = 0; if (!desc->file_size) return 0; DBG(2, "writing image, file=%s, file_size=%d\n", desc->file_name, desc->file_size); csum_init(&css, CSUM_TYPE_32); res = image_writeout_file(outfile, desc, &css); if (res) return res; /* write padding data if neccesary */ padlen = desc->out_size - desc->file_size; DBG(1,"padding desc, length=%d", padlen); res = write_out_padding(outfile, padlen, desc->padc, &css); desc->csum = csum_get(&css); return res;}intwrite_out_header(FILE *outfile){ union file_hdr tmp; int res; errno = 0; if (fseek(outfile, 0, SEEK_SET) != 0) { ERRS("fseek failed on output file"); return ERR_FATAL; } switch (board->header_type) { case HEADER_TYPE_CAS: tmp.cas.type = HOST_TO_LE32(header.cas.type); tmp.cas.id = HOST_TO_LE32(header.cas.id); tmp.cas.kernel_offs = HOST_TO_LE32(sizeof(tmp.cas)); tmp.cas.kernel_size = HOST_TO_LE32(kernel_image.out_size); tmp.cas.kernel_csum = HOST_TO_LE32(kernel_image.csum); tmp.cas.magic1 = HOST_TO_LE32(CAS_MAGIC1); tmp.cas.magic2 = HOST_TO_LE32(CAS_MAGIC2); tmp.cas.magic3 = HOST_TO_LE32(CAS_MAGIC3); res = write_out_data(outfile, (uint8_t *)&tmp.cas, sizeof(tmp.cas), NULL); break; case HEADER_TYPE_NFS: tmp.nfs.type = HOST_TO_LE32(header.nfs.type); tmp.nfs.id = HOST_TO_LE32(header.nfs.id); tmp.nfs.kernel_offs = HOST_TO_LE32(sizeof(tmp.nfs)); tmp.nfs.kernel_size = HOST_TO_LE32(kernel_image.out_size); tmp.nfs.kernel_csum = HOST_TO_LE32(kernel_image.csum); tmp.nfs.fs_offs = HOST_TO_LE32(sizeof(tmp.nfs) + kernel_image.out_size); tmp.nfs.fs_size = HOST_TO_LE32(fs_image.out_size); tmp.nfs.fs_csum = HOST_TO_LE32(fs_image.csum); res = write_out_data(outfile, (uint8_t *)&tmp.nfs, sizeof(tmp.nfs), NULL); break; } return res;}intwrite_out_images(FILE *outfile){ struct image_desc *desc; int i, res; res = image_writeout(outfile, &kernel_image); if (res) return res; res = image_writeout(outfile, &fs_image); if (res) return res; return 0;}struct board_info *find_board(char *model){ struct board_info *ret; struct board_info *board; ret = NULL; for (board = boards; board->model != NULL; board++){ if (strcasecmp(model, board->model) == 0) { ret = board; break; } }; return ret;}intparse_opt_board(char ch, char *arg){ DBG(1,"parsing board option: -%c %s", ch, arg); if (board != NULL) { ERR("only one board option allowed"); return ERR_FATAL; } if (required_arg(ch, arg)) return ERR_FATAL; board = find_board(arg); if (board == NULL){ ERR("invalid/unknown board specified: %s", arg); return ERR_FATAL; } switch (board->header_type) { case HEADER_TYPE_CAS: header.cas.type = HEADER_TYPE_CAS; header.cas.id = board->id; break; case HEADER_TYPE_NFS: header.nfs.type = HEADER_TYPE_NFS; header.nfs.id = board->id; break; default: ERR("internal error, unknown header type\n"); return ERR_FATAL; } return 0;}intparse_opt_image(char ch, char *arg){ char buf[MAX_ARG_LEN]; char *argv[MAX_ARG_COUNT]; int argc; char *p; struct image_desc *desc = NULL; int i; switch (ch) { case 'K': if (kernel_image.file_name) { WARN("only one kernel option allowed"); break; } desc = &kernel_image; break; case 'F': if (fs_image.file_name) { WARN("only one fs option allowed"); break; } desc = &fs_image; break; } if (!desc) return ERR_FATAL; argc = parse_arg(arg, buf, argv); i = 0; p = argv[i++]; if (!is_empty_arg(p)) { desc->file_name = strdup(p); if (desc->file_name == NULL) { ERR("not enough memory"); return ERR_FATAL; } } else { ERR("no file specified for option %c", ch); return ERR_FATAL; } return 0;}intprocess_images(void){ struct image_desc *desc; uint32_t offs = 0; int i; int res; kernel_image.out_size = board->max_kernel_size; kernel_image.padc = DEFAULT_PADC; res = image_stat_file(&kernel_image); if (res) return res; if (!fs_image.file_name) return 0; fs_image.out_size = board->max_fs_size; fs_image.padc = DEFAULT_PADC; res = image_stat_file(&fs_image); if (res) return res; return 0;}intmain(int argc, char *argv[]){ int optinvalid = 0; /* flag for invalid option */ int c; int res = ERR_FATAL; FILE *outfile; progname=basename(argv[0]); opterr = 0; /* could not print standard getopt error messages */ while ( 1 ) { optinvalid = 0; c = getopt(argc, argv, "B:C:dhK:r:vw:x:"); if (c == -1) break; switch (c) { case 'B': optinvalid = parse_opt_board(c,optarg); break; case 'd': invalid_causes_error = 0; break; case 'C': case 'K': optinvalid = parse_opt_image(c,optarg); break; case 'k': keep_invalid_images = 1; break; case 'v': verblevel++; break; case 'h': usage(EXIT_SUCCESS); break; default: optinvalid = 1; break; } if (optinvalid != 0 ){ ERR("invalid option: -%c", optopt); goto out; } } if (board == NULL) { ERR("no board specified"); goto out; } if (optind == argc) { ERR("no output file specified"); goto out; } ofname = argv[optind++]; if (optind < argc) { ERR("invalid option: %s", argv[optind]); goto out; } res = process_images(); if (res == ERR_FATAL) goto out; if (res == ERR_INVALID_IMAGE) { if (invalid_causes_error) res = ERR_FATAL; if (keep_invalid_images == 0) { WARN("generation of invalid images disabled", ofname); goto out; } WARN("generating invalid image", ofname); } outfile = fopen(ofname, "w"); if (outfile == NULL) { ERRS("could not open \"%s\" for writing", ofname); res = ERR_FATAL; goto out; } if (write_out_header(outfile) != 0) { res = ERR_FATAL; goto out_flush; } if (write_out_images(outfile) != 0) { res = ERR_FATAL; goto out_flush; } if (write_out_header(outfile) != 0) { res = ERR_FATAL; goto out_flush; } DBG(1,"Image file %s completed.", ofname);out_flush: fflush(outfile); fclose(outfile); if (res == ERR_FATAL) { unlink(ofname); }out: if (res == ERR_FATAL) return EXIT_FAILURE; return EXIT_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -