Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / SLOF / romfs / tools / create_flash.c
1 /******************************************************************************
2  * Copyright (c) 2004, 2008 IBM Corporation
3  * All rights reserved.
4  * This program and the accompanying materials
5  * are made available under the terms of the BSD License
6  * which accompanies this distribution, and is available at
7  * http://www.opensource.org/licenses/bsd-license.php
8  *
9  * Contributors:
10  *     IBM Corporation - initial implementation
11  *****************************************************************************/
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <string.h>
18 #include <unistd.h>
19 #include <getopt.h>
20
21 #include <cfgparse.h>
22
23 int verbose = 0;
24
25 #define dprintf(fmt, args...) if (verbose) printf(fmt, ##args)
26
27 static void
28 print_usage(void)
29 {
30         printf
31             ("Usage: build_romfs [-?] [--help] [-s|--romfs-size <romfs_size>]\n"
32              "\t[-p|--smart-pad] [-n|--notime] <config-file> <output-file>\n");
33 }
34
35 unsigned long
36 str_to_num(const char *str)
37 {
38         char *s = (char *) str;
39         unsigned long num = strtoul(s, &s, 0);
40         if (s) {
41                 if (s[0] == 'K')
42                         num <<= 10;
43                 if (s[0] == 'M')
44                         num <<= 20;
45         }
46         return num;
47 }
48
49 /*
50  * NOTE: We should consider to install an exit handler which does the
51  * unlink() of the output file. In case of error we just do exit() and
52  * forget about all the clumsy error handling free/close code, which
53  * blows up the code significantly and makes it hard to read.
54  */
55 int
56 main(int argc, char *argv[])
57 {
58         int conf_file, rc;
59         struct ffs_chain_t ffs_chain;
60         int c;
61         int smart_pad = 0;      /* default */
62         int notime = 0;
63         const char *config_file = "boot_rom.ffs";
64         const char *output_file = "boot_rom.bin";
65
66         memset((void *) &ffs_chain, 0, sizeof(struct ffs_chain_t));
67
68         while (1) {
69                 int option_index = 0;
70                 static struct option long_options[] = {
71                         {"romfs-size", 1, 0, 's'},
72                         {"smart-pad", 0, 0, 'p'},
73                         {"notime", 0, 0, 'n'},
74                         {"verbose", 0, 0, 'v'},
75                         {"help", 1, 0, 'h'},
76                         {0, 0, 0, 0}
77                 };
78                 c = getopt_long(argc, argv, "s:ph?nv", long_options,
79                                 &option_index);
80                 if (c == -1)
81                         break;
82
83                 switch (c) {
84                 case 's':
85                         ffs_chain.romfs_size = str_to_num(optarg);
86                         break;
87                 case 'p':
88                         smart_pad = 1;
89                         break;
90                 case 'n':
91                         notime = 1;
92                         break;
93                 case 'v':
94                         verbose = 1;
95                         break;
96                 case '?':
97                 case 'h':
98                         print_usage();
99                         return EXIT_SUCCESS;
100                 default:
101                         printf("?? getopt returned character code 0%o ??\n", c);
102                 }
103         }
104
105         /* two files must always be specified: config-file and output-file */
106         if (optind + 2 != argc) {
107                 print_usage();
108                 return EXIT_FAILURE;
109         }
110
111         config_file = argv[optind++];
112         output_file = argv[optind++];
113
114         dprintf("ROMFS FILESYSTEM CREATION V0.3 (bad parser)\n"
115                 "Build directory structure...\n"
116                 "  smart padding %s, maximum romfs size %d bytes\n",
117                 smart_pad ? "enabled" : "disabled", ffs_chain.romfs_size);
118
119         conf_file = open(config_file, O_RDONLY);
120         if (0 >= conf_file) {
121                 perror("load config file:");
122                 return EXIT_FAILURE;
123         }
124
125         rc = read_config(conf_file, &ffs_chain);
126         close(conf_file);
127         if (rc < 1) {
128                 fprintf(stderr, "flash cannot be built due to config errors\n");
129                 return EXIT_FAILURE;
130         }
131
132         rc = EXIT_SUCCESS;
133
134         if (verbose)
135                 dump_fs_contents(&ffs_chain);
136         if (smart_pad)
137                 /* FIXME: size is only verified during reorder */
138                 rc = reorder_ffs_chain(&ffs_chain);
139
140         if (rc == EXIT_FAILURE)
141                 goto out;
142
143         dprintf("Build ffs and write to image file...\n");
144         if (build_ffs(&ffs_chain, output_file, notime) != 0) {
145                 fprintf(stderr, "build ffs failed\n");
146                 rc = EXIT_FAILURE;
147         } else {
148                 rc = EXIT_SUCCESS;
149         }
150
151         /* Check if there are any duplicate entries in the image,
152            print warning if this is the case. */
153         find_duplicates(&ffs_chain);
154         free_chain_memory(&ffs_chain);
155         dprintf("\n");
156
157       out:
158         /* If the build failed, remove the target image file */
159         if (rc == EXIT_FAILURE)
160                 unlink(output_file);
161
162         return rc;
163 }