1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <stdio.h>
22#include <string.h>
23#include "common.h"
24#include "cbfs.h"
25
26typedef enum {
27 CMD_ADD,
28 CMD_ADD_PAYLOAD,
29 CMD_ADD_STAGE,
30 CMD_CREATE,
31 CMD_LOCATE,
32 CMD_PRINT,
33 CMD_EXTRACT,
34} cmd_t;
35
36struct command {
37 cmd_t id;
38 const char *name;
39 int (*function) (int argc, char **argv);
40};
41
42static int cbfs_add(int argc, char **argv)
43{
44 char *romname = argv[1];
45 char *cmd = argv[2];
46 void *rom = loadrom(romname);
47
48 if (rom == NULL) {
49 printf("Could not load ROM image '%s'.\n", romname);
50 return 1;
51 }
52
53 if (argc < 5) {
54 printf("not enough arguments to '%s'.\n", cmd);
55 return 1;
56 }
57
58 char *filename = argv[3];
59 char *cbfsname = argv[4];
60
61 uint32_t filesize = 0;
62 void *filedata = loadfile(filename, &filesize, 0, SEEK_SET);
63 if (filedata == NULL) {
64 printf("Could not load file '%s'.\n", filename);
65 return 1;
66 }
67
68 uint32_t base = 0;
69 void *cbfsfile = NULL;
70
71 if (argc < 6) {
72 printf("not enough arguments to 'add'.\n");
73 return 1;
74 }
75 uint32_t type;
76 if (intfiletype(argv[5]) != ((uint64_t) - 1))
77 type = intfiletype(argv[5]);
78 else
79 type = strtoul(argv[5], NULL, 0);
80 if (argc > 6) {
81 base = strtoul(argv[6], NULL, 0);
82 }
83 cbfsfile = create_cbfs_file(cbfsname, filedata, &filesize, type, &base);
84 if (add_file_to_cbfs(cbfsfile, filesize, base))
85 return 1;
86 if (writerom(romname, rom, romsize))
87 return 1;
88 return 0;
89}
90
91static int cbfs_add_payload(int argc, char **argv)
92{
93 char *romname = argv[1];
94 char *cmd = argv[2];
95 void *rom = loadrom(romname);
96
97 if (rom == NULL) {
98 printf("Could not load ROM image '%s'.\n", romname);
99 return 1;
100 }
101
102 if (argc < 5) {
103 printf("not enough arguments to '%s'.\n", cmd);
104 return 1;
105 }
106
107 char *filename = argv[3];
108 char *cbfsname = argv[4];
109
110 uint32_t filesize = 0;
111 void *filedata = loadfile(filename, &filesize, 0, SEEK_SET);
112 if (filedata == NULL) {
113 printf("Could not load file '%s'.\n", filename);
114 return 1;
115 }
116
117 uint32_t base = 0;
118 void *cbfsfile = NULL;
119
120 comp_algo algo = CBFS_COMPRESS_NONE;
121 if (argc > 5) {
122 if (argv[5][0] == 'l')
123 algo = CBFS_COMPRESS_LZMA;
124 }
125 if (argc > 6) {
126 base = strtoul(argv[6], NULL, 0);
127 }
128 unsigned char *payload;
129 filesize = parse_elf_to_payload(filedata, &payload, algo);
130 cbfsfile =
131 create_cbfs_file(cbfsname, payload, &filesize,
132 CBFS_COMPONENT_PAYLOAD, &base);
133 if (add_file_to_cbfs(cbfsfile, filesize, base))
134 return 1;
135 if (writerom(romname, rom, romsize))
136 return 1;
137 return 0;
138}
139
140static int cbfs_add_stage(int argc, char **argv)
141{
142 char *romname = argv[1];
143 char *cmd = argv[2];
144 void *rom = loadrom(romname);
145
146 if (rom == NULL) {
147 printf("Could not load ROM image '%s'.\n", romname);
148 return 1;
149 }
150
151 if (argc < 5) {
152 printf("not enough arguments to '%s'.\n", cmd);
153 return 1;
154 }
155
156 char *filename = argv[3];
157 char *cbfsname = argv[4];
158
159 uint32_t filesize = 0;
160 void *filedata = loadfile(filename, &filesize, 0, SEEK_SET);
161 if (filedata == NULL) {
162 printf("Could not load file '%s'.\n", filename);
163 return 1;
164 }
165
166 uint32_t base = 0;
167 void *cbfsfile = NULL;
168
169 comp_algo algo = CBFS_COMPRESS_NONE;
170 if (argc > 5) {
171 if (argv[5][0] == 'l')
172 algo = CBFS_COMPRESS_LZMA;
173 }
174 if (argc > 6) {
175 base = strtoul(argv[6], NULL, 0);
176 }
177 unsigned char *stage;
178 filesize = parse_elf_to_stage(filedata, &stage, algo, &base);
179 cbfsfile =
180 create_cbfs_file(cbfsname, stage, &filesize,
181 CBFS_COMPONENT_STAGE, &base);
182
183 if (add_file_to_cbfs(cbfsfile, filesize, base))
184 return 1;
185 if (writerom(romname, rom, romsize))
186 return 1;
187 return 0;
188}
189
190static int cbfs_create(int argc, char **argv)
191{
192 char *romname = argv[1];
193 char *cmd = argv[2];
194 if (argc < 5) {
195 printf("not enough arguments to 'create'.\n");
196 return 1;
197 }
198
199 char* suffix;
200 uint32_t size = strtoul(argv[3], &suffix, 0);
201 if (tolower(suffix[0])=='k') {
202 size *= 1024;
203 }
204 if (tolower(suffix[0])=='m') {
205 size *= 1024 * 1024;
206 }
207 char *bootblock = argv[4];
208 uint32_t align = 0;
209
210 if (argc > 5)
211 align = strtoul(argv[5], NULL, 0);
212
213 return create_cbfs_image(romname, size, bootblock, align);
214}
215
216static int cbfs_locate(int argc, char **argv)
217{
218 char *romname = argv[1];
219 if (argc < 6) {
220 printf("not enough arguments to 'locate'.\n");
221 return 1;
222 }
223
224 const char *file = argv[3];
225 uint32_t filesize = getfilesize(file);
226 const char *filename = argv[4];
227 int align = strtoul(argv[5], NULL, 0);
228
229 printf("%x\n", cbfs_find_location(romname, filesize, filename, align));
230 return 0;
231}
232
233static int cbfs_print(int argc, char **argv)
234{
235 char *romname = argv[1];
236 char *cmd = argv[2];
237 void *rom = loadrom(romname);
238
239 if (rom == NULL) {
240 printf("Could not load ROM image '%s'.\n", romname);
241 return 1;
242 }
243
244 print_cbfs_directory(romname);
245 return 0;
246}
247
248static int cbfs_extract(int argc, char **argv)
249{
250 char *romname = argv[1];
251 char *cmd = argv[2];
252 void *rom = loadrom(romname);
253
254 if (rom == NULL) {
255 printf("Could not load ROM image '%s'.\n", romname);
256 return 1;
257 }
258
259 if (argc != 5)
260 {
261 printf("Error: you must specify a CBFS name and a file to dump it in.\n");
262 return 1;
263 }
264
265 return extract_file_from_cbfs(romname, argv[3], argv[4]);
266}
267
268struct command commands[] = {
269 {CMD_ADD, "add", cbfs_add},
270 {CMD_ADD_PAYLOAD, "add-payload", cbfs_add_payload},
271 {CMD_ADD_STAGE, "add-stage", cbfs_add_stage},
272 {CMD_CREATE, "create", cbfs_create},
273 {CMD_LOCATE, "locate", cbfs_locate},
274 {CMD_PRINT, "print", cbfs_print},
275 {CMD_EXTRACT, "extract", cbfs_extract},
276};
277
278void usage(void)
279{
280 printf
281 ("cbfstool: Management utility for CBFS formatted ROM images\n\n"
282 "USAGE:\n" " cbfstool [-h]\n"
283 " cbfstool FILE COMMAND [PARAMETERS]...\n\n" "OPTIONs:\n"
284 " -h Display this help message\n\n"
285 "COMMANDs:\n"
286 " add FILE NAME TYPE [base address] Add a component\n"
287 " add-payload FILE NAME [COMP] [base] Add a payload to the ROM\n"
288 " add-stage FILE NAME [COMP] [base] Add a stage to the ROM\n"
289 " create SIZE BOOTBLOCK [ALIGN] Create a ROM file\n"
290 " locate FILE NAME ALIGN Find a place for a file of that size\n"
291 " print Show the contents of the ROM\n"
292 " extract NAME FILE Extracts a raw payload from ROM\n"
293 "\n"
294 "TYPEs:\n"
295 );
296 print_supported_filetypes();
297}
298
299int main(int argc, char **argv)
300{
301 int i;
302
303 if (argc < 3) {
304 usage();
305 return 1;
306 }
307
308 char *cmd = argv[2];
309
310 for (i = 0; i < ARRAY_SIZE(commands); i++) {
311 if (strcmp(cmd, commands[i].name) != 0)
312 continue;
313 return commands[i].function(argc, argv);
314 }
315
316 printf("Unknown command '%s'.\n", cmd);
317 usage();
318 return 1;
319}
320