#include <image.h>
-#if defined(CONFIG_FIT)
+#if defined(CONFIG_FIT) || defined (CONFIG_OF_LIBFDT)
#include <fdt.h>
#include <libfdt.h>
#include <fdt_support.h>
+#endif
+
+#if defined(CONFIG_FIT)
#include <sha1.h>
+
+static int fit_check_ramdisk (const void *fit, int os_noffset,
+ uint8_t arch, int verify);
#endif
#ifdef CONFIG_CMD_BDI
DECLARE_GLOBAL_DATA_PTR;
-static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag,
- int argc, char *argv[],
- ulong rd_addr, uint8_t arch, int verify);
+static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
+ int verify);
#else
#include "mkimage.h"
#include <time.h>
#ifndef USE_HOSTCC
/**
* image_get_ramdisk - get and verify ramdisk image
- * @cmdtp: command table pointer
- * @flag: command flag
- * @argc: command argument count
- * @argv: command argument list
* @rd_addr: ramdisk image start address
* @arch: expected ramdisk architecture
* @verify: checksum verification flag
* pointer to a ramdisk image header, if image was found and valid
* otherwise, return NULL
*/
-static image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag,
- int argc, char *argv[],
- ulong rd_addr, uint8_t arch, int verify)
+static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
+ int verify)
{
- image_header_t *rd_hdr;
-
- show_boot_progress (9);
- rd_hdr = (image_header_t *)rd_addr;
+ image_header_t *rd_hdr = (image_header_t *)rd_addr;
if (!image_check_magic (rd_hdr)) {
puts ("Bad Magic Number\n");
return tmp;
}
-#ifdef CFG_SDRAM_BASE
+#if defined(CFG_SDRAM_BASE)
return CFG_SDRAM_BASE;
+#elif defined(CONFIG_ARM)
+ return gd->bd->bi_dram[0].start;
#else
return 0;
#endif
return tmp;
}
+#if defined(CONFIG_ARM)
+ return gd->bd->bi_dram[0].size;
+#else
return gd->bd->bi_memsize;
+#endif
}
void memmove_wd (void *to, void *from, size_t len, ulong chunksz)
return ram_addr;
}
+/**
+ * fit_has_config - check if there is a valid FIT configuration
+ * @images: pointer to the bootm command headers structure
+ *
+ * fit_has_config() checks if there is a FIT configuration in use
+ * (if FTI support is present).
+ *
+ * returns:
+ * 0, no FIT support or no configuration found
+ * 1, configuration found
+ */
+int genimg_has_config (bootm_headers_t *images)
+{
+#if defined(CONFIG_FIT)
+ if (images->fit_uname_cfg)
+ return 1;
+#endif
+ return 0;
+}
+
/**
* boot_get_ramdisk - main ramdisk handling routine
- * @cmdtp: command table pointer
- * @flag: command flag
* @argc: command argument count
* @argv: command argument list
* @images: pointer to the bootm images structure
* - commandline provided address of decicated ramdisk image.
*
* returns:
+ * 0, if ramdisk image was found and valid, or skiped
* rd_start and rd_end are set to ramdisk start/end addresses if
* ramdisk image is found and valid
+ *
+ * 1, if ramdisk image is found but corrupted
* rd_start and rd_end are set to 0 if no ramdisk exists
- * return 1 if ramdisk image is found but corrupted
*/
-int boot_get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
- bootm_headers_t *images, uint8_t arch,
- ulong *rd_start, ulong *rd_end)
+int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
+ uint8_t arch, ulong *rd_start, ulong *rd_end)
{
ulong rd_addr, rd_load;
ulong rd_data, rd_len;
const char *fit_uname_config = NULL;
const char *fit_uname_ramdisk = NULL;
ulong default_addr;
+ int rd_noffset;
+ int cfg_noffset;
+ const void *data;
+ size_t size;
#endif
+ *rd_start = 0;
+ *rd_end = 0;
+
/*
* Look for a '-' which indicates to ignore the
* ramdisk argument
if ((argc >= 3) && (strcmp(argv[2], "-") == 0)) {
debug ("## Skipping init Ramdisk\n");
rd_len = rd_data = 0;
- } else if (argc >= 3) {
+ } else if (argc >= 3 || genimg_has_config (images)) {
#if defined(CONFIG_FIT)
- /*
- * If the init ramdisk comes from the FIT image and the FIT image
- * address is omitted in the command line argument, try to use
- * os FIT image address or default load address.
- */
- if (images->fit_uname_os)
- default_addr = (ulong)images->fit_hdr_os;
- else
- default_addr = load_addr;
-
- if (fit_parse_conf (argv[2], 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,
- &rd_addr, &fit_uname_ramdisk)) {
- debug ("* ramdisk: subimage '%s' from image at 0x%08lx\n",
- fit_uname_ramdisk, rd_addr);
- } else
+ if (argc >= 3) {
+ /*
+ * If the init ramdisk comes from the FIT image and
+ * the FIT image address is omitted in the command
+ * line argument, try to use os FIT image address or
+ * default load address.
+ */
+ if (images->fit_uname_os)
+ default_addr = (ulong)images->fit_hdr_os;
+ else
+ default_addr = load_addr;
+
+ if (fit_parse_conf (argv[2], 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,
+ &rd_addr, &fit_uname_ramdisk)) {
+ debug ("* ramdisk: subimage '%s' from image at 0x%08lx\n",
+ fit_uname_ramdisk, rd_addr);
+ } else
#endif
- {
- rd_addr = simple_strtoul(argv[2], NULL, 16);
- debug ("* ramdisk: cmdline image address = 0x%08lx\n",
- rd_addr);
+ {
+ rd_addr = simple_strtoul(argv[2], 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
+ */
+ rd_addr = (ulong)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 = (void *)rd_addr;
+ cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
+ if (cfg_noffset < 0) {
+ debug ("* ramdisk: no such config\n");
+ return 0;
+ }
+
+ rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);
+ if (rd_noffset < 0) {
+ debug ("* ramdisk: no ramdisk in config\n");
+ return 0;
+ }
}
+#endif
/* copy from dataflash if needed */
- printf ("## Loading init Ramdisk Image at %08lx ...\n",
- rd_addr);
rd_addr = genimg_get_image (rd_addr);
/*
*/
switch (genimg_get_format ((void *)rd_addr)) {
case IMAGE_FORMAT_LEGACY:
+ printf ("## Loading init Ramdisk from Legacy "
+ "Image at %08lx ...\n", rd_addr);
- debug ("* ramdisk: legacy format image\n");
-
- rd_hdr = image_get_ramdisk (cmdtp, flag, argc, argv,
- rd_addr, arch, images->verify);
+ show_boot_progress (9);
+ rd_hdr = image_get_ramdisk (rd_addr, arch,
+ images->verify);
- if (rd_hdr == NULL) {
- *rd_start = 0;
- *rd_end = 0;
+ if (rd_hdr == NULL)
return 1;
- }
rd_data = image_get_data (rd_hdr);
rd_len = image_get_data_size (rd_hdr);
#if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT:
fit_hdr = (void *)rd_addr;
- debug ("* ramdisk: FIT format image\n");
- fit_unsupported_reset ("ramdisk");
- return 1;
+ printf ("## Loading init Ramdisk from FIT "
+ "Image at %08lx ...\n", rd_addr);
+
+ show_boot_progress (120);
+ if (!fit_check_format (fit_hdr)) {
+ puts ("Bad FIT ramdisk image format!\n");
+ show_boot_progress (-120);
+ return 0;
+ }
+ show_boot_progress (121);
+
+ 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
+ */
+ show_boot_progress (122);
+ cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
+ if (cfg_noffset < 0) {
+ puts ("Could not find configuration node\n");
+ show_boot_progress (-122);
+ return 0;
+ }
+ 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 */
+ show_boot_progress (123);
+ rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk);
+ }
+ if (rd_noffset < 0) {
+ puts ("Could not find subimage node\n");
+ show_boot_progress (-124);
+ return 0;
+ }
+
+ printf (" Trying '%s' ramdisk subimage\n", fit_uname_ramdisk);
+
+ show_boot_progress (125);
+ if (!fit_check_ramdisk (fit_hdr, rd_noffset, arch, images->verify))
+ return 0;
+
+ /* 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");
+ show_boot_progress (-127);
+ return 0;
+ }
+ show_boot_progress (128);
+
+ 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");
+ show_boot_progress (-129);
+ return 0;
+ }
+ show_boot_progress (129);
+
+ images->fit_hdr_rd = fit_hdr;
+ images->fit_uname_rd = fit_uname_ramdisk;
+ images->fit_noffset_rd = rd_noffset;
+ break;
#endif
default:
- printf ("Wrong Image Format for %s command\n",
- cmdtp->name);
- rd_data = rd_len = 0;
+ puts ("Wrong Ramdisk Image Format\n");
+ rd_data = rd_len = rd_load = 0;
}
#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)
*/
show_boot_progress (13);
printf ("## Loading init Ramdisk from multi component "
- "Image at %08lx ...\n",
+ "Legacy Image at %08lx ...\n",
(ulong)images->legacy_hdr_os);
image_multi_getimg (images->legacy_hdr_os, 1, &rd_data, &rd_len);
if (!rd_data) {
debug ("## No init Ramdisk\n");
- *rd_start = 0;
- *rd_end = 0;
} else {
*rd_start = rd_data;
*rd_end = rd_data + rd_len;
/**
* fit_conf_print - prints out the FIT configuration details
* @fit: pointer to the FIT format image header
- * @conf_noffset: offset of the configuration node
+ * @noffset: offset of the configuration node
* @p: pointer to prefix string
*
* fit_conf_print() lists all mandatory properies for the processed
if (uname)
printf ("%s FDT: %s\n", p, uname);
}
+
+/**
+ * fit_check_ramdisk - verify FIT format ramdisk subimage
+ * @fit_hdr: pointer to the FIT ramdisk header
+ * @rd_noffset: ramdisk subimage node offset within FIT image
+ * @arch: requested ramdisk image architecture type
+ * @verify: data CRC verification flag
+ *
+ * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from
+ * specified FIT image.
+ *
+ * returns:
+ * 1, on success
+ * 0, on failure
+ */
+#ifndef USE_HOSTCC
+static int fit_check_ramdisk (const void *fit, int rd_noffset, uint8_t arch, int verify)
+{
+ fit_image_print (fit, rd_noffset, " ");
+
+ if (verify) {
+ puts (" Verifying Hash Integrity ... ");
+ if (!fit_image_check_hashes (fit, rd_noffset)) {
+ puts ("Bad Data Hash\n");
+ show_boot_progress (-125);
+ return 0;
+ }
+ puts ("OK\n");
+ }
+
+ show_boot_progress (126);
+ if (!fit_image_check_os (fit, rd_noffset, IH_OS_LINUX) ||
+ !fit_image_check_arch (fit, rd_noffset, arch) ||
+ !fit_image_check_type (fit, rd_noffset, IH_TYPE_RAMDISK)) {
+ printf ("No Linux %s Ramdisk Image\n",
+ genimg_get_arch_name(arch));
+ show_boot_progress (-126);
+ return 0;
+ }
+
+ show_boot_progress (127);
+ return 1;
+}
+#endif /* USE_HOSTCC */
#endif /* CONFIG_FIT */