Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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