blob: 961e9dc918000be005ecab97f04e3579b2a97b28 [file] [log] [blame]
Sol Boucher69b88bf2015-02-26 11:47:19 -08001/*
2 * fmaptool, CLI utility for converting plaintext fmd files into fmap blobs
3 *
4 * Copyright (C) 2015 Google, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
18 */
19
20#include "common.h"
21#include "fmap_from_fmd.h"
22
23#include <stdio.h>
24#include <string.h>
25
26#define STDIN_FILENAME_SENTINEL "-"
27
28enum fmaptool_return {
29 FMAPTOOL_EXIT_SUCCESS = 0,
30 FMAPTOOL_EXIT_BAD_ARGS,
31 FMAPTOOL_EXIT_BAD_INPUT_PATH,
32 FMAPTOOL_EXIT_BAD_OUTPUT_PATH,
33 FMAPTOOL_EXIT_FAILED_DESCRIPTOR,
34 FMAPTOOL_EXIT_FAILED_FMAP_CONVERSION,
35 FMAPTOOL_EXIT_UNKNOWN_FMAP_SIZE,
36 FMAPTOOL_EXIT_FAILED_WRITING_FILE,
37};
38
39bool fmd_process_annotation_impl(unused const struct flashmap_descriptor *node,
40 unused const char *annotation)
41{
42 // We always accept annotations, but never act on them.
43 return true;
44}
45
46int main(int argc, char **argv)
47{
48 if (argc != 3) {
49 fputs("Convert a human-readable flashmap descriptor (fmd) file into the binary FMAP format for use in firmware images\n",
50 stderr);
51 fprintf(stderr,
52 "USAGE: %s <fmd input file> <binary output file>\n",
53 argv[0]);
54 fprintf(stderr,
55 "To read from standard input, provide '%s' as the input filename.\n",
56 STDIN_FILENAME_SENTINEL);
57 return FMAPTOOL_EXIT_BAD_ARGS;
58 }
59 const char *fmd_filename = argv[1];
60 const char *fmap_filename = argv[2];
61
62 FILE *fmd_file = stdin;
63 if (strcmp(fmd_filename, STDIN_FILENAME_SENTINEL) != 0) {
64 fmd_file = fopen(fmd_filename, "r");
65 if (!fmd_file) {
66 fprintf(stderr, "FATAL: Unable to open file '%s'\n",
67 fmd_filename);
68 return FMAPTOOL_EXIT_BAD_INPUT_PATH;
69 }
70 }
71
72 struct flashmap_descriptor *descriptor = fmd_create(fmd_file);
73 fclose(fmd_file);
74 if (!descriptor) {
75 fputs("FATAL: Failed while processing provided descriptor\n",
76 stderr);
77 return FMAPTOOL_EXIT_FAILED_DESCRIPTOR;
78 }
79
80 struct fmap *flashmap = fmap_from_fmd(descriptor);
81 if (!flashmap) {
82 fputs("FATAL: Failed while constructing FMAP section\n",
83 stderr);
84 fmd_cleanup(descriptor);
85 return FMAPTOOL_EXIT_FAILED_FMAP_CONVERSION;
86 }
87
88 int size = fmap_size(flashmap);
89 if (size < 0) {
90 fputs("FATAL: Failed to determine FMAP section size\n",
91 stderr);
92 fmap_destroy(flashmap);
93 fmd_cleanup(descriptor);
94 return FMAPTOOL_EXIT_UNKNOWN_FMAP_SIZE;
95 }
96
97 FILE *fmap_file = fopen(fmap_filename, "wb");
98 if (!fmap_file) {
99 fprintf(stderr, "FATAL: Unable to open file '%s' for writing\n",
100 fmap_filename);
101 fmap_destroy(flashmap);
102 fmd_cleanup(descriptor);
103 return FMAPTOOL_EXIT_BAD_OUTPUT_PATH;
104 }
105
106 if (!fwrite(flashmap, size, 1, fmap_file)) {
107 fputs("FATAL: Failed to write final FMAP to file\n", stderr);
108 fclose(fmap_file);
109 fmap_destroy(flashmap);
110 fmd_cleanup(descriptor);
111 return FMAPTOOL_EXIT_FAILED_WRITING_FILE;
112 }
113 fclose(fmap_file);
114 printf("SUCCESS: Wrote %d bytes to file '%s'\n", size, fmap_filename);
115
116 fmap_destroy(flashmap);
117 fmd_cleanup(descriptor);
118 return FMAPTOOL_EXIT_SUCCESS;
119}