Skip to content

Commit 169043d

Browse files
pantoniousjg20
authored andcommitted
fit: Introduce methods for applying overlays on fit-load
Introduce an overlay based method for constructing a base DT blob to pass to the kernel. It is based on a specific method now to get the FDT from a FIT image named boot_get_fdt_fit(). Signed-off-by: Pantelis Antoniou <[email protected]> Acked-by: Simon Glass <[email protected]>
1 parent 7c3dc77 commit 169043d

File tree

3 files changed

+205
-8
lines changed

3 files changed

+205
-8
lines changed

common/image-fdt.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -356,17 +356,16 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch,
356356
if (fit_check_format(buf)) {
357357
ulong load, len;
358358

359-
fdt_noffset = fit_image_load(images,
359+
fdt_noffset = boot_get_fdt_fit(images,
360360
fdt_addr, &fit_uname_fdt,
361361
&fit_uname_config,
362-
arch, IH_TYPE_FLATDT,
363-
BOOTSTAGE_ID_FIT_FDT_START,
364-
FIT_LOAD_OPTIONAL, &load, &len);
362+
arch, &load, &len);
365363

366364
images->fit_hdr_fdt = map_sysmem(fdt_addr, 0);
367365
images->fit_uname_fdt = fit_uname_fdt;
368366
images->fit_noffset_fdt = fdt_noffset;
369367
fdt_addr = load;
368+
370369
break;
371370
} else
372371
#endif

common/image-fit.c

+177-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <errno.h>
2020
#include <mapmem.h>
2121
#include <asm/io.h>
22+
#include <malloc.h>
2223
DECLARE_GLOBAL_DATA_PTR;
2324
#endif /* !USE_HOSTCC*/
2425

@@ -434,6 +435,10 @@ void fit_image_print(const void *fit, int image_noffset, const char *p)
434435
printf("0x%08lx\n", load);
435436
}
436437

438+
/* optional load address for FDT */
439+
if (type == IH_TYPE_FLATDT && !fit_image_get_load(fit, image_noffset, &load))
440+
printf("%s Load Address: 0x%08lx\n", p, load);
441+
437442
if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
438443
(type == IH_TYPE_RAMDISK)) {
439444
ret = fit_image_get_entry(fit, image_noffset, &entry);
@@ -1454,6 +1459,8 @@ int fit_conf_get_node(const void *fit, const char *conf_uname)
14541459
{
14551460
int noffset, confs_noffset;
14561461
int len;
1462+
const char *s;
1463+
char *conf_uname_copy = NULL;
14571464

14581465
confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
14591466
if (confs_noffset < 0) {
@@ -1475,12 +1482,29 @@ int fit_conf_get_node(const void *fit, const char *conf_uname)
14751482
debug("Found default configuration: '%s'\n", conf_uname);
14761483
}
14771484

1485+
s = strchr(conf_uname, '#');
1486+
if (s) {
1487+
len = s - conf_uname;
1488+
conf_uname_copy = malloc(len + 1);
1489+
if (!conf_uname_copy) {
1490+
debug("Can't allocate uname copy: '%s'\n",
1491+
conf_uname);
1492+
return -ENOMEM;
1493+
}
1494+
memcpy(conf_uname_copy, conf_uname, len);
1495+
conf_uname_copy[len] = '\0';
1496+
conf_uname = conf_uname_copy;
1497+
}
1498+
14781499
noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
14791500
if (noffset < 0) {
14801501
debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
14811502
conf_uname, fdt_strerror(noffset));
14821503
}
14831504

1505+
if (conf_uname_copy)
1506+
free(conf_uname_copy);
1507+
14841508
return noffset;
14851509
}
14861510

@@ -1527,7 +1551,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
15271551
char *desc;
15281552
const char *uname;
15291553
int ret;
1530-
int loadables_index;
1554+
int fdt_index, loadables_index;
15311555

