1 /*
2 * Copyright (c) 2014 Brian Swetland
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <fcntl.h>
14
15 #include "bootimage.h"
16
17 static const char *outname = "boot.img";
18
19 static struct {
20 const char *cmd;
21 unsigned kind;
22 unsigned type;
23 } types[] = {
24 { "lk", KIND_FILE, TYPE_LK },
25 { "fpga", KIND_FILE, TYPE_FPGA_IMAGE },
26 { "linux", KIND_FILE, TYPE_LINUX_KERNEL },
27 { "initrd", KIND_FILE, TYPE_LINUX_INITRD },
28 { "devicetree", KIND_FILE, TYPE_DEVICE_TREE },
29 { "sysparams", KIND_FILE, TYPE_SYSPARAMS },
30 { "board", KIND_BOARD, 0 },
31 { "build", KIND_BUILD, 0 },
32 { NULL, 0 },
33 };
34
usage(const char * binary)35 void usage(const char *binary) {
36 unsigned n;
37 fprintf(stderr, "usage:\n");
38 fprintf(stderr, "%s [-h] [-o <output file] section:file ...\n\n", binary);
39
40 fprintf(stderr, "Supported section types:\n");
41 for (n = 0; types[n].cmd != NULL; n++) {
42 if (types[n].kind == KIND_FILE) {
43 fprintf(stderr, "\t%s\n", types[n].cmd);
44 }
45 }
46
47 fprintf(stderr, "\nSupported string types:\n");
48 for (n = 0; types[n].cmd != NULL; n++) {
49 if (types[n].kind != KIND_FILE) {
50 fprintf(stderr, "\t%s\n", types[n].cmd);
51 }
52 }
53 }
54
process(bootimage * img,char * cmd,char * arg)55 int process(bootimage *img, char *cmd, char *arg) {
56 unsigned n;
57
58 for (n = 0; types[n].cmd != NULL; n++) {
59 if (strcmp(cmd, types[n].cmd)) {
60 continue;
61 }
62 if (types[n].kind == KIND_FILE) {
63 if (bootimage_add_file(img, types[n].type, arg) == NULL) {
64 return -1;
65 }
66 } else {
67 if (bootimage_add_string(img, types[n].kind, arg) == NULL) {
68 return -1;
69 }
70 }
71 return 0;
72 }
73
74 fprintf(stderr, "unknown command '%s'\n", cmd);
75 return -1;
76 }
77
main(int argc,char ** argv)78 int main(int argc, char **argv) {
79 const char *binary = argv[0];
80 bootimage *img;
81 int fd;
82 int count = 0;
83
84 img = bootimage_init();
85
86 while (argc > 1) {
87 char *cmd = argv[1];
88 char *arg = strchr(cmd, ':');
89 argc--;
90 argv++;
91
92 if (!strcmp(cmd, "-h") || !strcmp(cmd, "--help")) {
93 usage(binary);
94 return 1;
95 } else if (!strcmp(cmd, "-o")) {
96 outname = argv[1];
97 argc--;
98 argv++;
99 } else {
100 if (arg == NULL) {
101 fprintf(stderr, "error: invalid argument '%s'\n", cmd);
102 return 1;
103 }
104
105 *arg++ = 0;
106
107 if (process(img, cmd, arg)) {
108 return 1;
109 }
110 count++;
111 }
112 }
113
114 if (count == 0) {
115 fprintf(stderr, "no sections to process\n");
116 return 1;
117 }
118
119 bootimage_done(img);
120
121 if ((fd = open(outname, O_CREAT|O_TRUNC|O_WRONLY, 0644)) < 0) {
122 fprintf(stderr, "error: cannot open '%s' for writing\n", outname);
123 return 1;
124 }
125 if (bootimage_write(img, fd)) {
126 fprintf(stderr, "error: failed to write '%s'\n", outname);
127 unlink(outname);
128 return 1;
129 }
130 close(fd);
131 return 0;
132 }
133