[new uImage] Add proper ramdisk/FDT handling when FIT configuration is used
authorMarian Balakowicz <m8@semihalf.com>
Wed, 12 Mar 2008 09:35:46 +0000 (10:35 +0100)
committerMarian Balakowicz <m8@semihalf.com>
Wed, 12 Mar 2008 09:35:46 +0000 (10:35 +0100)
Save FIT configuration provied in the first bootm argument and use it
when to get ramdisk/FDT subimages when second and third (ramdisk/FDT)
arguments are not specified.

Signed-off-by: Marian Balakowicz <m8@semihalf.com>
README
common/cmd_bootm.c
common/image.c
include/image.h
lib_ppc/bootm.c

diff --git a/README b/README
index 183246e7b01889dc2f99b98d45392a9953f5b28a..0ed47f09177301fb9cfe76ce293ac1ccd0bc1911 100644 (file)
--- a/README
+++ b/README
@@ -1769,6 +1769,7 @@ FIT uImage format:
  -101  common/cmd_bootm.c      Can't get configuration for kernel subimage
   102  common/cmd_bootm.c      Kernel unit name specified
  -103  common/cmd_bootm.c      Can't get kernel subimage node offset
+  103  common/cmd_bootm.c      Found configuration node
   104  common/cmd_bootm.c      Got kernel subimage node offset
  -104  common/cmd_bootm.c      Kernel subimage hash verification failed
   105  common/cmd_bootm.c      Kernel subimage hash verification OK
index e95c5dd034ac0921fbbf6a008f3e45fc2cbc0034..2f232e79538a74dcabc1be51bd8d8bd47ac4d29b 100644 (file)
@@ -469,7 +469,7 @@ static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]
        const char      *fit_uname_kernel = NULL;
        const void      *data;
        size_t          len;
-       int             conf_noffset;
+       int             cfg_noffset;
        int             os_noffset;
 #endif
 
@@ -548,13 +548,19 @@ static void *boot_get_kernel (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]
                         * fit_conf_get_node() will try to find default config node
                         */
                        show_boot_progress (101);
-                       conf_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
-                       if (conf_noffset < 0) {
+                       cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
+                       if (cfg_noffset < 0) {
                                show_boot_progress (-101);
                                return NULL;
                        }
+                       /* save configuration uname provided in the first
+                        * bootm argument
+                        */
+                       images->fit_uname_cfg = fdt_get_name (fit_hdr, cfg_noffset, NULL);
+                       printf ("   Using '%s' configuration\n", images->fit_uname_cfg);
+                       show_boot_progress (103);
 
-                       os_noffset = fit_conf_get_kernel_node (fit_hdr, conf_noffset);
+                       os_noffset = fit_conf_get_kernel_node (fit_hdr, cfg_noffset);
                        fit_uname_kernel = fit_get_name (fit_hdr, os_noffset, NULL);
                } else {
                        /* get kernel component image node offset */
index f29614b9e223381243389dbf1722711c1580c23c..bb57d6dba63939d0a8f5b376fa4b79dd95366eb0 100644 (file)
@@ -737,6 +737,26 @@ ulong genimg_get_image (ulong img_addr)
        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
  * @argc: command argument count
@@ -771,7 +791,7 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
        const char      *fit_uname_ramdisk = NULL;
        ulong           default_addr;
        int             rd_noffset;
-       int             conf_noffset;
+       int             cfg_noffset;
        const void      *data;
        size_t          size;
 #endif
@@ -786,33 +806,63 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
        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 */
                rd_addr = genimg_get_image (rd_addr);
@@ -859,13 +909,16 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
                                 * fit_conf_get_node() will try to find default config node
                                 */
                                show_boot_progress (122);
-                               conf_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
-                               if (conf_noffset < 0) {
+                               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, conf_noffset);
+                               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 */
@@ -873,6 +926,7 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
                                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;
                        }
@@ -2394,7 +2448,7 @@ int fit_conf_get_fdt_node (const void *fit, int noffset)
 /**
  * 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
index 51c0c896f678459d87dd9e8e3d06047eabe725f8..01095608a474c4a4a4e65642f3ea5058d28ddade 100644 (file)
@@ -206,6 +206,8 @@ typedef struct bootm_headers {
        ulong           legacy_hdr_valid;
 
 #if defined(CONFIG_FIT)
+       const char      *fit_uname_cfg; /* configuration node unit name */
+
        void            *fit_hdr_os;    /* os FIT image header */
        const char      *fit_uname_os;  /* os subimage node unit name */
        int             fit_noffset_os; /* os subimage node offset */
@@ -251,6 +253,7 @@ int genimg_get_comp_id (const char *name);
 #define IMAGE_FORMAT_FIT       0x02    /* new, libfdt based format */
 
 int genimg_get_format (void *img_addr);
+int genimg_has_config (bootm_headers_t *images);
 ulong genimg_get_image (ulong img_addr);
 
 int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
index 86e104cdcc34240e87f0b89dc528336d4528da49..8cdace2859474dbba5ade46ea6cef5deadad7067 100644 (file)
@@ -415,7 +415,7 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
         const char      *fit_uname_config = NULL;
         const char      *fit_uname_fdt = NULL;
        ulong           default_addr;
