stand/fdt: Fallback to name + ".dtbo" if we fail to load name

This behavior also matches a Linux-ism by allowing fdt_overlays to specify
names of overlays without an extension, e.g. fdt-overlays="sunxi-h3-h5-emac"

If we fail to load the file given by a name in fdt_overlays, try again with
".dtbo" appended to it. This still allows overlays to lack .dtbo extension
if user prefers it and just adds a fallback cushion.

Future work could move this from a hard-coded ".dtbo" to a loader.conf(5)
configuration option.

Reviewed by:	gonzo
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D13968
This commit is contained in:
Kyle Evans 2018-01-23 18:03:13 +00:00
parent f9a20b8fc1
commit 13811ec82e

View File

@ -73,6 +73,7 @@ static size_t fdtp_size = 0;
static vm_offset_t fdtp_va = 0; static vm_offset_t fdtp_va = 0;
static int fdt_load_dtb(vm_offset_t va); static int fdt_load_dtb(vm_offset_t va);
static void fdt_print_overlay_load_error(int err, const char *filename);
static int fdt_cmd_nyi(int argc, char *argv[]); static int fdt_cmd_nyi(int argc, char *argv[]);
@ -286,36 +287,57 @@ fdt_load_dtb_overlay(const char * filename)
debugf("fdt_load_dtb_overlay(%s)\n", filename); debugf("fdt_load_dtb_overlay(%s)\n", filename);
/* Attempt to load and validate a new dtb from a file. */ /* Attempt to load and validate a new dtb from a file. FDT_ERR_NOTFOUND
if ((bfp = file_loadraw(filename, "dtbo", 1)) == NULL) { * is normally a libfdt error code, but libfdt would actually return
printf("failed to load file '%s'\n", filename); * -FDT_ERR_NOTFOUND. We re-purpose the error code here to convey a
return (1); * similar meaning: the file itself was not found, which can still be
} * considered an error dealing with FDT pieces.
*/
if ((bfp = file_loadraw(filename, "dtbo", 1)) == NULL)
return (FDT_ERR_NOTFOUND);
COPYOUT(bfp->f_addr, &header, sizeof(header)); COPYOUT(bfp->f_addr, &header, sizeof(header));
err = fdt_check_header(&header); err = fdt_check_header(&header);
if (err < 0) { if (err < 0) {
file_discard(bfp); file_discard(bfp);
if (err == -FDT_ERR_BADVERSION) return (err);
printf("incompatible blob version: %d, should be: %d\n",
fdt_version(fdtp), FDT_LAST_SUPPORTED_VERSION);
else
printf("error validating blob: %s\n",
fdt_strerror(err));
return (1);
} }
return (0); return (0);
} }
static void
fdt_print_overlay_load_error(int err, const char *filename)
{
switch (err) {
case FDT_ERR_NOTFOUND:
printf("%s: failed to load file\n", filename);
break;
case -FDT_ERR_BADVERSION:
printf("%s: incompatible blob version: %d, should be: %d\n",
filename, fdt_version(fdtp),
FDT_LAST_SUPPORTED_VERSION);
break;
default:
/* libfdt errs are negative */
if (err < 0)
printf("%s: error validating blob: %s\n",
filename, fdt_strerror(err));
else
printf("%s: unknown load error\n", filename);
break;
}
}
int int
fdt_load_dtb_overlays(const char * filenames) fdt_load_dtb_overlays(const char * filenames)
{ {
char *names; char *names;
char *name; char *name, *name_ext;
char *comaptr; char *comaptr;
int err, namesz;
debugf("fdt_load_dtb_overlay(%s)\n", filenames); debugf("fdt_load_dtb_overlay(%s)\n", filenames);
@ -327,7 +349,23 @@ fdt_load_dtb_overlays(const char * filenames)
comaptr = strchr(name, ','); comaptr = strchr(name, ',');
if (comaptr) if (comaptr)
*comaptr = '\0'; *comaptr = '\0';
fdt_load_dtb_overlay(name); err = fdt_load_dtb_overlay(name);
if (err == FDT_ERR_NOTFOUND) {
/* Allocate enough to append ".dtbo" */
namesz = strlen(name) + 6;
name_ext = malloc(namesz);
if (name_ext == NULL) {
fdt_print_overlay_load_error(err, name);
name = comaptr + 1;
continue;
}
snprintf(name_ext, namesz, "%s.dtbo", name);
err = fdt_load_dtb_overlay(name_ext);
free(name_ext);
}
/* Catch error with either initial load or fallback load */
if (err != 0)
fdt_print_overlay_load_error(err, name);
name = comaptr + 1; name = comaptr + 1;
} while(comaptr); } while(comaptr);