MFC r262340, r262345, r262347, find and load an appropriate dtb file.
The search order for a usable dtb in fdt_setup_fdtp() is now - A dtb loaded with an explicit "load -t dtb" command. - A dtb already loaded into memory somehow[*] and pointed to by fdt_to_load. - A dtb in the memory pointed to by the u-boot env vars fdtaddr or fdt_addr. - A file named by the u-boot env vars fdtfile or fdt_file. - A static dtb compiled into the kernel. * Presumably by some arch-specific command or code.
This commit is contained in:
parent
4793c2eddb
commit
56bd016e78
@ -233,6 +233,7 @@ int mod_loadkld(const char *name, int argc, char *argv[]);
|
||||
struct preloaded_file *file_alloc(void);
|
||||
struct preloaded_file *file_findfile(char *name, char *type);
|
||||
struct file_metadata *file_findmetadata(struct preloaded_file *fp, int type);
|
||||
struct preloaded_file *file_loadraw(char *name, char *type);
|
||||
void file_discard(struct preloaded_file *fp);
|
||||
void file_addmetadata(struct preloaded_file *fp, int type, size_t size, void *p);
|
||||
int file_addmodule(struct preloaded_file *fp, char *modname, int version,
|
||||
|
@ -52,7 +52,6 @@ struct moduledir {
|
||||
};
|
||||
|
||||
static int file_load(char *filename, vm_offset_t dest, struct preloaded_file **result);
|
||||
static int file_loadraw(char *type, char *name);
|
||||
static int file_load_dependencies(struct preloaded_file *base_mod);
|
||||
static char * file_search(const char *name, char **extlist);
|
||||
static struct kernel_module * file_findmodule(struct preloaded_file *fp, char *modname, struct mod_depend *verinfo);
|
||||
@ -134,7 +133,7 @@ command_load(int argc, char *argv[])
|
||||
command_errmsg = "invalid load type";
|
||||
return(CMD_ERROR);
|
||||
}
|
||||
return(file_loadraw(typestr, argv[1]));
|
||||
return(file_loadraw(argv[1], typestr) ? CMD_OK : CMD_ERROR);
|
||||
}
|
||||
/*
|
||||
* Do we have explicit KLD load ?
|
||||
@ -189,7 +188,7 @@ command_load_geli(int argc, char *argv[])
|
||||
argv += (optind - 1);
|
||||
argc -= (optind - 1);
|
||||
sprintf(typestr, "%s:geli_keyfile%d", argv[1], num);
|
||||
return(file_loadraw(typestr, argv[2]));
|
||||
return(file_loadraw(argv[2], typestr) ? CMD_OK : CMD_ERROR);
|
||||
}
|
||||
|
||||
COMMAND_SET(unload, "unload", "unload all modules", command_unload);
|
||||
@ -357,8 +356,8 @@ file_load_dependencies(struct preloaded_file *base_file)
|
||||
* We've been asked to load (name) as (type), so just suck it in,
|
||||
* no arguments or anything.
|
||||
*/
|
||||
int
|
||||
file_loadraw(char *type, char *name)
|
||||
struct preloaded_file *
|
||||
file_loadraw(char *name, char *type)
|
||||
{
|
||||
struct preloaded_file *fp;
|
||||
char *cp;
|
||||
@ -368,21 +367,21 @@ file_loadraw(char *type, char *name)
|
||||
/* We can't load first */
|
||||
if ((file_findfile(NULL, NULL)) == NULL) {
|
||||
command_errmsg = "can't load file before kernel";
|
||||
return(CMD_ERROR);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* locate the file on the load path */
|
||||
cp = file_search(name, NULL);
|
||||
if (cp == NULL) {
|
||||
sprintf(command_errbuf, "can't find '%s'", name);
|
||||
return(CMD_ERROR);
|
||||
return(NULL);
|
||||
}
|
||||
name = cp;
|
||||
|
||||
if ((fd = open(name, O_RDONLY)) < 0) {
|
||||
sprintf(command_errbuf, "can't open '%s': %s", name, strerror(errno));
|
||||
free(name);
|
||||
return(CMD_ERROR);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (archsw.arch_loadaddr != NULL)
|
||||
@ -398,7 +397,7 @@ file_loadraw(char *type, char *name)
|
||||
sprintf(command_errbuf, "error reading '%s': %s", name, strerror(errno));
|
||||
free(name);
|
||||
close(fd);
|
||||
return(CMD_ERROR);
|
||||
return(NULL);
|
||||
}
|
||||
laddr += got;
|
||||
}
|
||||
@ -419,7 +418,7 @@ file_loadraw(char *type, char *name)
|
||||
/* Add to the list of loaded files */
|
||||
file_insert_tail(fp);
|
||||
close(fd);
|
||||
return(CMD_OK);
|
||||
return(fp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -128,6 +128,8 @@ fdt_find_static_dtb()
|
||||
char *strp;
|
||||
int i, sym_count;
|
||||
|
||||
debugf("fdt_find_static_dtb()\n");
|
||||
|
||||
sym_count = symtab = strtab = 0;
|
||||
strp = NULL;
|
||||
|
||||
@ -189,6 +191,8 @@ fdt_load_dtb(vm_offset_t va)
|
||||
struct fdt_header header;
|
||||
int err;
|
||||
|
||||
debugf("fdt_load_dtb(0x%08jx)\n", (uintmax_t)va);
|
||||
|
||||
COPYOUT(va, &header, sizeof(header));
|
||||
err = fdt_check_header(&header);
|
||||
if (err < 0) {
|
||||
@ -229,6 +233,8 @@ fdt_load_dtb_addr(struct fdt_header *header)
|
||||
{
|
||||
int err;
|
||||
|
||||
debugf("fdt_load_dtb_addr(0x%p)\n", header);
|
||||
|
||||
fdtp_size = fdt_totalsize(header);
|
||||
err = fdt_check_header(header);
|
||||
if (err < 0) {
|
||||
@ -247,6 +253,32 @@ fdt_load_dtb_addr(struct fdt_header *header)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
fdt_load_dtb_file(const char * filename)
|
||||
{
|
||||
struct preloaded_file *bfp, *oldbfp;
|
||||
int err;
|
||||
|
||||
debugf("fdt_load_dtb_file(%s)\n", filename);
|
||||
|
||||
oldbfp = file_findfile(NULL, "dtb");
|
||||
|
||||
/* Attempt to load and validate a new dtb from a file. */
|
||||
if ((bfp = file_loadraw(filename, "dtb")) == NULL) {
|
||||
sprintf(command_errbuf, "failed to load file '%s'", filename);
|
||||
return (1);
|
||||
}
|
||||
if ((err = fdt_load_dtb(bfp->f_addr)) != 0) {
|
||||
file_discard(bfp);
|
||||
return (err);
|
||||
}
|
||||
|
||||
/* A new dtb was validated, discard any previous file. */
|
||||
if (oldbfp)
|
||||
file_discard(oldbfp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
fdt_setup_fdtp()
|
||||
{
|
||||
@ -256,35 +288,68 @@ fdt_setup_fdtp()
|
||||
char *p;
|
||||
vm_offset_t va;
|
||||
|
||||
debugf("fdt_setup_fdtp()\n");
|
||||
|
||||
/* If we already loaded a file, use it. */
|
||||
if ((bfp = file_findfile(NULL, "dtb")) != NULL) {
|
||||
printf("Using DTB from loaded file.\n");
|
||||
return fdt_load_dtb(bfp->f_addr);
|
||||
}
|
||||
|
||||
if (fdt_to_load != NULL) {
|
||||
printf("Using DTB from memory address 0x%08X.\n",
|
||||
(unsigned int)fdt_to_load);
|
||||
return fdt_load_dtb_addr(fdt_to_load);
|
||||
if (fdt_load_dtb(bfp->f_addr) == 0) {
|
||||
printf("Using DTB from loaded file '%s'.\n",
|
||||
bfp->f_name);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Board vendors use both fdtaddr and fdt_addr names. Grrrr. */
|
||||
/* If we were given the address of a valid blob in memory, use it. */
|
||||
if (fdt_to_load != NULL) {
|
||||
if (fdt_load_dtb_addr(fdt_to_load) == 0) {
|
||||
printf("Using DTB from memory address 0x%08X.\n",
|
||||
(unsigned int)fdt_to_load);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the U-boot environment contains a variable giving the address of a
|
||||
* valid blob in memory, use it. Board vendors use both fdtaddr and
|
||||
* fdt_addr names.
|
||||
*/
|
||||
s = ub_env_get("fdtaddr");
|
||||
if (s == NULL)
|
||||
s = ub_env_get("fdt_addr");
|
||||
if (s != NULL && *s != '\0') {
|
||||
hdr = (struct fdt_header *)strtoul(s, &p, 16);
|
||||
if (*p == '\0') {
|
||||
printf("Using DTB provided by U-Boot.\n");
|
||||
return fdt_load_dtb_addr(hdr);
|
||||
if (fdt_load_dtb_addr(hdr) == 0) {
|
||||
printf("Using DTB provided by U-Boot at "
|
||||
"address 0x%p.\n", hdr);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the U-boot environment contains a variable giving the name of a
|
||||
* file, use it if we can load and validate it.
|
||||
*/
|
||||
s = ub_env_get("fdtfile");
|
||||
if (s == NULL)
|
||||
s = ub_env_get("fdt_file");
|
||||
if (s != NULL && *s != '\0') {
|
||||
if (fdt_load_dtb_file(s) == 0) {
|
||||
printf("Loaded DTB from file '%s'.\n", s);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is a dtb compiled into the kernel, use it. */
|
||||
if ((va = fdt_find_static_dtb()) != 0) {
|
||||
if (fdt_load_dtb(va) == 0) {
|
||||
printf("Using DTB compiled into kernel.\n");
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
if ((va = fdt_find_static_dtb()) != 0) {
|
||||
printf("Using DTB compiled into kernel.\n");
|
||||
return (fdt_load_dtb(va));
|
||||
}
|
||||
|
||||
command_errmsg = "no device tree blob found!";
|
||||
command_errmsg = "No device tree blob found!\n";
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -678,6 +743,8 @@ fdt_fixup(void)
|
||||
ethstr = NULL;
|
||||
len = 0;
|
||||
|
||||
debugf("fdt_fixup()\n");
|
||||
|
||||
if (fdtp == NULL && fdt_setup_fdtp() != 0)
|
||||
return (0);
|
||||
|
||||
@ -741,7 +808,7 @@ int
|
||||
fdt_copy(vm_offset_t va)
|
||||
{
|
||||
int err;
|
||||
|
||||
debugf("fdt_copy va 0x%08x\n", va);
|
||||
if (fdtp == NULL) {
|
||||
err = fdt_setup_fdtp();
|
||||
if (err) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user