blob: aceaa8634e3d0e8b0b58e32662844de5a8e21020 [file] [log] [blame]
xjb04a4022021-11-25 15:01:52 +08001/*
2 * Copyright (c) 2014 Brian Swetland
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <unistd.h>
28#include <fcntl.h>
29
30#include "bootimage.h"
31
32static const char *outname = "boot.img";
33
34static struct {
35 const char *cmd;
36 unsigned kind;
37 unsigned type;
38} types[] = {
39 { "lk", KIND_FILE, TYPE_LK },
40 { "fpga", KIND_FILE, TYPE_FPGA_IMAGE },
41 { "linux", KIND_FILE, TYPE_LINUX_KERNEL },
42 { "initrd", KIND_FILE, TYPE_LINUX_INITRD },
43 { "devicetree", KIND_FILE, TYPE_DEVICE_TREE },
44 { "sysparams", KIND_FILE, TYPE_SYSPARAMS },
45 { "board", KIND_BOARD, 0 },
46 { "build", KIND_BUILD, 0 },
47 { NULL, 0 },
48};
49
50void usage(const char *binary) {
51 unsigned n;
52 fprintf(stderr, "usage:\n");
53 fprintf(stderr, "%s [-h] [-o <output file] section:file ...\n\n", binary);
54
55 fprintf(stderr, "Supported section types:\n");
56 for (n = 0; types[n].cmd != NULL; n++) {
57 if (types[n].kind == KIND_FILE) {
58 fprintf(stderr, "\t%s\n", types[n].cmd);
59 }
60 }
61
62 fprintf(stderr, "\nSupported string types:\n");
63 for (n = 0; types[n].cmd != NULL; n++) {
64 if (types[n].kind != KIND_FILE) {
65 fprintf(stderr, "\t%s\n", types[n].cmd);
66 }
67 }
68}
69
70int process(bootimage *img, char *cmd, char *arg) {
71 unsigned n;
72
73 for (n = 0; types[n].cmd != NULL; n++) {
74 if (strcmp(cmd, types[n].cmd)) {
75 continue;
76 }
77 if (types[n].kind == KIND_FILE) {
78 if (bootimage_add_file(img, types[n].type, arg) == NULL) {
79 return -1;
80 }
81 } else {
82 if (bootimage_add_string(img, types[n].kind, arg) == NULL) {
83 return -1;
84 }
85 }
86 return 0;
87 }
88
89 fprintf(stderr, "unknown command '%s'\n", cmd);
90 return -1;
91}
92
93int main(int argc, char **argv) {
94 const char *binary = argv[0];
95 bootimage *img;
96 int fd;
97 int count = 0;
98
99 img = bootimage_init();
100
101 while (argc > 1) {
102 char *cmd = argv[1];
103 char *arg = strchr(cmd, ':');
104 argc--;
105 argv++;
106
107 if (!strcmp(cmd, "-h") || !strcmp(cmd, "--help")) {
108 usage(binary);
109 return 1;
110 } else if (!strcmp(cmd, "-o")) {
111 outname = argv[1];
112 argc--;
113 argv++;
114 } else {
115 if (arg == NULL) {
116 fprintf(stderr, "error: invalid argument '%s'\n", cmd);
117 return 1;
118 }
119
120 *arg++ = 0;
121
122 if (process(img, cmd, arg)) {
123 return 1;
124 }
125 count++;
126 }
127 }
128
129 if (count == 0) {
130 fprintf(stderr, "no sections to process\n");
131 return 1;
132 }
133
134 bootimage_done(img);
135
136 if ((fd = open(outname, O_CREAT|O_TRUNC|O_WRONLY, 0644)) < 0) {
137 fprintf(stderr, "error: cannot open '%s' for writing\n", outname);
138 return 1;
139 }
140 if (bootimage_write(img, fd)) {
141 fprintf(stderr, "error: failed to write '%s'\n", outname);
142 unlink(outname);
143 return 1;
144 }
145 close(fd);
146 return 0;
147}
148
149// vim: set noexpandtab: