[U-Boot-Users] [PATCH 17/20] [new uImage] Add proper ramdisk/FDT handling when FIT configuration is used
Bartlomiej Sieka
tur at semihalf.com
Wed Mar 12 21:12:13 CET 2008
From: Marian Balakowicz <m8 at semihalf.com>
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 at semihalf.com>
---
README | 1
common/cmd_bootm.c | 14 +++++--
common/image.c | 112 +++++++++++++++++++++++++++++++++++++++-------------
include/image.h | 3 +
lib_ppc/bootm.c | 104 ++++++++++++++++++++++++++++++++++--------------
5 files changed, 170 insertions(+), 64 deletions(-)
diff --git a/README b/README
index 183246e..0ed47f0 100644
--- 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
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index e95c5dd..2f232e7 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -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 */
diff --git a/common/image.c b/common/image.c
index f29614b..bb57d6d 100644
--- a/common/image.c
+++ b/common/image.c
@@ -738,6 +738,26 @@ ulong genimg_get_image (ulong img_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
* @argv: command argument list
@@ -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
diff --git a/include/image.h b/include/image.h
index 51c0c89..0109560 100644
--- a/include/image.h
+++ b/include/image.h
@@ -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,
diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c
index 86e104c..8cdace2 100644
--- a/lib_ppc/bootm.c
+++ b/lib_ppc/bootm.c
@@ -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);
More information about the U-Boot
mailing list