blob: 6277bd197ddb0cb4ac63d4ba4c9cc5c4a8f5204b [file] [log] [blame]
/*
* Copyright (c) 2014 Brian Swetland
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "bootimage.h"
static const char *outname = "boot.img";
static struct {
const char *cmd;
unsigned kind;
unsigned type;
} types[] = {
{ "lk", KIND_FILE, TYPE_LK },
{ "fpga", KIND_FILE, TYPE_FPGA_IMAGE },
{ "linux", KIND_FILE, TYPE_LINUX_KERNEL },
{ "initrd", KIND_FILE, TYPE_LINUX_INITRD },
{ "devicetree", KIND_FILE, TYPE_DEVICE_TREE },
{ "sysparams", KIND_FILE, TYPE_SYSPARAMS },
{ "board", KIND_BOARD, 0 },
{ "build", KIND_BUILD, 0 },
{ NULL, 0 },
};
void usage(const char *binary)
{
unsigned n;
fprintf(stderr, "usage:\n");
fprintf(stderr, "%s [-h] [-o <output file] section:file ...\n\n", binary);
fprintf(stderr, "Supported section types:\n");
for (n = 0; types[n].cmd != NULL; n++) {
if (types[n].kind == KIND_FILE) {
fprintf(stderr, "\t%s\n", types[n].cmd);
}
}
fprintf(stderr, "\nSupported string types:\n");
for (n = 0; types[n].cmd != NULL; n++) {
if (types[n].kind != KIND_FILE) {
fprintf(stderr, "\t%s\n", types[n].cmd);
}
}
}
int process(bootimage *img, char *cmd, char *arg)
{
unsigned n;
for (n = 0; types[n].cmd != NULL; n++) {
if (strcmp(cmd, types[n].cmd)) {
continue;
}
if (types[n].kind == KIND_FILE) {
if (bootimage_add_file(img, types[n].type, arg) == NULL) {
return -1;
}
} else {
if (bootimage_add_string(img, types[n].kind, arg) == NULL) {
return -1;
}
}
return 0;
}
fprintf(stderr, "unknown command '%s'\n", cmd);
return -1;
}
int main(int argc, char **argv)
{
const char *binary = argv[0];
bootimage *img;
int fd;
int count = 0;
img = bootimage_init();
while (argc > 1) {
char *cmd = argv[1];
char *arg = strchr(cmd, ':');
argc--;
argv++;
if (!strcmp(cmd, "-h") || !strcmp(cmd, "--help")) {
usage(binary);
return 1;
} else if (!strcmp(cmd, "-o")) {
outname = argv[1];
argc--;
argv++;
} else {
if (arg == NULL) {
fprintf(stderr, "error: invalid argument '%s'\n", cmd);
return 1;
}
*arg++ = 0;
if (process(img, cmd, arg)) {
return 1;
}
count++;
}
}
if (count == 0) {
fprintf(stderr, "no sections to process\n");
return 1;
}
bootimage_done(img);
if ((fd = open(outname, O_CREAT|O_TRUNC|O_WRONLY, 0644)) < 0) {
fprintf(stderr, "error: cannot open '%s' for writing\n", outname);
return 1;
}
if (bootimage_write(img, fd)) {
fprintf(stderr, "error: failed to write '%s'\n", outname);
unlink(outname);
return 1;
}
close(fd);
return 0;
}