mirror of
https://github.com/dgibson/dtc.git
synced 2025-10-13 16:27:39 -04:00
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:
|
Where options are:
|
||||||
-d,--debug Dump debug information while decoding the file
|
-d,--debug Dump debug information while decoding the file
|
||||||
-s,--scan Scan for an embedded fdt in given 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 += fdtdump
|
||||||
BIN += fdtget
|
BIN += fdtget
|
||||||
BIN += fdtput
|
BIN += fdtput
|
||||||
|
BIN += fdtoverlay
|
||||||
|
|
||||||
SCRIPTS = dtdiff
|
SCRIPTS = dtdiff
|
||||||
|
|
||||||
|
@ -150,6 +151,7 @@ ifneq ($(DEPTARGETS),)
|
||||||
-include $(FDTDUMP_OBJS:%.o=%.d)
|
-include $(FDTDUMP_OBJS:%.o=%.d)
|
||||||
-include $(FDTGET_OBJS:%.o=%.d)
|
-include $(FDTGET_OBJS:%.o=%.d)
|
||||||
-include $(FDTPUT_OBJS:%.o=%.d)
|
-include $(FDTPUT_OBJS:%.o=%.d)
|
||||||
|
-include $(FDTOVERLAY_OBJS:%.o=%.d)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -226,6 +228,8 @@ fdtget: $(FDTGET_OBJS) $(LIBFDT_archive)
|
||||||
|
|
||||||
fdtput: $(FDTPUT_OBJS) $(LIBFDT_archive)
|
fdtput: $(FDTPUT_OBJS) $(LIBFDT_archive)
|
||||||
|
|
||||||
|
fdtoverlay: $(FDTOVERLAY_OBJS) $(LIBFDT_archive)
|
||||||
|
|
||||||
dist:
|
dist:
|
||||||
git archive --format=tar --prefix=dtc-$(dtc_version)/ HEAD \
|
git archive --format=tar --prefix=dtc-$(dtc_version)/ HEAD \
|
||||||
> ../dtc-$(dtc_version).tar
|
> ../dtc-$(dtc_version).tar
|
||||||
|
@ -280,6 +284,7 @@ TESTS_BIN += convert-dtsv0
|
||||||
TESTS_BIN += fdtput
|
TESTS_BIN += fdtput
|
||||||
TESTS_BIN += fdtget
|
TESTS_BIN += fdtget
|
||||||
TESTS_BIN += fdtdump
|
TESTS_BIN += fdtdump
|
||||||
|
TESTS_BIN += fdtoverlay
|
||||||
ifeq ($(NO_PYTHON),)
|
ifeq ($(NO_PYTHON),)
|
||||||
TESTS_PYLIBFDT += maybe_pylibfdt
|
TESTS_PYLIBFDT += maybe_pylibfdt
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -22,3 +22,9 @@ FDTPUT_SRCS = \
|
||||||
util.c
|
util.c
|
||||||
|
|
||||||
FDTPUT_OBJS = $(FDTPUT_SRCS:%.c=%.o)
|
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…
Add table
Add a link
Reference in a new issue