15321556
/* Mandatory properties */
15331557
ret = fit_get_desc(fit, noffset, &desc);
@@ -1549,9 +1573,17 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
15491573
if (uname)
15501574
printf("%s Init Ramdisk: %s\n", p, uname);
15511575

1552-
uname = fdt_getprop(fit, noffset, FIT_FDT_PROP, NULL);
1553-
if (uname)
1554-
printf("%s FDT: %s\n", p, uname);
1576+
for (fdt_index = 0;
1577+
uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP,
1578+
fdt_index, NULL), uname;
1579+
fdt_index++) {
1580+
1581+
if (fdt_index == 0)
1582+
printf("%s FDT: ", p);
1583+
else
1584+
printf("%s ", p);
1585+
printf("%s\n", uname);
1586+
}
15551587

15561588
uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL);
15571589
if (uname)
@@ -1888,3 +1920,144 @@ int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
18881920

18891921
return ret;
18901922
}
1923+
1924+
#ifndef USE_HOSTCC
1925+
int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
1926+
const char **fit_unamep, const char **fit_uname_configp,
1927+
int arch, ulong *datap, ulong *lenp)
1928+
{
1929+
int fdt_noffset, cfg_noffset, count;
1930+
const void *fit;
1931+
const char *fit_uname = NULL;
1932+
const char *fit_uname_config = NULL;
1933+
char *fit_uname_config_copy = NULL;
1934+
char *next_config = NULL;
1935+
ulong load, len;
1936+
#ifdef CONFIG_OF_LIBFDT_OVERLAY
1937+
ulong image_start, image_end;
1938+
ulong ovload, ovlen;
1939+
const char *uconfig;
1940+
const char *uname;
1941+
void *base, *ov;
1942+
int i, err, noffset, ov_noffset;
1943+
#endif
1944+
1945+
fit_uname = fit_unamep ? *fit_unamep : NULL;
1946+
1947+
if (fit_uname_configp && *fit_uname_configp) {
1948+
fit_uname_config_copy = strdup(*fit_uname_configp);
1949+
if (!fit_uname_config_copy)
1950+
return -ENOMEM;
1951+
1952+
next_config = strchr(fit_uname_config_copy, '#');
1953+
if (next_config)
1954+
*next_config++ = '\0';
1955+
if (next_config - 1 > fit_uname_config_copy)
1956+
fit_uname_config = fit_uname_config_copy;
1957+
}
1958+
1959+
fdt_noffset = fit_image_load(images,
1960+
addr, &fit_uname, &fit_uname_config,
1961+
arch, IH_TYPE_FLATDT,
1962+
BOOTSTAGE_ID_FIT_FDT_START,
1963+
FIT_LOAD_OPTIONAL, &load, &len);
1964+
1965+
if (fdt_noffset < 0)
1966+
goto out;
1967+
1968+
debug("fit_uname=%s, fit_uname_config=%s\n",
1969+
fit_uname ? fit_uname : "<NULL>",
1970+
fit_uname_config ? fit_uname_config : "<NULL>");
1971+
1972+
fit = map_sysmem(addr, 0);
1973+
1974+
cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
1975+
1976+
/* single blob, or error just return as well */
1977+
count = fit_conf_get_prop_node_count(fit, cfg_noffset, FIT_FDT_PROP);
1978+
if (count <= 1 && !next_config)
1979+
goto out;
1980+
1981+
/* we need to apply overlays */
1982+
1983+
#ifdef CONFIG_OF_LIBFDT_OVERLAY
1984+
image_start = addr;
1985+
image_end = addr + fit_get_size(fit);
1986+
/* verify that relocation took place by load address not being in fit */
1987+
if (load >= image_start && load < image_end) {
1988+
/* check is simplified; fit load checks for overlaps */
1989+
printf("Overlayed FDT requires relocation\n");
1990+
fdt_noffset = -EBADF;
1991+
goto out;
1992+
}
1993+
1994+
base = map_sysmem(load, len);
1995+
1996+
/* apply extra configs in FIT first, followed by args */
1997+
for (i = 1; ; i++) {
1998+
if (i < count) {
1999+
noffset = fit_conf_get_prop_node_index(fit, cfg_noffset,
2000+
FIT_FDT_PROP, i);
2001+
uname = fit_get_name(fit, noffset, NULL);
2002+
uconfig = NULL;
2003+
} else {
2004+
if (!next_config)
2005+
break;
2006+
uconfig = next_config;
2007+
next_config = strchr(next_config, '#');
2008+
if (next_config)
2009+
*next_config++ = '\0';
2010+
uname = NULL;
2011+
}
2012+
2013+
debug("%d: using uname=%s uconfig=%s\n", i, uname, uconfig);
2014+
2015+
ov_noffset = fit_image_load(images,
2016+
addr, &uname, &uconfig,
2017+
arch, IH_TYPE_FLATDT,
2018+
BOOTSTAGE_ID_FIT_FDT_START,
2019+
FIT_LOAD_REQUIRED, &ovload, &ovlen);
2020+
if (ov_noffset < 0) {
2021+
printf("load of %s failed\n", uname);
2022+
continue;
2023+
}
2024+
debug("%s loaded at 0x%08lx len=0x%08lx\n",
2025+
uname, ovload, ovlen);
2026+
ov = map_sysmem(ovload, ovlen);
2027+
2028+
base = map_sysmem(load, len + ovlen);
2029+
err = fdt_open_into(base, base, len + ovlen);
2030+
if (err < 0) {
2031+
printf("failed on fdt_open_into\n");
2032+
fdt_noffset = err;
2033+
goto out;
2034+
}
2035+
/* the verbose method prints out messages on error */
2036+
err = fdt_overlay_apply_verbose(base, ov);
2037+
if (err < 0) {
2038+
fdt_noffset = err;
2039+
goto out;
2040+
}
2041+
fdt_pack(base);
2042+
len = fdt_totalsize(base);
2043+
}
2044+
#else
2045+
printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
2046+
fdt_noffset = -EBADF;
2047+
#endif
2048+
2049+
out:
2050+
if (datap)
2051+
*datap = load;
2052+
if (lenp)
2053+
*lenp = len;
2054+
if (fit_unamep)
2055+
*fit_unamep = fit_uname;
2056+
if (fit_uname_configp)
2057+
*fit_uname_configp = fit_uname_config;
2058+
2059+
if (fit_uname_config_copy)
2060+
free(fit_uname_config_copy);
2061+
return fdt_noffset;
2062+
}
2063+
#endif

include/image.h

+25
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,31 @@ int boot_get_loadable(int argc, char * const argv[], bootm_headers_t *images,
593593
int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
594594
ulong *setup_start, ulong *setup_len);
595595

596+
/**
597+
* boot_get_fdt_fit() - load a DTB from a FIT file (applying overlays)
598+
*
599+
* This deals with all aspects of loading an DTB from a FIT.
600+
* The correct base image based on configuration will be selected, and
601+
* then any overlays specified will be applied (as present in fit_uname_configp).
602+
*
603+
* @param images Boot images structure
604+
* @param addr Address of FIT in memory
605+
* @param fit_unamep On entry this is the requested image name
606+
* (e.g. "kernel@1") or NULL to use the default. On exit
607+
* points to the selected image name
608+
* @param fit_uname_configp On entry this is the requested configuration
609+
* name (e.g. "conf@1") or NULL to use the default. On
610+
* exit points to the selected configuration name.
611+
* @param arch Expected architecture (IH_ARCH_...)
612+
* @param datap Returns address of loaded image
613+
* @param lenp Returns length of loaded image
614+
*
615+
* @return node offset of base image, or -ve error code on error
616+
*/
617+
int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
618+
const char **fit_unamep, const char **fit_uname_configp,
619+
int arch, ulong *datap, ulong *lenp);
620+
596621
/**
597622
* fit_image_load() - load an image from a FIT
598623
*

0 commit comments

Comments
 (0)