blob: a4263aa6bc86abccf8539534a30b8725bfe2644b [file] [log] [blame]
Peer Chen8d782ee2011-01-18 21:34:18 -05001/**
2 * Copyright (c) 2011 NVIDIA Corporation. All rights reserved.
3 *
4 * See file CREDITS for list of people who contributed to this
5 * project.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
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., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23/*
24 * cbootimage.c - Implementation of the cbootimage tool.
25 */
26
27#include "cbootimage.h"
28#include "nvbctlib.h"
29#include "crypto.h"
30#include "data_layout.h"
31#include "parse.h"
32#include "set.h"
Anton Staaf73664ab2011-02-17 09:22:32 -080033#include "context.h"
Peer Chen8d782ee2011-01-18 21:34:18 -050034
35/*
36 * Global data
37 */
38int enable_debug = 0;
39
40static int help_only = 0; // Only print help & exit
41
42/*
43 * Function prototypes
44 */
45int main(int argc, char *argv[]);
46
Peer Chen8d782ee2011-01-18 21:34:18 -050047int
48write_image_file(build_image_context *context)
49{
50 assert(context != NULL);
51
52 return write_block_raw(context);
53}
54
55static void
56usage(void)
57{
58 printf("Usage: cbootimage [options] configfile imagename\n");
59 printf(" options:\n");
60 printf(" -h, --help, -? Display this message.\n");
61 printf(" -d, --debug Output debugging information.\n");
Peer Chen7557d9b2011-02-24 09:29:23 -080062 printf(" -gbct Generate the new bct file.\n");
Peer Chen8d782ee2011-01-18 21:34:18 -050063 printf(" configfile File with configuration information\n");
64 printf(" imagename Output image name\n");
65}
66
67static int
68process_command_line(int argc, char *argv[], build_image_context *context)
69{
70 int arg = 1;
71
Peer Chen7557d9b2011-02-24 09:29:23 -080072 context->generate_bct = 0;
73
Peer Chen8d782ee2011-01-18 21:34:18 -050074 while (arg < argc) {
75 /* Process the next argument. */
76 if (!strcmp(argv[arg], "-h") ||
77 !strcmp(argv[arg], "--help") ||
78 !strcmp(argv[arg], "-?")) {
79 help_only = 1;
80 usage();
81 return 0;
82 } else if (!strcmp(argv[arg], "-d") ||
83 !strcmp(argv[arg], "--debug")) {
84 enable_debug = 1;
85 arg++;
Peer Chen7557d9b2011-02-24 09:29:23 -080086 } else if (!strcmp(argv[arg], "-gbct")) {
87 context->generate_bct = 1;
88 arg++;
Peer Chen8d782ee2011-01-18 21:34:18 -050089 } else if (argv[arg][0] == '-') {
90 printf("Illegal option %s\n", argv[arg]);
91 usage();
92 return -EINVAL;
93 }
94 else
95 break; /* Finished with options */
96 }
97
98 /* Handle file specification errors. */
99 switch (argc - arg) {
100 case 0:
101 printf("Missing configuration and image file names.\n");
102 usage();
103 return -EINVAL;
104
105 case 1:
106 printf("Missing configuration or image file name.\n");
107 usage();
108 return -EINVAL;
109
110 case 2:
111 /* Correct args, so break from the switch statement. */
112 break;
113
114 default:
115 printf("Too many arguments.\n");
116 usage();
117 return -EINVAL;
118 }
119
120 /* Open the configuration file. */
121 context->config_file = fopen(argv[arg], "r");
122 if (context->config_file == NULL) {
123 printf("Error opening config file.\n");
124 return -ENODATA;
125 }
126
127 /* Record the output filename */
128 context->image_filename = argv[arg + 1];
129
130 /* Set up the Nvbctlib function pointers. */
131 nvbct_lib_get_fns(&(context->bctlib));
132
133 return 0;
134}
135
136int
137main(int argc, char *argv[])
138{
139 int e = 0;
140 build_image_context context;
141 u_int32_t data = 0;
142
143 memset(&context, 0, sizeof(build_image_context));
144
145 /* Process command line arguments. */
146 if (process_command_line(argc, argv, &context) != 0)
147 return -EINVAL;
148
149 if (help_only)
150 return 1;
151
152 e = init_context(&context);
153 if (e != 0) {
154 printf("context initialization failed. Aborting.\n");
155 return e;
156 }
157
158 if (enable_debug) {
159 /* Debugging information... */
160 e = context.bctlib.get_value(nvbct_lib_id_bct_size,
161 &data, context.bct);
162 printf("bct size: %d\n", e == 0 ? data : -1);
163 }
164
165 /* Open the raw output file. */
166 context.raw_file = fopen(context.image_filename,
167 "w+");
168 if (context.raw_file == NULL) {
169 printf("Error opening raw file %s.\n",
170 context.image_filename);
171 goto fail;
172 }
173
174 /* Parse & process the contents of the config file. */
175 process_config_file(&context);
176
Peer Chen7557d9b2011-02-24 09:29:23 -0800177 /* Generate the new bct file */
178 if (context.generate_bct != 0) {
Peer Chen053d5782011-03-03 10:12:58 -0800179 /* Update the BCT */
180 begin_update(&context);
Peer Chen7557d9b2011-02-24 09:29:23 -0800181 /* Signing the bct. */
182 e = sign_bct(&context, context.bct);
183 if (e != 0)
184 printf("Signing BCT failed, error: %d.\n", e);
185
186 fwrite(context.bct, 1, sizeof(nvboot_config_table),
187 context.raw_file);
188 printf("New BCT file %s has been successfully generated!\n",
189 context.image_filename);
190 goto fail;
191 }
192
Peer Chen8d782ee2011-01-18 21:34:18 -0500193 /* Update the bct file */
194 /* Update the add on file */
195 e = update_addon_item(&context);
196 if ( e!= 0) {
197 printf("Write addon item failed, error: %d.\n", e);
198 goto fail;
199 }
200 /* Peform final signing & encryption of bct. */
201 e = sign_bct(&context, context.bct);
202 if (e != 0) {
203 printf("Signing BCT failed, error: %d.\n", e);
204 goto fail;
205 }
206 /* Write the image file. */
207 /* The image hasn't been written yet. */
208 if (write_image_file(&context) != 0)
209 printf("Error writing image file.\n");
210 else
211 printf("Image file %s has been successfully generated!\n",
212 context.image_filename);
213
214 fail:
215 /* Close the file(s). */
216 if (context.raw_file)
217 fclose(context.raw_file);
218
219 /* Clean up memory. */
220 cleanup_context(&context);
221
222 return e;
223}