#include <common.h>
#include <bootstage.h>
#include <cpu_func.h>
+#include <display_options.h>
#include <env.h>
#include <fpga.h>
#include <image.h>
#include <init.h>
+#include <log.h>
#include <mapmem.h>
#include <rtc.h>
#include <watchdog.h>
DECLARE_GLOBAL_DATA_PTR;
-#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
/**
* image_get_ramdisk - get and verify ramdisk image
* @rd_addr: ramdisk image start address
* pointer to a ramdisk image header, if image was found and valid
* otherwise, return NULL
*/
-static const image_header_t *image_get_ramdisk(ulong rd_addr, u8 arch,
- int verify)
+static const struct legacy_img_hdr *image_get_ramdisk(ulong rd_addr, u8 arch,
+ int verify)
{
- const image_header_t *rd_hdr = (const image_header_t *)rd_addr;
+ const struct legacy_img_hdr *rd_hdr = (const struct legacy_img_hdr *)rd_addr;
if (!image_check_magic(rd_hdr)) {
puts("Bad Magic Number\n");
return rd_hdr;
}
-#endif
/*****************************************************************************/
/* Shared dual-format routines */
return tmp;
}
-#if defined(CONFIG_SYS_SDRAM_BASE)
- return CONFIG_SYS_SDRAM_BASE;
+#if defined(CFG_SYS_SDRAM_BASE)
+ return CFG_SYS_SDRAM_BASE;
#elif defined(CONFIG_ARM) || defined(CONFIG_MICROBLAZE) || defined(CONFIG_RISCV)
return gd->bd->bi_dram[0].start;
#else
return tmp;
}
-#if defined(CONFIG_SYS_BOOTMAPSZ)
- return CONFIG_SYS_BOOTMAPSZ;
+#if defined(CFG_SYS_BOOTMAPSZ)
+ return CFG_SYS_BOOTMAPSZ;
#else
return env_get_bootm_size();
#endif
if (to == from)
return;
-#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
- if (to > from) {
- from += len;
- to += len;
- }
- while (len > 0) {
- size_t tail = (len > chunksz) ? chunksz : len;
-
- WATCHDOG_RESET();
+ if (IS_ENABLED(CONFIG_HW_WATCHDOG) || IS_ENABLED(CONFIG_WATCHDOG)) {
if (to > from) {
- to -= tail;
- from -= tail;
+ from += len;
+ to += len;
}
- memmove(to, from, tail);
- if (to < from) {
- to += tail;
- from += tail;
+ while (len > 0) {
+ size_t tail = (len > chunksz) ? chunksz : len;
+
+ schedule();
+ if (to > from) {
+ to -= tail;
+ from -= tail;
+ }
+ memmove(to, from, tail);
+ if (to < from) {
+ to += tail;
+ from += tail;
+ }
+ len -= tail;
}
- len -= tail;
+ } else {
+ memmove(to, from, len);
}
-#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
- memmove(to, from, len);
-#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
}
/**
int genimg_get_format(const void *img_addr)
{
if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) {
- const image_header_t *hdr;
+ const struct legacy_img_hdr *hdr;
- hdr = (const image_header_t *)img_addr;
+ hdr = (const struct legacy_img_hdr *)img_addr;
if (image_check_magic(hdr))
return IMAGE_FORMAT_LEGACY;
}
return IMAGE_FORMAT_FIT;
}
if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE) &&
- !android_image_check_header(img_addr))
+ is_android_boot_image_header(img_addr))
return IMAGE_FORMAT_ANDROID;
return IMAGE_FORMAT_INVALID;
* 0, no FIT support or no configuration found
* 1, configuration found
*/
-int genimg_has_config(bootm_headers_t *images)
+int genimg_has_config(struct bootm_headers *images)
{
if (CONFIG_IS_ENABLED(FIT) && images->fit_uname_cfg)
return 1;
* select_ramdisk() - Select and locate the ramdisk to use
*
* @images: pointer to the bootm images structure
- * @select: name of ramdisk to select, or NULL for any
+ * @select: name of ramdisk to select, or hex address, NULL for any
* @arch: expected ramdisk architecture
* @rd_datap: pointer to a ulong variable, will hold ramdisk pointer
* @rd_lenp: pointer to a ulong variable, will hold ramdisk length
* Return: 0 if OK, -ENOPKG if no ramdisk (but an error should not be reported),
* other -ve value on other error
*/
-static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch,
+static int select_ramdisk(struct bootm_headers *images, const char *select, u8 arch,
ulong *rd_datap, ulong *rd_lenp)
{
+ const char *fit_uname_config;
+ const char *fit_uname_ramdisk;
+ bool done_select = !select;
+ bool done = false;
+ int rd_noffset;
ulong rd_addr;
char *buf;
-#if CONFIG_IS_ENABLED(FIT)
- const char *fit_uname_config = images->fit_uname_cfg;
- const char *fit_uname_ramdisk = NULL;
- int rd_noffset;
+ if (CONFIG_IS_ENABLED(FIT)) {
+ fit_uname_config = images->fit_uname_cfg;
+ fit_uname_ramdisk = NULL;
if (select) {
ulong default_addr;
else
default_addr = image_load_addr;
- if (fit_parse_conf(select, default_addr,
- &rd_addr, &fit_uname_config)) {
+ if (fit_parse_conf(select, default_addr, &rd_addr,
+ &fit_uname_config)) {
debug("* ramdisk: config '%s' from image at 0x%08lx\n",
fit_uname_config, rd_addr);
+ done_select = true;
} else if (fit_parse_subimage(select, default_addr,
&rd_addr,
&fit_uname_ramdisk)) {
debug("* ramdisk: subimage '%s' from image at 0x%08lx\n",
fit_uname_ramdisk, rd_addr);
- } else
-#endif
- {
- rd_addr = hextoul(select, NULL);
- debug("* ramdisk: cmdline image address = 0x%08lx\n",
- rd_addr);
+ done_select = true;
}
-#if CONFIG_IS_ENABLED(FIT)
- } else {
- /* use FIT configuration provided in first bootm
- * command argument. If the property is not defined,
- * quit silently (with -ENOPKG)
- */
- rd_addr = map_to_sysmem(images->fit_hdr_os);
- rd_noffset = fit_get_node_from_config(images,
- FIT_RAMDISK_PROP,
- rd_addr);
- if (rd_noffset == -ENOENT)
- return -ENOPKG;
- else if (rd_noffset < 0)
- return rd_noffset;
}
-#endif
-
- /*
- * Check if there is an initrd image at the
- * address provided in the second bootm argument
- * check image type, for FIT images get FIT node.
+ }
+ if (!done_select) {
+ rd_addr = hextoul(select, NULL);
+ debug("* ramdisk: cmdline image address = 0x%08lx\n", rd_addr);
+ }
+ if (CONFIG_IS_ENABLED(FIT) && !select) {
+ /* use FIT configuration provided in first bootm
+ * command argument. If the property is not defined,
+ * quit silently (with -ENOPKG)
*/
- buf = map_sysmem(rd_addr, 0);
- switch (genimg_get_format(buf)) {
-#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)
- case IMAGE_FORMAT_LEGACY: {
- const image_header_t *rd_hdr;
+ rd_addr = map_to_sysmem(images->fit_hdr_os);
+ rd_noffset = fit_get_node_from_config(images, FIT_RAMDISK_PROP,
+ rd_addr);
+ if (rd_noffset == -ENOENT)
+ return -ENOPKG;
+ else if (rd_noffset < 0)
+ return rd_noffset;
+ }
+
+ /*
+ * Check if there is an initrd image at the
+ * address provided in the second bootm argument
+ * check image type, for FIT images get FIT node.
+ */
+ buf = map_sysmem(rd_addr, 0);
+ switch (genimg_get_format(buf)) {
+ case IMAGE_FORMAT_LEGACY:
+ if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) {
+ const struct legacy_img_hdr *rd_hdr;
printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n",
rd_addr);
*rd_datap = image_get_data(rd_hdr);
*rd_lenp = image_get_data_size(rd_hdr);
- break;
+ done = true;
}
-#endif
-#if CONFIG_IS_ENABLED(FIT)
- case IMAGE_FORMAT_FIT:
- rd_noffset = fit_image_load(images,
- rd_addr, &fit_uname_ramdisk,
- &fit_uname_config, arch,
- IH_TYPE_RAMDISK,
+ break;
+ case IMAGE_FORMAT_FIT:
+ if (CONFIG_IS_ENABLED(FIT)) {
+ rd_noffset = fit_image_load(images, rd_addr,
+ &fit_uname_ramdisk,
+ &fit_uname_config,
+ arch, IH_TYPE_RAMDISK,
BOOTSTAGE_ID_FIT_RD_START,
FIT_LOAD_OPTIONAL_NON_ZERO,
rd_datap, rd_lenp);
images->fit_hdr_rd = map_sysmem(rd_addr, 0);
images->fit_uname_rd = fit_uname_ramdisk;
images->fit_noffset_rd = rd_noffset;
- break;
-#endif
-#ifdef CONFIG_ANDROID_BOOT_IMAGE
- case IMAGE_FORMAT_ANDROID:
- android_image_get_ramdisk((void *)images->os.start,
- rd_datap, rd_lenp);
- break;
-#endif
- default:
- if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) {
- char *end = NULL;
-
- if (select)
- end = strchr(select, ':');
- if (end) {
- *rd_lenp = hextoul(++end, NULL);
- *rd_datap = rd_addr;
- break;
- }
+ done = true;
+ }
+ break;
+ case IMAGE_FORMAT_ANDROID:
+ if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) {
+ int ret;
+ if (IS_ENABLED(CONFIG_CMD_ABOOTIMG)) {
+ void *boot_img = map_sysmem(get_abootimg_addr(), 0);
+ void *vendor_boot_img = map_sysmem(get_avendor_bootimg_addr(), 0);
+
+ ret = android_image_get_ramdisk(boot_img, vendor_boot_img,
+ rd_datap, rd_lenp);
+ unmap_sysmem(vendor_boot_img);
+ unmap_sysmem(boot_img);
+ } else {
+ void *ptr = map_sysmem(images->os.start, 0);
+
+ ret = android_image_get_ramdisk(ptr, NULL, rd_datap, rd_lenp);
+ unmap_sysmem(ptr);
}
+
+ if (ret)
+ return ret;
+ done = true;
+ }
+ break;
+ }
+
+ if (!done) {
+ if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) {
+ char *end = NULL;
+
+ if (select)
+ end = strchr(select, ':');
+ if (end) {
+ *rd_lenp = hextoul(++end, NULL);
+ *rd_datap = rd_addr;
+ done = true;
+ }
+ }
+
+ if (!done) {
puts("Wrong Ramdisk Image Format\n");
return -EINVAL;
}
+ }
return 0;
}
* 1, if ramdisk image is found but corrupted, or invalid
* rd_start and rd_end are set to 0 if no ramdisk exists
*/
-int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images,
+int boot_get_ramdisk(int argc, char *const argv[], struct bootm_headers *images,
u8 arch, ulong *rd_start, ulong *rd_end)
{
ulong rd_data, rd_len;
return 0;
}
-#if defined(CONFIG_LMB)
/**
* boot_ramdisk_high - relocate init ramdisk
* @lmb: pointer to lmb handle, will be used for memory mgmt
error:
return -1;
}
-#endif
-int boot_get_setup(bootm_headers_t *images, u8 arch,
+int boot_get_setup(struct bootm_headers *images, u8 arch,
ulong *setup_start, ulong *setup_len)
{
if (!CONFIG_IS_ENABLED(FIT))
return boot_get_setup_fit(images, arch, setup_start, setup_len);
}
-int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images,
+int boot_get_fpga(int argc, char *const argv[], struct bootm_headers *images,
u8 arch, const ulong *ld_start, ulong * const ld_len)
{
ulong tmp_img_addr, img_data, img_len;
img_len, BIT_FULL);
if (err)
err = fpga_load(devnum, (const void *)img_data,
- img_len, BIT_FULL);
+ img_len, BIT_FULL, 0);
} else {
name = "partial";
err = fpga_loadbitstream(devnum, (char *)img_data,
img_len, BIT_PARTIAL);
if (err)
err = fpga_load(devnum, (const void *)img_data,
- img_len, BIT_PARTIAL);
+ img_len, BIT_PARTIAL, 0);
}
if (err)
fit_loadable_handler->handler(img_data, img_len);
}
-int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images,
+int boot_get_loadable(int argc, char *const argv[], struct bootm_headers *images,
u8 arch, const ulong *ld_start, ulong * const ld_len)
{
/*
return 0;
}
-#if defined(CONFIG_LMB)
-#ifdef CONFIG_SYS_BOOT_GET_CMDLINE
/**
* boot_get_cmdline - allocate and initialize kernel cmdline
* @lmb: pointer to lmb handle, will be used for memory mgmt
* @cmd_start: pointer to a ulong variable, will hold cmdline start
* @cmd_end: pointer to a ulong variable, will hold cmdline end
*
- * boot_get_cmdline() allocates space for kernel command line below
+ * This allocates space for kernel command line below
* BOOTMAPSZ + env_get_bootm_low() address. If "bootargs" U-Boot environment
* variable is present its contents is copied to allocated kernel
* command line.
*/
int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end)
{
+ int barg;
char *cmdline;
char *s;
- cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf,
+ /*
+ * Help the compiler detect that this function is only called when
+ * CONFIG_SYS_BOOT_GET_CMDLINE is enabled
+ */
+ if (!IS_ENABLED(CONFIG_SYS_BOOT_GET_CMDLINE))
+ return 0;
+
+ barg = IF_ENABLED_INT(CONFIG_SYS_BOOT_GET_CMDLINE, CONFIG_SYS_BARGSIZE);
+ cmdline = (char *)(ulong)lmb_alloc_base(lmb, barg, 0xf,
env_get_bootm_mapsize() + env_get_bootm_low());
if (!cmdline)
return -1;
debug("## kernel board info at 0x%08lx\n", (ulong)*kbd);
-#if defined(DEBUG)
- if (IS_ENABLED(CONFIG_CMD_BDI))
+ if (_DEBUG && IS_ENABLED(CONFIG_CMD_BDI))
do_bdinfo(NULL, 0, 0, NULL);
-#endif
return 0;
}
-#endif
-int image_setup_linux(bootm_headers_t *images)
+int image_setup_linux(struct bootm_headers *images)
{
ulong of_size = images->ft_len;
char **of_flat_tree = &images->ft_addr;
- struct lmb *lmb = &images->lmb;
+ struct lmb *lmb = images_lmb(images);
int ret;
+ /* This function cannot be called without lmb support */
+ if (!IS_ENABLED(CONFIG_LMB))
+ return -EFAULT;
if (CONFIG_IS_ENABLED(OF_LIBFDT))
boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
return 0;
}
-#endif
void genimg_print_size(uint32_t size)
{
tm.tm_year, tm.tm_mon, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
}
+
+/**
+ * get_default_image() - Return default property from /images
+ *
+ * Return: Pointer to value of default property (or NULL)
+ */
+static const char *get_default_image(const void *fit)
+{
+ int images_noffset;
+
+ images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
+ if (images_noffset < 0)
+ return NULL;
+
+ return fdt_getprop(fit, images_noffset, FIT_DEFAULT_PROP, NULL);
+}
+
+int image_locate_script(void *buf, int size, const char *fit_uname,
+ const char *confname, char **datap, uint *lenp)
+{
+ const struct legacy_img_hdr *hdr;
+ const void *fit_data;
+ const void *fit_hdr;
+ size_t fit_len;
+ int noffset;
+ int verify;
+ ulong len;
+ u32 *data;
+
+ verify = env_get_yesno("verify");
+
+ switch (genimg_get_format(buf)) {
+ case IMAGE_FORMAT_LEGACY:
+ if (!IS_ENABLED(CONFIG_LEGACY_IMAGE_FORMAT)) {
+ goto exit_image_format;
+ } else {
+ hdr = buf;
+
+ if (!image_check_magic(hdr)) {
+ puts("Bad magic number\n");
+ return 1;
+ }
+
+ if (!image_check_hcrc(hdr)) {
+ puts("Bad header crc\n");
+ return 1;
+ }
+
+ if (verify) {
+ if (!image_check_dcrc(hdr)) {
+ puts("Bad data crc\n");
+ return 1;
+ }
+ }
+
+ if (!image_check_type(hdr, IH_TYPE_SCRIPT)) {
+ puts("Bad image type\n");
+ return 1;
+ }
+
+ /* get length of script */
+ data = (u32 *)image_get_data(hdr);
+
+ len = uimage_to_cpu(*data);
+ if (!len) {
+ puts("Empty Script\n");
+ return 1;
+ }
+
+ /*
+ * scripts are just multi-image files with one
+ * component, so seek past the zero-terminated sequence
+ * of image lengths to get to the actual image data
+ */
+ while (*data++);
+ }
+ break;
+ case IMAGE_FORMAT_FIT:
+ if (!IS_ENABLED(CONFIG_FIT)) {
+ goto exit_image_format;
+ } else {
+ fit_hdr = buf;
+ if (fit_check_format(fit_hdr, IMAGE_SIZE_INVAL)) {
+ puts("Bad FIT image format\n");
+ return 1;
+ }
+
+ if (!fit_uname) {
+ /* If confname is empty, use the default */
+ if (confname && *confname)
+ noffset = fit_conf_get_node(fit_hdr, confname);
+ else
+ noffset = fit_conf_get_node(fit_hdr, NULL);
+ if (noffset < 0) {
+ if (!confname)
+ goto fallback;
+ printf("Could not find config %s\n", confname);
+ return 1;
+ }
+
+ if (verify && fit_config_verify(fit_hdr, noffset))
+ return 1;
+
+ noffset = fit_conf_get_prop_node(fit_hdr,
+ noffset,
+ FIT_SCRIPT_PROP,
+ IH_PHASE_NONE);
+ if (noffset < 0) {
+ if (!confname)
+ goto fallback;
+ printf("Could not find script in %s\n", confname);
+ return 1;
+ }
+ } else {
+fallback:
+ if (!fit_uname || !*fit_uname)
+ fit_uname = get_default_image(fit_hdr);
+ if (!fit_uname) {
+ puts("No FIT subimage unit name\n");
+ return 1;
+ }
+
+ /* get script component image node offset */
+ noffset = fit_image_get_node(fit_hdr, fit_uname);
+ if (noffset < 0) {
+ printf("Can't find '%s' FIT subimage\n",
+ fit_uname);
+ return 1;
+ }
+ }
+
+ if (!fit_image_check_type(fit_hdr, noffset,
+ IH_TYPE_SCRIPT)) {
+ puts("Not a image image\n");
+ return 1;
+ }
+
+ /* verify integrity */
+ if (verify && !fit_image_verify(fit_hdr, noffset)) {
+ puts("Bad Data Hash\n");
+ return 1;
+ }
+
+ /* get script subimage data address and length */
+ if (fit_image_get_data(fit_hdr, noffset, &fit_data, &fit_len)) {
+ puts("Could not find script subimage data\n");
+ return 1;
+ }
+
+ data = (u32 *)fit_data;
+ len = (ulong)fit_len;
+ }
+ break;
+ default:
+ goto exit_image_format;
+ }
+
+ *datap = (char *)data;
+ *lenp = len;
+
+ return 0;
+
+exit_image_format:
+ puts("Wrong image format for \"source\" command\n");
+ return -EPERM;
+}