fdtoverlay: A tool that applies overlays
Since libfdt support overlay application on FDT blobs, provide a command line tool that applies an arbitrary number of overlays, one after another to a base fdt blob and output the result in the given file. Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
aae22722fc
commit
42409146f2
4 changed files with 193 additions and 0 deletions
|
@ -679,3 +679,17 @@ The syntax of the fdtdump command line is:
|
|||
Where options are:
|
||||
-d,--debug Dump debug information while decoding the file
|
||||
-s,--scan Scan for an embedded fdt in given file
|
||||
|
||||
3) fdtoverlay -- Flat Device Tree overlay applicator
|
||||
|
||||
The fdtoverlay applies an arbitrary number of FDT overlays to a base FDT blob
|
||||
to a given output file.
|
||||
|
||||
The syntax of the fdtoverlay command line is:
|
||||
|
||||
fdtoverlay -i <base-blob> -o <output-blob> <overlay-blob0> [<overlay-blob1> ...]
|
||||
|
||||
Where options are:
|
||||
-i, --input Input base DT blob
|
||||
-o, --output Output DT blob
|
||||
-v, --verbose Verbose message output
|
||||
|
|
5
Makefile
5
Makefile
|
@ -120,6 +120,7 @@ BIN += dtc
|
|||
BIN += fdtdump
|
||||
BIN += fdtget
|
||||
BIN += fdtput
|
||||
BIN += fdtoverlay
|
||||
|
||||
SCRIPTS = dtdiff
|
||||
|
||||
|
@ -150,6 +151,7 @@ ifneq ($(DEPTARGETS),)
|
|||
-include $(FDTDUMP_OBJS:%.o=%.d)
|
||||
-include $(FDTGET_OBJS:%.o=%.d)
|
||||
-include $(FDTPUT_OBJS:%.o=%.d)
|
||||
-include $(FDTOVERLAY_OBJS:%.o=%.d)
|
||||
endif
|
||||
|
||||
|
||||
|
@ -226,6 +228,8 @@ fdtget: $(FDTGET_OBJS) $(LIBFDT_archive)
|
|||
|
||||
fdtput: $(FDTPUT_OBJS) $(LIBFDT_archive)
|
||||
|
||||
fdtoverlay: $(FDTOVERLAY_OBJS) $(LIBFDT_archive)
|
||||
|
||||
dist:
|
||||
git archive --format=tar --prefix=dtc-$(dtc_version)/ HEAD \
|
||||
> ../dtc-$(dtc_version).tar
|
||||
|
@ -280,6 +284,7 @@ TESTS_BIN += convert-dtsv0
|
|||
TESTS_BIN += fdtput
|
||||
TESTS_BIN += fdtget
|
||||
TESTS_BIN += fdtdump
|
||||
TESTS_BIN += fdtoverlay
|
||||
ifeq ($(NO_PYTHON),)
|
||||
TESTS_PYLIBFDT += maybe_pylibfdt
|
||||
endif
|
||||
|
|
|
@ -22,3 +22,9 @@ FDTPUT_SRCS = \
|
|||
util.c
|
||||
|
||||
FDTPUT_OBJS = $(FDTPUT_SRCS:%.c=%.o)
|
||||
|
||||
FDTOVERLAY_SRCS = \
|
||||
fdtoverlay.c \
|
||||
util.c
|
||||
|
||||
FDTOVERLAY_OBJS = $(FDTOVERLAY_SRCS:%.c=%.o)
|
||||
|
|
168
fdtoverlay.c
Normal file
168
fdtoverlay.c
Normal file
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Konsulko Group Inc. All rights reserved.
|
||||
*
|
||||
* Author:
|
||||
* Pantelis Antoniou <pantelis.antoniou@konsulko.com>
|
||||
*
|
||||
* 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; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <alloca.h>
|
||||
|
||||
#include <libfdt.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
/* Usage related data. */
|
||||
static const char usage_synopsis[] =
|
||||
"apply a number of overlays to a base blob\n"
|
||||
" fdtoverlay <options> [<overlay.dtbo> [<overlay.dtbo>]]\n"
|
||||
"\n"
|
||||
USAGE_TYPE_MSG;
|
||||
static const char usage_short_opts[] = "i:o:v" USAGE_COMMON_SHORT_OPTS;
|
||||
static struct option const usage_long_opts[] = {
|
||||
{"input", required_argument, NULL, 'i'},
|
||||
{"output", required_argument, NULL, 'o'},
|
||||
{"verbose", no_argument, NULL, 'v'},
|
||||
USAGE_COMMON_LONG_OPTS,
|
||||
};
|
||||
static const char * const usage_opts_help[] = {
|
||||
"Input base DT blob",
|
||||
"Output DT blob",
|
||||
"Verbose messages",
|
||||
USAGE_COMMON_OPTS_HELP
|
||||
};
|
||||
|
||||
int verbose = 0;
|
||||
|
||||
static int do_fdtoverlay(const char *input_filename,
|
||||
const char *output_filename,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
char *blob = NULL;
|
||||
char **ovblob = NULL;
|
||||
off_t blob_len, ov_len, total_len;
|
||||
int i, ret = -1;
|
||||
|
||||
blob = utilfdt_read_len(input_filename, &blob_len);
|
||||
if (!blob) {
|
||||
fprintf(stderr, "\nFailed to read base blob %s\n",
|
||||
input_filename);
|
||||
goto out_err;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
/* allocate blob pointer array */
|
||||
ovblob = alloca(sizeof(*ovblob) * argc);
|
||||
memset(ovblob, 0, sizeof(*ovblob) * argc);
|
||||
|
||||
/* read and keep track of the overlay blobs */
|
||||
total_len = 0;
|
||||
for (i = 0; i < argc; i++) {
|
||||
ovblob[i] = utilfdt_read_len(argv[i], &ov_len);
|
||||
if (!ovblob[i]) {
|
||||
fprintf(stderr, "\nFailed to read overlay %s\n",
|
||||
argv[i]);
|
||||
goto out_err;
|
||||
}
|
||||
total_len += ov_len;
|
||||
}
|
||||
|
||||
/* grow the blob to worst case */
|
||||
blob_len = fdt_totalsize(blob) + total_len;
|
||||
blob = xrealloc(blob, blob_len);
|
||||
fdt_open_into(blob, blob, blob_len);
|
||||
|
||||
/* apply the overlays in sequence */
|
||||
for (i = 0; i < argc; i++) {
|
||||
ret = fdt_overlay_apply(blob, ovblob[i]);
|
||||
if (ret) {
|
||||
fprintf(stderr, "\nFailed to apply %s (%d)\n",
|
||||
argv[i], ret);
|
||||
goto out_err;
|
||||
}
|
||||
}
|
||||
|
||||
fdt_pack(blob);
|
||||
ret = utilfdt_write(output_filename, blob);
|
||||
if (ret)
|
||||
fprintf(stderr, "\nFailed to write output blob %s\n",
|
||||
output_filename);
|
||||
|
||||
out_err:
|
||||
if (ovblob) {
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (ovblob[i])
|
||||
free(ovblob[i]);
|
||||
}
|
||||
}
|
||||
free(blob);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int opt, i;
|
||||
char *input_filename = NULL;
|
||||
char *output_filename = NULL;
|
||||
|
||||
while ((opt = util_getopt_long()) != EOF) {
|
||||
switch (opt) {
|
||||
case_USAGE_COMMON_FLAGS
|
||||
|
||||
case 'i':
|
||||
input_filename = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
output_filename = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!input_filename)
|
||||
usage("missing input file");
|
||||
|
||||
if (!output_filename)
|
||||
usage("missing output file");
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
if (argc <= 0)
|
||||
usage("missing overlay file(s)");
|
||||
|
||||
if (verbose) {
|
||||
printf("input = %s\n", input_filename);
|
||||
printf("output = %s\n", output_filename);
|
||||
for (i = 0; i < argc; i++)
|
||||
printf("overlay[%d] = %s\n", i, argv[i]);
|
||||
}
|
||||
|
||||
if (do_fdtoverlay(input_filename, output_filename, argc, argv))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue