/****************************************************************************** * Copyright (c) 2004, 2008 IBM Corporation * All rights reserved. * This program and the accompanying materials * are made available under the terms of the BSD License * which accompanies this distribution, and is available at * http://www.opensource.org/licenses/bsd-license.php * * Contributors: * IBM Corporation - initial implementation *****************************************************************************/ #include #include #include #include #include #include #include #include #include int verbose = 0; #define dprintf(fmt, args...) if (verbose) printf(fmt, ##args) static void print_usage(void) { printf ("Usage: build_romfs [-?] [--help] [-s|--romfs-size ]\n" "\t[-p|--smart-pad] [-n|--notime] \n"); } unsigned long str_to_num(const char *str) { char *s = (char *) str; unsigned long num = strtoul(s, &s, 0); if (s) { if (s[0] == 'K') num <<= 10; if (s[0] == 'M') num <<= 20; } return num; } /* * NOTE: We should consider to install an exit handler which does the * unlink() of the output file. In case of error we just do exit() and * forget about all the clumsy error handling free/close code, which * blows up the code significantly and makes it hard to read. */ int main(int argc, char *argv[]) { int conf_file, rc; struct ffs_chain_t ffs_chain; int c; int smart_pad = 0; /* default */ int notime = 0; const char *config_file = "boot_rom.ffs"; const char *output_file = "boot_rom.bin"; memset((void *) &ffs_chain, 0, sizeof(struct ffs_chain_t)); while (1) { int option_index = 0; static struct option long_options[] = { {"romfs-size", 1, 0, 's'}, {"smart-pad", 0, 0, 'p'}, {"notime", 0, 0, 'n'}, {"verbose", 0, 0, 'v'}, {"help", 1, 0, 'h'}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "s:ph?nv", long_options, &option_index); if (c == -1) break; switch (c) { case 's': ffs_chain.romfs_size = str_to_num(optarg); break; case 'p': smart_pad = 1; break; case 'n': notime = 1; break; case 'v': verbose = 1; break; case '?': case 'h': print_usage(); return EXIT_SUCCESS; default: printf("?? getopt returned character code 0%o ??\n", c); } } /* two files must always be specified: config-file and output-file */ if (optind + 2 != argc) { print_usage(); return EXIT_FAILURE; } config_file = argv[optind++]; output_file = argv[optind++]; dprintf("ROMFS FILESYSTEM CREATION V0.3 (bad parser)\n" "Build directory structure...\n" " smart padding %s, maximum romfs size %d bytes\n", smart_pad ? "enabled" : "disabled", ffs_chain.romfs_size); conf_file = open(config_file, O_RDONLY); if (0 >= conf_file) { perror("load config file:"); return EXIT_FAILURE; } rc = read_config(conf_file, &ffs_chain); close(conf_file); if (rc < 1) { fprintf(stderr, "flash cannot be built due to config errors\n"); return EXIT_FAILURE; } rc = EXIT_SUCCESS; if (verbose) dump_fs_contents(&ffs_chain); if (smart_pad) /* FIXME: size is only verified during reorder */ rc = reorder_ffs_chain(&ffs_chain); if (rc == EXIT_FAILURE) goto out; dprintf("Build ffs and write to image file...\n"); if (build_ffs(&ffs_chain, output_file, notime) != 0) { fprintf(stderr, "build ffs failed\n"); rc = EXIT_FAILURE; } else { rc = EXIT_SUCCESS; } /* Check if there are any duplicate entries in the image, print warning if this is the case. */ find_duplicates(&ffs_chain); free_chain_memory(&ffs_chain); dprintf("\n"); out: /* If the build failed, remove the target image file */ if (rc == EXIT_FAILURE) unlink(output_file); return rc; }