~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/dtc/fdtoverlay.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * Copyright (c) 2017 Konsulko Group Inc. All rights reserved.
  4  *
  5  * Author:
  6  *       Pantelis Antoniou <pantelis.antoniou@konsulko.com>
  7  */
  8 
  9 #include <assert.h>
 10 #include <ctype.h>
 11 #include <getopt.h>
 12 #include <stdio.h>
 13 #include <stdlib.h>
 14 #include <string.h>
 15 #include <inttypes.h>
 16 
 17 #include <libfdt.h>
 18 
 19 #include "util.h"
 20 
 21 #define BUF_INCREMENT   65536
 22 
 23 /* Usage related data. */
 24 static const char usage_synopsis[] =
 25         "apply a number of overlays to a base blob\n"
 26         "       fdtoverlay <options> [<overlay.dtbo> [<overlay.dtbo>]]";
 27 static const char usage_short_opts[] = "i:o:v" USAGE_COMMON_SHORT_OPTS;
 28 static struct option const usage_long_opts[] = {
 29         {"input",            required_argument, NULL, 'i'},
 30         {"output",           required_argument, NULL, 'o'},
 31         {"verbose",                no_argument, NULL, 'v'},
 32         USAGE_COMMON_LONG_OPTS,
 33 };
 34 static const char * const usage_opts_help[] = {
 35         "Input base DT blob",
 36         "Output DT blob",
 37         "Verbose messages",
 38         USAGE_COMMON_OPTS_HELP
 39 };
 40 
 41 int verbose = 0;
 42 
 43 static void *apply_one(char *base, const char *overlay, size_t *buf_len,
 44                        const char *name)
 45 {
 46         char *tmp = NULL;
 47         char *tmpo;
 48         int ret;
 49 
 50         /*
 51          * We take a copies first, because a failed apply can trash
 52          * both the base blob and the overlay
 53          */
 54         tmpo = xmalloc(fdt_totalsize(overlay));
 55 
 56         do {
 57                 tmp = xrealloc(tmp, *buf_len);
 58                 ret = fdt_open_into(base, tmp, *buf_len);
 59                 if (ret) {
 60                         fprintf(stderr,
 61                                 "\nFailed to make temporary copy: %s\n",
 62                                 fdt_strerror(ret));
 63                         goto fail;
 64                 }
 65 
 66                 memcpy(tmpo, overlay, fdt_totalsize(overlay));
 67 
 68                 ret = fdt_overlay_apply(tmp, tmpo);
 69                 if (ret == -FDT_ERR_NOSPACE) {
 70                         *buf_len += BUF_INCREMENT;
 71                 }
 72         } while (ret == -FDT_ERR_NOSPACE);
 73 
 74         if (ret) {
 75                 fprintf(stderr, "\nFailed to apply '%s': %s\n",
 76                         name, fdt_strerror(ret));
 77                 goto fail;
 78         }
 79 
 80         free(base);
 81         free(tmpo);
 82         return tmp;
 83 
 84 fail:
 85         free(tmpo);
 86         if (tmp)
 87                 free(tmp);
 88 
 89         return NULL;
 90 }
 91 static int do_fdtoverlay(const char *input_filename,
 92                          const char *output_filename,
 93                          int argc, char *argv[])
 94 {
 95         char *blob = NULL;
 96         char **ovblob = NULL;
 97         size_t buf_len;
 98         int i, ret = -1;
 99 
100         blob = utilfdt_read(input_filename, &buf_len);
101         if (!blob) {
102                 fprintf(stderr, "\nFailed to read '%s'\n", input_filename);
103                 goto out_err;
104         }
105         if (fdt_totalsize(blob) > buf_len) {
106                 fprintf(stderr,
107  "\nBase blob is incomplete (%lu / %" PRIu32 " bytes read)\n",
108                         (unsigned long)buf_len, fdt_totalsize(blob));
109                 goto out_err;
110         }
111 
112         /* allocate blob pointer array */
113         ovblob = xmalloc(sizeof(*ovblob) * argc);
114         memset(ovblob, 0, sizeof(*ovblob) * argc);
115 
116         /* read and keep track of the overlay blobs */
117         for (i = 0; i < argc; i++) {
118                 size_t ov_len;
119                 ovblob[i] = utilfdt_read(argv[i], &ov_len);
120                 if (!ovblob[i]) {
121                         fprintf(stderr, "\nFailed to read '%s'\n", argv[i]);
122                         goto out_err;
123                 }
124                 if (fdt_totalsize(ovblob[i]) > ov_len) {
125                         fprintf(stderr,
126 "\nOverlay '%s' is incomplete (%lu / %" PRIu32 " bytes read)\n",
127                                 argv[i], (unsigned long)ov_len,
128                                 fdt_totalsize(ovblob[i]));
129                         goto out_err;
130                 }
131         }
132 
133         buf_len = fdt_totalsize(blob);
134 
135         /* apply the overlays in sequence */
136         for (i = 0; i < argc; i++) {
137                 blob = apply_one(blob, ovblob[i], &buf_len, argv[i]);
138                 if (!blob)
139                         goto out_err;
140         }
141 
142         fdt_pack(blob);
143         ret = utilfdt_write(output_filename, blob);
144         if (ret)
145                 fprintf(stderr, "\nFailed to write '%s'\n",
146                         output_filename);
147 
148 out_err:
149         if (ovblob) {
150                 for (i = 0; i < argc; i++) {
151                         if (ovblob[i])
152                                 free(ovblob[i]);
153                 }
154                 free(ovblob);
155         }
156         free(blob);
157 
158         return ret;
159 }
160 
161 int main(int argc, char *argv[])
162 {
163         int opt, i;
164         char *input_filename = NULL;
165         char *output_filename = NULL;
166 
167         while ((opt = util_getopt_long()) != EOF) {
168                 switch (opt) {
169                 case_USAGE_COMMON_FLAGS
170 
171                 case 'i':
172                         input_filename = optarg;
173                         break;
174                 case 'o':
175                         output_filename = optarg;
176                         break;
177                 case 'v':
178                         verbose = 1;
179                         break;
180                 }
181         }
182 
183         if (!input_filename)
184                 usage("missing input file");
185 
186         if (!output_filename)
187                 usage("missing output file");
188 
189         argv += optind;
190         argc -= optind;
191 
192         if (argc <= 0)
193                 usage("missing overlay file(s)");
194 
195         if (verbose) {
196                 printf("input  = %s\n", input_filename);
197                 printf("output = %s\n", output_filename);
198                 for (i = 0; i < argc; i++)
199                         printf("overlay[%d] = %s\n", i, argv[i]);
200         }
201 
202         if (do_fdtoverlay(input_filename, output_filename, argc, argv))
203                 return 1;
204 
205         return 0;
206 }
207 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php