* (C) Copyright 2000-2006
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0+
*/
#ifndef USE_HOSTCC
#endif
#include <u-boot/md5.h>
-#include <sha1.h>
+#include <u-boot/sha1.h>
+#include <asm/errno.h>
#include <asm/io.h>
#ifdef CONFIG_CMD_BDI
DECLARE_GLOBAL_DATA_PTR;
+#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch,
int verify);
+#endif
#else
#include "mkimage.h"
#include <u-boot/md5.h>
{ IH_ARCH_NDS32, "nds32", "NDS32", },
{ IH_ARCH_OPENRISC, "or1k", "OpenRISC 1000",},
{ IH_ARCH_SANDBOX, "sandbox", "Sandbox", },
+ { IH_ARCH_ARM64, "arm64", "AArch64", },
+ { IH_ARCH_ARC, "arc", "ARC", },
{ -1, "", "", },
};
{ IH_OS_PLAN9, "plan9", "Plan 9", },
{ IH_OS_RTEMS, "rtems", "RTEMS", },
{ IH_OS_U_BOOT, "u-boot", "U-Boot", },
+ { IH_OS_VXWORKS, "vxworks", "VxWorks", },
#if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
{ IH_OS_QNX, "qnx", "QNX", },
- { IH_OS_VXWORKS, "vxworks", "VxWorks", },
#endif
#if defined(CONFIG_INTEGRITY) || defined(USE_HOSTCC)
{ IH_OS_INTEGRITY,"integrity", "INTEGRITY", },
{ IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", },
{ IH_TYPE_FIRMWARE, "firmware", "Firmware", },
{ IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", },
+ { IH_TYPE_GPIMAGE, "gpimage", "TI Keystone SPL Image",},
{ IH_TYPE_KERNEL, "kernel", "Kernel Image", },
{ IH_TYPE_KERNEL_NOLOAD, "kernel_noload", "Kernel Image (no loading done)", },
{ IH_TYPE_KWBIMAGE, "kwbimage", "Kirkwood Boot Image",},
{ IH_TYPE_SCRIPT, "script", "Script", },
{ IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
{ IH_TYPE_UBLIMAGE, "ublimage", "Davinci UBL image",},
+ { IH_TYPE_MXSIMAGE, "mxsimage", "Freescale MXS Boot Image",},
+ { IH_TYPE_ATMELIMAGE, "atmelimage", "ATMEL ROM-Boot Image",},
{ -1, "", "", },
};
#ifndef USE_HOSTCC
+#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
/**
* image_get_ramdisk - get and verify ramdisk image
* @rd_addr: ramdisk image start address
return rd_hdr;
}
+#endif
#endif /* !USE_HOSTCC */
/*****************************************************************************/
}
#ifndef USE_HOSTCC
+/**
+ * genimg_get_kernel_addr_fit - get the real kernel address and return 2
+ * FIT strings
+ * @img_addr: a string might contain real image address
+ * @fit_uname_config: double pointer to a char, will hold pointer to a
+ * configuration unit name
+ * @fit_uname_kernel: double pointer to a char, will hold pointer to a subimage
+ * name
+ *
+ * genimg_get_kernel_addr_fit get the real kernel start address from a string
+ * which is normally the first argv of bootm/bootz
+ *
+ * returns:
+ * kernel start address
+ */
+ulong genimg_get_kernel_addr_fit(char * const img_addr,
+ const char **fit_uname_config,
+ const char **fit_uname_kernel)
+{
+ ulong kernel_addr;
+
+ /* find out kernel image address */
+ if (!img_addr) {
+ kernel_addr = load_addr;
+ debug("* kernel: default image load address = 0x%08lx\n",
+ load_addr);
+#if defined(CONFIG_FIT)
+ } else if (fit_parse_conf(img_addr, load_addr, &kernel_addr,
+ fit_uname_config)) {
+ debug("* kernel: config '%s' from image at 0x%08lx\n",
+ *fit_uname_config, kernel_addr);
+ } else if (fit_parse_subimage(img_addr, load_addr, &kernel_addr,
+ fit_uname_kernel)) {
+ debug("* kernel: subimage '%s' from image at 0x%08lx\n",
+ *fit_uname_kernel, kernel_addr);
+#endif
+ } else {
+ kernel_addr = simple_strtoul(img_addr, NULL, 16);
+ debug("* kernel: cmdline image address = 0x%08lx\n",
+ kernel_addr);
+ }
+
+ return kernel_addr;
+}
+
+/**
+ * genimg_get_kernel_addr() is the simple version of
+ * genimg_get_kernel_addr_fit(). It ignores those return FIT strings
+ */
+ulong genimg_get_kernel_addr(char * const img_addr)
+{
+ const char *fit_uname_config = NULL;
+ const char *fit_uname_kernel = NULL;
+
+ return genimg_get_kernel_addr_fit(img_addr, &fit_uname_config,
+ &fit_uname_kernel);
+}
+
/**
* genimg_get_format - get image format type
* @img_addr: image start address
*/
int genimg_get_format(const void *img_addr)
{
- ulong format = IMAGE_FORMAT_INVALID;
+#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
const image_header_t *hdr;
-#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
- char *fit_hdr;
-#endif
hdr = (const image_header_t *)img_addr;
if (image_check_magic(hdr))
- format = IMAGE_FORMAT_LEGACY;
+ return IMAGE_FORMAT_LEGACY;
+#endif
#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
- else {
- fit_hdr = (char *)img_addr;
- if (fdt_check_header(fit_hdr) == 0)
- format = IMAGE_FORMAT_FIT;
- }
+ if (fdt_check_header(img_addr) == 0)
+ return IMAGE_FORMAT_FIT;
+#endif
+#ifdef CONFIG_ANDROID_BOOT_IMAGE
+ if (android_image_check_header(img_addr) == 0)
+ return IMAGE_FORMAT_ANDROID;
#endif
- return format;
+ return IMAGE_FORMAT_INVALID;
}
/**
/* get data size */
switch (genimg_get_format(buf)) {
+#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
case IMAGE_FORMAT_LEGACY:
d_size = image_get_data_size(buf);
debug(" Legacy format image found at 0x%08lx, "
"size 0x%08lx\n",
ram_addr, d_size);
break;
+#endif
#if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT:
d_size = fit_get_size(buf) - h_size;
{
ulong rd_addr, rd_load;
ulong rd_data, rd_len;
+#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
const image_header_t *rd_hdr;
+#endif
void *buf;
#ifdef CONFIG_SUPPORT_RAW_INITRD
char *end;
#endif
#if defined(CONFIG_FIT)
- void *fit_hdr;
- const char *fit_uname_config = NULL;
+ const char *fit_uname_config = images->fit_uname_cfg;
const char *fit_uname_ramdisk = NULL;
ulong default_addr;
int rd_noffset;
- int cfg_noffset;
- const void *data;
- size_t size;
#endif
+ const char *select = NULL;
*rd_start = 0;
*rd_end = 0;
+ if (argc >= 2)
+ select = argv[1];
/*
* Look for a '-' which indicates to ignore the
* ramdisk argument
*/
- if ((argc >= 3) && (strcmp(argv[2], "-") == 0)) {
+ if (select && strcmp(select, "-") == 0) {
debug("## Skipping init Ramdisk\n");
rd_len = rd_data = 0;
- } else if (argc >= 3 || genimg_has_config(images)) {
+ } else if (select || genimg_has_config(images)) {
#if defined(CONFIG_FIT)
- if (argc >= 3) {
+ if (select) {
/*
* If the init ramdisk comes from the FIT image and
* the FIT image address is omitted in the command
else
default_addr = load_addr;
- if (fit_parse_conf(argv[2], 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);
- } else if (fit_parse_subimage(argv[2], default_addr,
+ } else if (fit_parse_subimage(select, default_addr,
&rd_addr, &fit_uname_ramdisk)) {
debug("* ramdisk: subimage '%s' from image at "
"0x%08lx\n",
} else
#endif
{
- rd_addr = simple_strtoul(argv[2], NULL, 16);
+ rd_addr = simple_strtoul(select, NULL, 16);
debug("* ramdisk: cmdline image address = "
"0x%08lx\n",
rd_addr);
#if defined(CONFIG_FIT)
} else {
/* use FIT configuration provided in first bootm
- * command argument
+ * command argument. If the property is not defined,
+ * quit silently.
*/
rd_addr = map_to_sysmem(images->fit_hdr_os);
- fit_uname_config = images->fit_uname_cfg;
- debug("* ramdisk: using config '%s' from image "
- "at 0x%08lx\n",
- fit_uname_config, rd_addr);
-
- /*
- * Check whether configuration has ramdisk defined,
- * if not, don't try to use it, quit silently.
- */
- fit_hdr = images->fit_hdr_os;
- cfg_noffset = fit_conf_get_node(fit_hdr,
- fit_uname_config);
- if (cfg_noffset < 0) {
- debug("* ramdisk: no such config\n");
- return 1;
- }
-
- rd_noffset = fit_conf_get_ramdisk_node(fit_hdr,
- cfg_noffset);
- if (rd_noffset < 0) {
- debug("* ramdisk: no ramdisk in config\n");
+ rd_noffset = fit_get_node_from_config(images,
+ FIT_RAMDISK_PROP, rd_addr);
+ if (rd_noffset == -ENOLINK)
return 0;
- }
+ else if (rd_noffset < 0)
+ return 1;
}
#endif
*/
buf = map_sysmem(rd_addr, 0);
switch (genimg_get_format(buf)) {
+#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
case IMAGE_FORMAT_LEGACY:
printf("## Loading init Ramdisk from Legacy "
"Image at %08lx ...\n", rd_addr);
rd_len = image_get_data_size(rd_hdr);
rd_load = image_get_load(rd_hdr);
break;
+#endif
#if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT:
- fit_hdr = buf;
- printf("## Loading init Ramdisk from FIT "
- "Image at %08lx ...\n", rd_addr);
-
- bootstage_mark(BOOTSTAGE_ID_FIT_RD_FORMAT);
- if (!fit_check_format(fit_hdr)) {
- puts("Bad FIT ramdisk image format!\n");
- bootstage_error(
- BOOTSTAGE_ID_FIT_RD_FORMAT);
- return 1;
- }
- bootstage_mark(BOOTSTAGE_ID_FIT_RD_FORMAT_OK);
-
- if (!fit_uname_ramdisk) {
- /*
- * no ramdisk image node unit name, try to get config
- * node first. If config unit node name is NULL
- * fit_conf_get_node() will try to find default config node
- */
- bootstage_mark(
- BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME);
- cfg_noffset = fit_conf_get_node(fit_hdr,
- fit_uname_config);
- if (cfg_noffset < 0) {
- puts("Could not find configuration "
- "node\n");
- bootstage_error(
- BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME);
- return 1;
- }
- fit_uname_config = fdt_get_name(fit_hdr,
- cfg_noffset, NULL);
- printf(" Using '%s' configuration\n",
- fit_uname_config);
-
- rd_noffset = fit_conf_get_ramdisk_node(fit_hdr,
- cfg_noffset);
- fit_uname_ramdisk = fit_get_name(fit_hdr,
- rd_noffset, NULL);
- } else {
- /* get ramdisk component image node offset */
- bootstage_mark(
- BOOTSTAGE_ID_FIT_RD_UNIT_NAME);
- rd_noffset = fit_image_get_node(fit_hdr,
- fit_uname_ramdisk);
- }
- if (rd_noffset < 0) {
- puts("Could not find subimage node\n");
- bootstage_error(BOOTSTAGE_ID_FIT_RD_SUBNODE);
- return 1;
- }
-
- printf(" Trying '%s' ramdisk subimage\n",
- fit_uname_ramdisk);
-
- bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK);
- if (!fit_check_ramdisk(fit_hdr, rd_noffset, arch,
- images->verify))
+ 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_data, &rd_len);
+ if (rd_noffset < 0)
return 1;
- /* get ramdisk image data address and length */
- if (fit_image_get_data(fit_hdr, rd_noffset, &data,
- &size)) {
- puts("Could not find ramdisk subimage data!\n");
- bootstage_error(BOOTSTAGE_ID_FIT_RD_GET_DATA);
- return 1;
- }
- bootstage_mark(BOOTSTAGE_ID_FIT_RD_GET_DATA_OK);
-
- rd_data = (ulong)data;
- rd_len = size;
-
- if (fit_image_get_load(fit_hdr, rd_noffset, &rd_load)) {
- puts("Can't get ramdisk subimage load "
- "address!\n");
- bootstage_error(BOOTSTAGE_ID_FIT_RD_LOAD);
- return 1;
- }
- bootstage_mark(BOOTSTAGE_ID_FIT_RD_LOAD);
-
- images->fit_hdr_rd = fit_hdr;
+ images->fit_hdr_rd = map_sysmem(rd_addr, 0);
images->fit_uname_rd = fit_uname_ramdisk;
images->fit_noffset_rd = rd_noffset;
break;
#endif
default:
#ifdef CONFIG_SUPPORT_RAW_INITRD
- if (argc >= 3 && (end = strchr(argv[2], ':'))) {
+ end = NULL;
+ if (select)
+ end = strchr(select, ':');
+ if (end) {
rd_len = simple_strtoul(++end, NULL, 16);
rd_data = rd_addr;
} else
(ulong)images->legacy_hdr_os);
image_multi_getimg(images->legacy_hdr_os, 1, &rd_data, &rd_len);
- } else {
+ }
+#ifdef CONFIG_ANDROID_BOOT_IMAGE
+ else if ((genimg_get_format(images) == IMAGE_FORMAT_ANDROID) &&
+ (!android_image_get_ramdisk((void *)images->os.start,
+ &rd_data, &rd_len))) {
+ /* empty */
+ }
+#endif
+ else {
/*
* no initrd image
*/
* @initrd_end: pointer to a ulong variable, will hold final init ramdisk
* end address (after possible relocation)
*
- * boot_ramdisk_high() takes a relocation hint from "initrd_high" environement
+ * boot_ramdisk_high() takes a relocation hint from "initrd_high" environment
* variable and if requested ramdisk data is moved to a specified location.
*
* Initrd_start and initrd_end are set to final (after relocation) ramdisk