-       int             conf_noffset;
+       int             cfg_noffset;
        int             fdt_noffset;
        const void      *data;
        size_t          size;
@@ -424,35 +424,67 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
        *of_flat_tree = NULL;
        *of_size = 0;
 
-       if (argc > 3) {
+       if (argc > 3 || genimg_has_config (images)) {
 #if defined(CONFIG_FIT)
-               /*
-                * If the FDT blob comes from the FIT image and the FIT image
-                * address is omitted in the command line argument, try to use
-                * ramdisk or os FIT image address or default load address.
-                */
-               if (images->fit_uname_rd)
-                       default_addr = (ulong)images->fit_hdr_rd;
-               else if (images->fit_uname_os)
-                       default_addr = (ulong)images->fit_hdr_os;
-               else
-                       default_addr = load_addr;
-
-               if (fit_parse_conf (argv[3], default_addr,
-                                       &fdt_addr, &fit_uname_config)) {
-                       debug ("*  fdt: config '%s' from image at 0x%08lx\n",
-                                       fit_uname_config, fdt_addr);
-               } else if (fit_parse_subimage (argv[3], default_addr,
-                                       &fdt_addr, &fit_uname_fdt)) {
-                       debug ("*  fdt: subimage '%s' from image at 0x%08lx\n",
-                                       fit_uname_fdt, fdt_addr);
-               } else
+               if (argc > 3) {
+                       /*
+                        * If the FDT blob comes from the FIT image and the
+                        * FIT image address is omitted in the command line
+                        * argument, try to use ramdisk or os FIT image
+                        * address or default load address.
+                        */
+                       if (images->fit_uname_rd)
+                               default_addr = (ulong)images->fit_hdr_rd;
+                       else if (images->fit_uname_os)
+                               default_addr = (ulong)images->fit_hdr_os;
+                       else
+                               default_addr = load_addr;
+
+                       if (fit_parse_conf (argv[3], default_addr,
+                                               &fdt_addr, &fit_uname_config)) {
+                               debug ("*  fdt: config '%s' from image at 0x%08lx\n",
+                                               fit_uname_config, fdt_addr);
+                       } else if (fit_parse_subimage (argv[3], default_addr,
+                                               &fdt_addr, &fit_uname_fdt)) {
+                               debug ("*  fdt: subimage '%s' from image at 0x%08lx\n",
+                                               fit_uname_fdt, fdt_addr);
+                       } else
 #endif
-               {
-                       fdt_addr = simple_strtoul(argv[3], NULL, 16);
-                       debug ("*  fdt: cmdline image address = 0x%08lx\n",
-                                       fdt_addr);
+                       {
+                               fdt_addr = simple_strtoul(argv[3], NULL, 16);
+                               debug ("*  fdt: cmdline image address = 0x%08lx\n",
+                                               fdt_addr);
+                       }
+#if defined(CONFIG_FIT)
+               } else {
+                       /* use FIT configuration provided in first bootm
+                        * command argument
+                        */
+                       fdt_addr = (ulong)images->fit_hdr_os;
+                       fit_uname_config = images->fit_uname_cfg;
+                       debug ("*  fdt: using config '%s' from image at 0x%08lx\n",
+                                       fit_uname_config, fdt_addr);
+
+                       /*
+                        * Check whether configuration has FDT blob defined,
+                        * if not quit silently.
+                        */
+                       fit_hdr = (void *)fdt_addr;
+                       cfg_noffset = fit_conf_get_node (fit_hdr,
+                                       fit_uname_config);
+                       if (cfg_noffset < 0) {
+                               debug ("*  fdt: no such config\n");
+                               return 0;
+                       }
+
+                       fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
+                                       cfg_noffset);
+                       if (fdt_noffset < 0) {
+                               debug ("*  fdt: no fdt in config\n");
+                               return 0;
+                       }
                }
+#endif
 
                debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n",
                                fdt_addr);
@@ -522,13 +554,21 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
                                         * fit_conf_get_node() will try to
                                         * find default config node
                                         */
-                                       conf_noffset = fit_conf_get_node (fit_hdr,
+                                       cfg_noffset = fit_conf_get_node (fit_hdr,
                                                        fit_uname_config);
-                                       if (conf_noffset < 0)
+
+                                       if (cfg_noffset < 0) {
+                                               fdt_error ("Could not find configuration node\n");
                                                goto error;
+                                       }
+
+                                       fit_uname_config = fdt_get_name (fit_hdr,
+                                                       cfg_noffset, NULL);
+                                       printf ("   Using '%s' configuration\n",
+                                                       fit_uname_config);
 
                                        fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
-                                                       conf_noffset);
+                                                       cfg_noffset);
                                        fit_uname_fdt = fit_get_name (fit_hdr,
                                                        fdt_noffset, NULL);
                                } else {
@@ -536,8 +576,10 @@ static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
                                        fdt_noffset = fit_image_get_node (fit_hdr,
                                                        fit_uname_fdt);
                                }
-                               if (fdt_noffset < 0)
+                               if (fdt_noffset < 0) {
+                                       fdt_error ("Could not find subimage node\n");
                                        goto error;
+                               }
 
                                printf ("   Trying '%s' FDT blob subimage\n",
                                                fit_uname_fdt);