blob: 9d22552b35b65dee2dd3606eb34d28209f8686d2 [file] [log] [blame]
Ronald G. Minnich5d01ec02009-03-31 11:57:36 +00001/*
Patrick Georgib7b56dd82009-09-14 13:29:27 +00002 * cbfstool, CLI utility for CBFS file manipulation
Ronald G. Minnich5d01ec02009-03-31 11:57:36 +00003 *
Patrick Georgib7b56dd82009-09-14 13:29:27 +00004 * Copyright (C) 2009 coresystems GmbH
5 * written by Patrick Georgi <patrick.georgi@coresystems.de>
David Hendricks90ca3b62012-11-16 14:48:22 -08006 * Copyright (C) 2012 Google, Inc.
Ronald G. Minnich5d01ec02009-03-31 11:57:36 +00007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
20 */
21
Patrick Georgib7b56dd82009-09-14 13:29:27 +000022#include <stdio.h>
Stefan Reinauera1e48242011-10-21 14:24:57 -070023#include <stdlib.h>
Stefan Reinauer336daa72009-12-21 15:09:01 +000024#include <string.h>
Stefan Reinauera1e48242011-10-21 14:24:57 -070025#include <ctype.h>
Stefan Reinauer63217582012-10-29 16:52:36 -070026#include <unistd.h>
27#include <getopt.h>
Patrick Georgib7b56dd82009-09-14 13:29:27 +000028#include "common.h"
29#include "cbfs.h"
Hung-Te Lin3bb035b2013-01-29 02:15:49 +080030#include "cbfs_image.h"
Ronald G. Minnich5d01ec02009-03-31 11:57:36 +000031
Stefan Reinauer3fec29c2009-09-22 15:58:19 +000032struct command {
Stefan Reinauer3fec29c2009-09-22 15:58:19 +000033 const char *name;
Stefan Reinauer63217582012-10-29 16:52:36 -070034 const char *optstring;
35 int (*function) (void);
Stefan Reinauer3fec29c2009-09-22 15:58:19 +000036};
37
Stefan Reinauer63217582012-10-29 16:52:36 -070038int verbose = 0;
Hung-Te Lind1739622013-01-28 14:23:49 +080039static struct param {
40 char *cbfs_name;
41 char *name;
42 char *filename;
43 char *bootblock;
44 uint32_t type;
45 uint32_t baseaddress;
46 uint32_t loadaddress;
47 uint32_t entrypoint;
48 uint32_t size;
49 uint32_t alignment;
50 uint32_t offset;
51 comp_algo algo;
52} param = {
53 /* All variables not listed are initialized as zero. */
54 .algo = CBFS_COMPRESS_NONE,
55};
Stefan Reinauer63217582012-10-29 16:52:36 -070056
57static int cbfs_add(void)
Ronald G. Minnich5d01ec02009-03-31 11:57:36 +000058{
Patrick Georgib7b56dd82009-09-14 13:29:27 +000059 uint32_t filesize = 0;
Stefan Reinauer63217582012-10-29 16:52:36 -070060 void *rom, *filedata, *cbfsfile;
61
Hung-Te Lind1739622013-01-28 14:23:49 +080062 if (!param.filename) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +080063 ERROR("You need to specify -f/--filename.\n");
Stefan Reinauer63217582012-10-29 16:52:36 -070064 return 1;
65 }
66
Hung-Te Lind1739622013-01-28 14:23:49 +080067 if (!param.name) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +080068 ERROR("You need to specify -n/--name.\n");
Stefan Reinauer63217582012-10-29 16:52:36 -070069 return 1;
70 }
71
Hung-Te Lind1739622013-01-28 14:23:49 +080072 if (param.type == 0) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +080073 ERROR("You need to specify a valid -t/--type.\n");
Stefan Reinauer63217582012-10-29 16:52:36 -070074 return 1;
75 }
76
Hung-Te Lind1739622013-01-28 14:23:49 +080077 rom = loadrom(param.cbfs_name);
Stefan Reinauer63217582012-10-29 16:52:36 -070078 if (rom == NULL) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +080079 ERROR("Could not load ROM image '%s'.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +080080 param.cbfs_name);
Stefan Reinauer63217582012-10-29 16:52:36 -070081 return 1;
82 }
83
Hung-Te Lind1739622013-01-28 14:23:49 +080084 filedata = loadfile(param.filename, &filesize, 0, SEEK_SET);
Patrick Georgi45d8a832009-09-15 08:21:46 +000085 if (filedata == NULL) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +080086 ERROR("Could not load file '%s'.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +080087 param.filename);
Stefan Reinauer63217582012-10-29 16:52:36 -070088 free(rom);
Patrick Georgi45d8a832009-09-15 08:21:46 +000089 return 1;
90 }
Ronald G. Minnich5d01ec02009-03-31 11:57:36 +000091
Hung-Te Lind1739622013-01-28 14:23:49 +080092 cbfsfile = create_cbfs_file(param.name, filedata, &filesize,
93 param.type, &param.baseaddress);
Stefan Reinauer63217582012-10-29 16:52:36 -070094 free(filedata);
Patrick Georgib7b56dd82009-09-14 13:29:27 +000095
Hung-Te Lind1739622013-01-28 14:23:49 +080096 if (add_file_to_cbfs(cbfsfile, filesize, param.baseaddress)) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +080097 ERROR("Adding file '%s' failed.\n", param.filename);
Stefan Reinauer63217582012-10-29 16:52:36 -070098 free(cbfsfile);
99 free(rom);
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000100 return 1;
101 }
Hung-Te Lind1739622013-01-28 14:23:49 +0800102 if (writerom(param.cbfs_name, rom, romsize)) {
Stefan Reinauer63217582012-10-29 16:52:36 -0700103 free(cbfsfile);
104 free(rom);
Patrick Georgi56f5fb72009-09-30 11:21:18 +0000105 return 1;
Stefan Reinauerfbadc492011-10-14 12:44:14 -0700106 }
Stefan Reinauer63217582012-10-29 16:52:36 -0700107
108 free(cbfsfile);
109 free(rom);
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000110 return 0;
111}
112
Stefan Reinauer63217582012-10-29 16:52:36 -0700113static int cbfs_add_payload(void)
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000114{
Hung-Te Lind1739622013-01-28 14:23:49 +0800115 uint32_t filesize = 0;
Stefan Reinauer63217582012-10-29 16:52:36 -0700116 void *rom, *filedata, *cbfsfile;
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000117 unsigned char *payload;
Stefan Reinauer63217582012-10-29 16:52:36 -0700118
Hung-Te Lind1739622013-01-28 14:23:49 +0800119 if (!param.filename) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800120 ERROR("You need to specify -f/--filename.\n");
Patrick Georgi56f5fb72009-09-30 11:21:18 +0000121 return 1;
Stefan Reinauerfbadc492011-10-14 12:44:14 -0700122 }
Stefan Reinauer63217582012-10-29 16:52:36 -0700123
Hung-Te Lind1739622013-01-28 14:23:49 +0800124 if (!param.name) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800125 ERROR("You need to specify -n/--name.\n");
Stefan Reinauer9bb043852010-06-24 13:37:59 +0000126 return 1;
Stefan Reinauer63217582012-10-29 16:52:36 -0700127 }
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000128
Hung-Te Lind1739622013-01-28 14:23:49 +0800129 rom = loadrom(param.cbfs_name);
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000130 if (rom == NULL) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800131 ERROR("Could not load ROM image '%s'.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +0800132 param.cbfs_name);
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000133 return 1;
134 }
135
Hung-Te Lind1739622013-01-28 14:23:49 +0800136 filedata = loadfile(param.filename, &filesize, 0, SEEK_SET);
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000137 if (filedata == NULL) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800138 ERROR("Could not load file '%s'.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +0800139 param.filename);
Stefan Reinauer63217582012-10-29 16:52:36 -0700140 free(rom);
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000141 return 1;
142 }
143
Hung-Te Lind1739622013-01-28 14:23:49 +0800144 filesize = parse_elf_to_payload(filedata, &payload, param.algo);
Stefan Reinauercf5aaaf2012-12-11 17:35:30 -0800145 if (filesize <= 0) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800146 ERROR("Adding payload '%s' failed.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +0800147 param.filename);
Stefan Reinauercf5aaaf2012-12-11 17:35:30 -0800148 free(rom);
149 return 1;
150 }
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000151
Hung-Te Lind1739622013-01-28 14:23:49 +0800152 cbfsfile = create_cbfs_file(param.name, payload, &filesize,
153 CBFS_COMPONENT_PAYLOAD, &param.baseaddress);
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000154
Stefan Reinauer63217582012-10-29 16:52:36 -0700155 free(filedata);
156 free(payload);
157
Hung-Te Lind1739622013-01-28 14:23:49 +0800158 if (add_file_to_cbfs(cbfsfile, filesize, param.baseaddress)) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800159 ERROR("Adding payload '%s' failed.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +0800160 param.filename);
Stefan Reinauer63217582012-10-29 16:52:36 -0700161 free(cbfsfile);
162 free(rom);
Patrick Georgi56f5fb72009-09-30 11:21:18 +0000163 return 1;
Stefan Reinauerfbadc492011-10-14 12:44:14 -0700164 }
Stefan Reinauer63217582012-10-29 16:52:36 -0700165
Hung-Te Lind1739622013-01-28 14:23:49 +0800166 if (writerom(param.cbfs_name, rom, romsize)) {
Stefan Reinauer63217582012-10-29 16:52:36 -0700167 free(cbfsfile);
168 free(rom);
Stefan Reinauer9bb043852010-06-24 13:37:59 +0000169 return 1;
Stefan Reinauer63217582012-10-29 16:52:36 -0700170 }
171
172 free(cbfsfile);
173 free(rom);
Patrick Georgib7b56dd82009-09-14 13:29:27 +0000174 return 0;
Ronald G. Minnich5d01ec02009-03-31 11:57:36 +0000175}
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000176
Stefan Reinauer63217582012-10-29 16:52:36 -0700177static int cbfs_add_stage(void)
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700178{
Stefan Reinauer63217582012-10-29 16:52:36 -0700179 uint32_t filesize = 0;
180 void *rom, *filedata, *cbfsfile;
181 unsigned char *stage;
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700182
Hung-Te Lind1739622013-01-28 14:23:49 +0800183 if (!param.filename) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800184 ERROR("You need to specify -f/--filename.\n");
Stefan Reinauer63217582012-10-29 16:52:36 -0700185 return 1;
186 }
187
Hung-Te Lind1739622013-01-28 14:23:49 +0800188 if (!param.name) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800189 ERROR("You need to specify -n/--name.\n");
Stefan Reinauer63217582012-10-29 16:52:36 -0700190 return 1;
191 }
192
Hung-Te Lind1739622013-01-28 14:23:49 +0800193 rom = loadrom(param.cbfs_name);
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700194 if (rom == NULL) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800195 ERROR("Could not load ROM image '%s'.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +0800196 param.cbfs_name);
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700197 return 1;
198 }
199
Hung-Te Lind1739622013-01-28 14:23:49 +0800200 filedata = loadfile(param.filename, &filesize, 0, SEEK_SET);
Stefan Reinauer63217582012-10-29 16:52:36 -0700201 if (filedata == NULL) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800202 ERROR("Could not load file '%s'.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +0800203 param.filename);
Stefan Reinauer63217582012-10-29 16:52:36 -0700204 free(rom);
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700205 return 1;
206 }
207
Hung-Te Lind1739622013-01-28 14:23:49 +0800208 filesize = parse_elf_to_stage(filedata, &stage, param.algo, &param.baseaddress);
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700209
Hung-Te Lind1739622013-01-28 14:23:49 +0800210 cbfsfile = create_cbfs_file(param.name, stage, &filesize,
211 CBFS_COMPONENT_STAGE, &param.baseaddress);
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700212
Stefan Reinauer63217582012-10-29 16:52:36 -0700213 free(filedata);
214 free(stage);
215
Hung-Te Lind1739622013-01-28 14:23:49 +0800216 if (add_file_to_cbfs(cbfsfile, filesize, param.baseaddress)) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800217 ERROR("Adding stage '%s' failed.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +0800218 param.filename);
Stefan Reinauer63217582012-10-29 16:52:36 -0700219 free(cbfsfile);
220 free(rom);
221 return 1;
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700222 }
Stefan Reinauer63217582012-10-29 16:52:36 -0700223
Hung-Te Lind1739622013-01-28 14:23:49 +0800224 if (writerom(param.cbfs_name, rom, romsize)) {
Stefan Reinauer63217582012-10-29 16:52:36 -0700225 free(cbfsfile);
226 free(rom);
227 return 1;
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700228 }
Stefan Reinauer63217582012-10-29 16:52:36 -0700229
230 free(cbfsfile);
231 free(rom);
232 return 0;
233}
234
235static int cbfs_add_flat_binary(void)
236{
237 uint32_t filesize = 0;
Stefan Reinauer63217582012-10-29 16:52:36 -0700238 void *rom, *filedata, *cbfsfile;
239 unsigned char *payload;
Stefan Reinauer63217582012-10-29 16:52:36 -0700240
Hung-Te Lind1739622013-01-28 14:23:49 +0800241 if (!param.filename) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800242 ERROR("You need to specify -f/--filename.\n");
Stefan Reinauer63217582012-10-29 16:52:36 -0700243 return 1;
244 }
245
Hung-Te Lind1739622013-01-28 14:23:49 +0800246 if (!param.name) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800247 ERROR("You need to specify -n/--name.\n");
Stefan Reinauer63217582012-10-29 16:52:36 -0700248 return 1;
249 }
250
Hung-Te Lind1739622013-01-28 14:23:49 +0800251 if (param.loadaddress == 0) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800252 ERROR("You need to specify a valid "
Stefan Reinauer63217582012-10-29 16:52:36 -0700253 "-l/--load-address.\n");
254 return 1;
255 }
256
Hung-Te Lind1739622013-01-28 14:23:49 +0800257 if (param.entrypoint == 0) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800258 ERROR("You need to specify a valid "
Stefan Reinauer63217582012-10-29 16:52:36 -0700259 "-e/--entry-point.\n");
260 return 1;
261 }
262
Hung-Te Lind1739622013-01-28 14:23:49 +0800263 rom = loadrom(param.cbfs_name);
Stefan Reinauer63217582012-10-29 16:52:36 -0700264 if (rom == NULL) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800265 ERROR("Could not load ROM image '%s'.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +0800266 param.cbfs_name);
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700267 return 1;
268 }
269
Hung-Te Lind1739622013-01-28 14:23:49 +0800270 filedata = loadfile(param.filename, &filesize, 0, SEEK_SET);
Stefan Reinauer63217582012-10-29 16:52:36 -0700271 if (filedata == NULL) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800272 ERROR("Could not load file '%s'.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +0800273 param.filename);
Stefan Reinauer63217582012-10-29 16:52:36 -0700274 free(rom);
275 return 1;
276 }
277
Hung-Te Lin05dccae2013-01-28 15:04:30 +0800278 filesize = parse_flat_binary_to_payload(filedata, &payload,
279 filesize,
280 param.loadaddress,
281 param.entrypoint,
282 param.algo);
283 free(filedata);
284
285 if ((int)filesize <= 0) {
286 ERROR("Adding payload '%s' failed.\n",
287 param.filename);
Stefan Reinauer63217582012-10-29 16:52:36 -0700288 free(rom);
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700289 return 1;
290 }
Hung-Te Lin05dccae2013-01-28 15:04:30 +0800291 cbfsfile = create_cbfs_file(param.name, payload, &filesize,
292 CBFS_COMPONENT_PAYLOAD, &param.baseaddress);
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700293
Stefan Reinauer63217582012-10-29 16:52:36 -0700294 free(payload);
Hung-Te Lin05dccae2013-01-28 15:04:30 +0800295 if (add_file_to_cbfs(cbfsfile, filesize, param.baseaddress)) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800296 ERROR("Adding payload '%s' failed.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +0800297 param.filename);
Stefan Reinauer63217582012-10-29 16:52:36 -0700298 free(cbfsfile);
299 free(rom);
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700300 return 1;
301 }
Hung-Te Lind1739622013-01-28 14:23:49 +0800302 if (writerom(param.cbfs_name, rom, romsize)) {
Stefan Reinauer63217582012-10-29 16:52:36 -0700303 free(cbfsfile);
304 free(rom);
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700305 return 1;
Stefan Reinauer63217582012-10-29 16:52:36 -0700306 }
307
308 free(cbfsfile);
309 free(rom);
Stefan Reinauer20848ee2012-10-22 16:04:13 -0700310 return 0;
311}
312
Stefan Reinauer63217582012-10-29 16:52:36 -0700313static int cbfs_remove(void)
Gabe Blacke1bb49e2012-01-27 00:33:47 -0800314{
Stefan Reinauer63217582012-10-29 16:52:36 -0700315 void *rom;
Gabe Blacke1bb49e2012-01-27 00:33:47 -0800316
Hung-Te Lind1739622013-01-28 14:23:49 +0800317 if (!param.name) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800318 ERROR("You need to specify -n/--name.\n");
Stefan Reinauer63217582012-10-29 16:52:36 -0700319 return 1;
320 }
321
Hung-Te Lind1739622013-01-28 14:23:49 +0800322 rom = loadrom(param.cbfs_name);
Gabe Blacke1bb49e2012-01-27 00:33:47 -0800323 if (rom == NULL) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800324 ERROR("Could not load ROM image '%s'.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +0800325 param.cbfs_name);
Gabe Blacke1bb49e2012-01-27 00:33:47 -0800326 return 1;
327 }
328
Hung-Te Lind1739622013-01-28 14:23:49 +0800329 if (remove_file_from_cbfs(param.name)) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800330 ERROR("Removing file '%s' failed.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +0800331 param.name);
Stefan Reinauer63217582012-10-29 16:52:36 -0700332 free(rom);
Gabe Blacke1bb49e2012-01-27 00:33:47 -0800333 return 1;
334 }
335
Hung-Te Lind1739622013-01-28 14:23:49 +0800336 if (writerom(param.cbfs_name, rom, romsize)) {
Stefan Reinauer63217582012-10-29 16:52:36 -0700337 free(rom);
Gabe Blacke1bb49e2012-01-27 00:33:47 -0800338 return 1;
339 }
Stefan Reinauer63217582012-10-29 16:52:36 -0700340
341 free(rom);
Gabe Blacke1bb49e2012-01-27 00:33:47 -0800342 return 0;
343}
344
Stefan Reinauer63217582012-10-29 16:52:36 -0700345static int cbfs_create(void)
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000346{
Hung-Te Lind1739622013-01-28 14:23:49 +0800347 if (param.size == 0) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800348 ERROR("You need to specify a valid -s/--size.\n");
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000349 return 1;
350 }
351
Hung-Te Lind1739622013-01-28 14:23:49 +0800352 if (!param.bootblock) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800353 ERROR("You need to specify -b/--bootblock.\n");
Stefan Reinauer63217582012-10-29 16:52:36 -0700354 return 1;
Patrick Georgi467b12a2009-12-21 13:50:37 +0000355 }
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000356
David Hendricks90ca3b62012-11-16 14:48:22 -0800357 if (arch == CBFS_ARCHITECTURE_UNKNOWN) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800358 ERROR("You need to specify -m/--machine arch\n");
David Hendricks90ca3b62012-11-16 14:48:22 -0800359 return 1;
360 }
361
Hung-Te Lind1739622013-01-28 14:23:49 +0800362 return create_cbfs_image(param.cbfs_name, param.size, param.bootblock,
363 param.alignment, param.offset);
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000364}
365
Stefan Reinauer63217582012-10-29 16:52:36 -0700366static int cbfs_locate(void)
Patrick Georgi0da38dd2009-11-09 17:18:02 +0000367{
Stefan Reinauer63217582012-10-29 16:52:36 -0700368 uint32_t filesize, location;
369
Hung-Te Lind1739622013-01-28 14:23:49 +0800370 if (!param.filename) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800371 ERROR("You need to specify -f/--filename.\n");
Patrick Georgi0da38dd2009-11-09 17:18:02 +0000372 return 1;
373 }
374
Hung-Te Lind1739622013-01-28 14:23:49 +0800375 if (!param.name) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800376 ERROR("You need to specify -n/--name.\n");
Stefan Reinauer63217582012-10-29 16:52:36 -0700377 return 1;
378 }
379
Hung-Te Lind1739622013-01-28 14:23:49 +0800380 filesize = getfilesize(param.filename);
Stefan Reinauer63217582012-10-29 16:52:36 -0700381
Hung-Te Lind1739622013-01-28 14:23:49 +0800382 location = cbfs_find_location(param.cbfs_name, filesize,
383 param.name, param.alignment);
Patrick Georgi0da38dd2009-11-09 17:18:02 +0000384
Hung-Te Lin657ea6a2013-01-28 23:00:47 +0800385 printf("0x%x\n", location);
zbao93dd07f2012-02-17 21:44:09 +0800386 return location == 0 ? 1 : 0;
Patrick Georgi0da38dd2009-11-09 17:18:02 +0000387}
388
Stefan Reinauer63217582012-10-29 16:52:36 -0700389static int cbfs_print(void)
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000390{
Hung-Te Lin3bb035b2013-01-29 02:15:49 +0800391 struct cbfs_image image;
392 if (cbfs_image_from_file(&image, param.cbfs_name) != 0) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800393 ERROR("Could not load ROM image '%s'.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +0800394 param.cbfs_name);
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000395 return 1;
396 }
Hung-Te Lin3bb035b2013-01-29 02:15:49 +0800397 cbfs_print_directory(&image);
398 cbfs_image_delete(&image);
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000399 return 0;
400}
401
Stefan Reinauer63217582012-10-29 16:52:36 -0700402static int cbfs_extract(void)
Aurelien Guillaumefe7d6b92011-01-13 09:09:21 +0000403{
Hung-Te Lin0f8af712013-01-29 02:29:49 +0800404 int result = 0;
405 struct cbfs_image image;
Aurelien Guillaumefe7d6b92011-01-13 09:09:21 +0000406
Hung-Te Lind1739622013-01-28 14:23:49 +0800407 if (!param.filename) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800408 ERROR("You need to specify -f/--filename.\n");
Stefan Reinauer63217582012-10-29 16:52:36 -0700409 return 1;
410 }
411
Hung-Te Lind1739622013-01-28 14:23:49 +0800412 if (!param.name) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800413 ERROR("You need to specify -n/--name.\n");
Stefan Reinauer63217582012-10-29 16:52:36 -0700414 return 1;
415 }
416
Hung-Te Lin0f8af712013-01-29 02:29:49 +0800417 if (cbfs_image_from_file(&image, param.cbfs_name) != 0) {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800418 ERROR("Could not load ROM image '%s'.\n",
Hung-Te Lind1739622013-01-28 14:23:49 +0800419 param.cbfs_name);
Hung-Te Lin0f8af712013-01-29 02:29:49 +0800420 result = 1;
421 } else if (cbfs_export_entry(&image, param.name,
422 param.filename) != 0) {
423 result = 1;
Aurelien Guillaumefe7d6b92011-01-13 09:09:21 +0000424 }
425
Hung-Te Lin0f8af712013-01-29 02:29:49 +0800426 cbfs_image_delete(&image);
427 return result;
Aurelien Guillaumefe7d6b92011-01-13 09:09:21 +0000428}
429
Stefan Reinauera1e48242011-10-21 14:24:57 -0700430static const struct command commands[] = {
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800431 {"add", "f:n:t:b:vh?", cbfs_add},
432 {"add-payload", "f:n:t:c:b:vh?", cbfs_add_payload},
433 {"add-stage", "f:n:t:c:b:vh?", cbfs_add_stage},
434 {"add-flat-binary", "f:n:l:e:c:b:vh?", cbfs_add_flat_binary},
435 {"remove", "n:vh?", cbfs_remove},
436 {"create", "s:B:a:o:m:vh?", cbfs_create},
437 {"locate", "f:n:a:vh?", cbfs_locate},
438 {"print", "vh?", cbfs_print},
439 {"extract", "n:f:vh?", cbfs_extract},
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000440};
441
Stefan Reinauer63217582012-10-29 16:52:36 -0700442static struct option long_options[] = {
443 {"name", required_argument, 0, 'n' },
444 {"type", required_argument, 0, 't' },
445 {"compression", required_argument, 0, 'c' },
446 {"base-address", required_argument, 0, 'b' },
447 {"load-address", required_argument, 0, 'l' },
448 {"entry-point", required_argument, 0, 'e' },
449 {"size", required_argument, 0, 's' },
450 {"bootblock", required_argument, 0, 'B' },
451 {"alignment", required_argument, 0, 'a' },
452 {"offset", required_argument, 0, 'o' },
453 {"file", required_argument, 0, 'f' },
David Hendricks90ca3b62012-11-16 14:48:22 -0800454 {"arch", required_argument, 0, 'm' },
Stefan Reinauer63217582012-10-29 16:52:36 -0700455 {"verbose", no_argument, 0, 'v' },
456 {"help", no_argument, 0, 'h' },
457 {NULL, 0, 0, 0 }
458};
459
460static void usage(char *name)
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000461{
462 printf
Stefan Reinauer07040582010-04-24 21:24:06 +0000463 ("cbfstool: Management utility for CBFS formatted ROM images\n\n"
Stefan Reinauer63217582012-10-29 16:52:36 -0700464 "USAGE:\n" " %s [-h]\n"
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800465 " %s FILE COMMAND [-v] [PARAMETERS]...\n\n" "OPTIONs:\n"
466 " -v Provide verbose output\n"
467 " -h Display this help message\n\n"
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000468 "COMMANDs:\n"
David Hendricks90ca3b62012-11-16 14:48:22 -0800469 " add -f FILE -n NAME -t TYPE [-b base-address] "
Stefan Reinauer63217582012-10-29 16:52:36 -0700470 "Add a component\n"
David Hendricks90ca3b62012-11-16 14:48:22 -0800471 " add-payload -f FILE -n NAME [-c compression] [-b base] "
Stefan Reinauer63217582012-10-29 16:52:36 -0700472 "Add a payload to the ROM\n"
David Hendricks90ca3b62012-11-16 14:48:22 -0800473 " add-stage -f FILE -n NAME [-c compression] [-b base] "
Stefan Reinauer63217582012-10-29 16:52:36 -0700474 "Add a stage to the ROM\n"
475 " add-flat-binary -f FILE -n NAME -l load-address \\\n"
David Hendricks90ca3b62012-11-16 14:48:22 -0800476 " -e entry-point [-c compression] [-b base] "
Stefan Reinauer63217582012-10-29 16:52:36 -0700477 "Add a 32bit flat mode binary\n"
David Hendricks90ca3b62012-11-16 14:48:22 -0800478 " remove -n NAME "
Stefan Reinauer63217582012-10-29 16:52:36 -0700479 "Remove a component\n"
David Hendricks90ca3b62012-11-16 14:48:22 -0800480 " create -s size -B bootblock -m ARCH [-a align] [-o offset] "
Stefan Reinauer63217582012-10-29 16:52:36 -0700481 "Create a ROM file\n"
David Hendricks90ca3b62012-11-16 14:48:22 -0800482 " locate -f FILE -n NAME -a align "
Stefan Reinauer63217582012-10-29 16:52:36 -0700483 "Find a place for a file of that size\n"
David Hendricks90ca3b62012-11-16 14:48:22 -0800484 " print "
Stefan Reinauer63217582012-10-29 16:52:36 -0700485 "Show the contents of the ROM\n"
David Hendricks90ca3b62012-11-16 14:48:22 -0800486 " extract -n NAME -f FILE "
Stefan Reinauer63217582012-10-29 16:52:36 -0700487 "Extracts a raw payload from ROM\n"
Peter Stugeb347e0d2011-01-17 05:02:09 +0000488 "\n"
David Hendricks90ca3b62012-11-16 14:48:22 -0800489 "ARCHes:\n"
490 " armv7, x86\n"
Stefan Reinauer63217582012-10-29 16:52:36 -0700491 "TYPEs:\n", name, name
492 );
Stefan Reinauer07040582010-04-24 21:24:06 +0000493 print_supported_filetypes();
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000494}
495
496int main(int argc, char **argv)
497{
Mathias Krause41c229c2012-07-17 21:17:15 +0200498 size_t i;
Stefan Reinauer63217582012-10-29 16:52:36 -0700499 int c;
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000500
501 if (argc < 3) {
Stefan Reinauer63217582012-10-29 16:52:36 -0700502 usage(argv[0]);
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000503 return 1;
504 }
505
Hung-Te Lind1739622013-01-28 14:23:49 +0800506 param.cbfs_name = argv[1];
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000507 char *cmd = argv[2];
Stefan Reinauer63217582012-10-29 16:52:36 -0700508 optind += 2;
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000509
510 for (i = 0; i < ARRAY_SIZE(commands); i++) {
511 if (strcmp(cmd, commands[i].name) != 0)
512 continue;
Stefan Reinauer63217582012-10-29 16:52:36 -0700513
514 while (1) {
515 char *suffix = NULL;
516 int option_index = 0;
517
518 c = getopt_long(argc, argv, commands[i].optstring,
519 long_options, &option_index);
520 if (c == -1)
521 break;
522
523 /* filter out illegal long options */
zbao062730d2013-01-08 10:10:16 +0800524 if (strchr(commands[i].optstring, c) == NULL) {
Stefan Reinauer63217582012-10-29 16:52:36 -0700525 /* TODO maybe print actual long option instead */
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800526 ERROR("%s: invalid option -- '%c'\n",
527 argv[0], c);
Stefan Reinauer63217582012-10-29 16:52:36 -0700528 c = '?';
529 }
530
531 switch(c) {
532 case 'n':
Hung-Te Lind1739622013-01-28 14:23:49 +0800533 param.name = optarg;
Stefan Reinauer63217582012-10-29 16:52:36 -0700534 break;
535 case 't':
536 if (intfiletype(optarg) != ((uint64_t) - 1))
Hung-Te Lind1739622013-01-28 14:23:49 +0800537 param.type = intfiletype(optarg);
Stefan Reinauer63217582012-10-29 16:52:36 -0700538 else
Hung-Te Lind1739622013-01-28 14:23:49 +0800539 param.type = strtoul(optarg, NULL, 0);
540 if (param.type == 0)
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800541 WARN("Unknown type '%s' ignored\n",
Stefan Reinauer63217582012-10-29 16:52:36 -0700542 optarg);
543 break;
544 case 'c':
545 if (!strncasecmp(optarg, "lzma", 5))
Hung-Te Lind1739622013-01-28 14:23:49 +0800546 param.algo = CBFS_COMPRESS_LZMA;
Stefan Reinauer63217582012-10-29 16:52:36 -0700547 else if (!strncasecmp(optarg, "none", 5))
Hung-Te Lind1739622013-01-28 14:23:49 +0800548 param.algo = CBFS_COMPRESS_NONE;
Stefan Reinauer63217582012-10-29 16:52:36 -0700549 else
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800550 WARN("Unknown compression '%s'"
551 " ignored.\n", optarg);
Stefan Reinauer63217582012-10-29 16:52:36 -0700552 break;
553 case 'b':
Hung-Te Lind1739622013-01-28 14:23:49 +0800554 param.baseaddress = strtoul(optarg, NULL, 0);
Stefan Reinauer63217582012-10-29 16:52:36 -0700555 break;
556 case 'l':
Hung-Te Lind1739622013-01-28 14:23:49 +0800557 param.loadaddress = strtoul(optarg, NULL, 0);
Stefan Reinauer63217582012-10-29 16:52:36 -0700558
559 break;
560 case 'e':
Hung-Te Lind1739622013-01-28 14:23:49 +0800561 param.entrypoint = strtoul(optarg, NULL, 0);
Stefan Reinauer63217582012-10-29 16:52:36 -0700562 break;
563 case 's':
Hung-Te Lind1739622013-01-28 14:23:49 +0800564 param.size = strtoul(optarg, &suffix, 0);
Stefan Reinauer63217582012-10-29 16:52:36 -0700565 if (tolower(suffix[0])=='k') {
Hung-Te Lind1739622013-01-28 14:23:49 +0800566 param.size *= 1024;
Stefan Reinauer63217582012-10-29 16:52:36 -0700567 }
568 if (tolower(suffix[0])=='m') {
Hung-Te Lind1739622013-01-28 14:23:49 +0800569 param.size *= 1024 * 1024;
Stefan Reinauer63217582012-10-29 16:52:36 -0700570 }
571 case 'B':
Hung-Te Lind1739622013-01-28 14:23:49 +0800572 param.bootblock = optarg;
Stefan Reinauer63217582012-10-29 16:52:36 -0700573 break;
574 case 'a':
Hung-Te Lind1739622013-01-28 14:23:49 +0800575 param.alignment = strtoul(optarg, NULL, 0);
Stefan Reinauer63217582012-10-29 16:52:36 -0700576 break;
577 case 'o':
Hung-Te Lind1739622013-01-28 14:23:49 +0800578 param.offset = strtoul(optarg, NULL, 0);
Stefan Reinauer63217582012-10-29 16:52:36 -0700579 break;
580 case 'f':
Hung-Te Lind1739622013-01-28 14:23:49 +0800581 param.filename = optarg;
Stefan Reinauer63217582012-10-29 16:52:36 -0700582 break;
583 case 'v':
584 verbose++;
585 break;
David Hendricks90ca3b62012-11-16 14:48:22 -0800586 case 'm':
587 arch = string_to_arch(optarg);
588 break;
Stefan Reinauer63217582012-10-29 16:52:36 -0700589 case 'h':
590 case '?':
591 usage(argv[0]);
592 return 1;
593 default:
594 break;
595 }
596 }
597
598 return commands[i].function();
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000599 }
600
Hung-Te Lin4d87d4e2013-01-28 14:39:43 +0800601 ERROR("Unknown command '%s'.\n", cmd);
Stefan Reinauer63217582012-10-29 16:52:36 -0700602 usage(argv[0]);
Stefan Reinauer3fec29c2009-09-22 15:58:19 +0000603 return 1;
604}