blob: 961e9dc918000be005ecab97f04e3579b2a97b28 [file] [log] [blame]
/*
* fmaptool, CLI utility for converting plaintext fmd files into fmap blobs
*
* Copyright (C) 2015 Google, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
*/
#include "common.h"
#include "fmap_from_fmd.h"
#include <stdio.h>
#include <string.h>
#define STDIN_FILENAME_SENTINEL "-"
enum fmaptool_return {
FMAPTOOL_EXIT_SUCCESS = 0,
FMAPTOOL_EXIT_BAD_ARGS,
FMAPTOOL_EXIT_BAD_INPUT_PATH,
FMAPTOOL_EXIT_BAD_OUTPUT_PATH,
FMAPTOOL_EXIT_FAILED_DESCRIPTOR,
FMAPTOOL_EXIT_FAILED_FMAP_CONVERSION,
FMAPTOOL_EXIT_UNKNOWN_FMAP_SIZE,
FMAPTOOL_EXIT_FAILED_WRITING_FILE,
};
bool fmd_process_annotation_impl(unused const struct flashmap_descriptor *node,
unused const char *annotation)
{
// We always accept annotations, but never act on them.
return true;
}
int main(int argc, char **argv)
{
if (argc != 3) {
fputs("Convert a human-readable flashmap descriptor (fmd) file into the binary FMAP format for use in firmware images\n",
stderr);
fprintf(stderr,
"USAGE: %s <fmd input file> <binary output file>\n",
argv[0]);
fprintf(stderr,
"To read from standard input, provide '%s' as the input filename.\n",
STDIN_FILENAME_SENTINEL);
return FMAPTOOL_EXIT_BAD_ARGS;
}
const char *fmd_filename = argv[1];
const char *fmap_filename = argv[2];
FILE *fmd_file = stdin;
if (strcmp(fmd_filename, STDIN_FILENAME_SENTINEL) != 0) {
fmd_file = fopen(fmd_filename, "r");
if (!fmd_file) {
fprintf(stderr, "FATAL: Unable to open file '%s'\n",
fmd_filename);
return FMAPTOOL_EXIT_BAD_INPUT_PATH;
}
}
struct flashmap_descriptor *descriptor = fmd_create(fmd_file);
fclose(fmd_file);
if (!descriptor) {
fputs("FATAL: Failed while processing provided descriptor\n",
stderr);
return FMAPTOOL_EXIT_FAILED_DESCRIPTOR;
}
struct fmap *flashmap = fmap_from_fmd(descriptor);
if (!flashmap) {
fputs("FATAL: Failed while constructing FMAP section\n",
stderr);
fmd_cleanup(descriptor);
return FMAPTOOL_EXIT_FAILED_FMAP_CONVERSION;
}
int size = fmap_size(flashmap);
if (size < 0) {
fputs("FATAL: Failed to determine FMAP section size\n",
stderr);
fmap_destroy(flashmap);
fmd_cleanup(descriptor);
return FMAPTOOL_EXIT_UNKNOWN_FMAP_SIZE;
}
FILE *fmap_file = fopen(fmap_filename, "wb");
if (!fmap_file) {
fprintf(stderr, "FATAL: Unable to open file '%s' for writing\n",
fmap_filename);
fmap_destroy(flashmap);
fmd_cleanup(descriptor);
return FMAPTOOL_EXIT_BAD_OUTPUT_PATH;
}
if (!fwrite(flashmap, size, 1, fmap_file)) {
fputs("FATAL: Failed to write final FMAP to file\n", stderr);
fclose(fmap_file);
fmap_destroy(flashmap);
fmd_cleanup(descriptor);
return FMAPTOOL_EXIT_FAILED_WRITING_FILE;
}
fclose(fmap_file);
printf("SUCCESS: Wrote %d bytes to file '%s'\n", size, fmap_filename);
fmap_destroy(flashmap);
fmd_cleanup(descriptor);
return FMAPTOOL_EXIT_SUCCESS;
}