Skip to content
Snippets Groups Projects
Commit c76f951a authored by Kumar Gala's avatar Kumar Gala
Browse files

Added support for Multi-Image files that contain a device tree


If a Multi-Image file contains a third image we try to use it as a
device tree.  The device tree image is assumed to be uncompressed in the
image file.  We automatically allocate space for the device tree in memory
and provide an 8k pad to allow more than a reasonable amount of growth.

Additionally, a device tree that was contained in flash will now automatically
get copied to system memory as part of boot.  Previously an error was
reported if one tried to boot a device tree that was in flash.

Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
parent 8ae3b713
No related branches found
No related tags found
No related merge requests found
...@@ -531,6 +531,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, ...@@ -531,6 +531,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
image_header_t *hdr = &header; image_header_t *hdr = &header;
#ifdef CONFIG_OF_FLAT_TREE #ifdef CONFIG_OF_FLAT_TREE
char *of_flat_tree = NULL; char *of_flat_tree = NULL;
ulong of_data = 0;
#endif #endif
if ((s = getenv ("initrd_high")) != NULL) { if ((s = getenv ("initrd_high")) != NULL) {
...@@ -745,11 +746,8 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, ...@@ -745,11 +746,8 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
if (*(ulong *)of_flat_tree == OF_DT_HEADER) { if (*(ulong *)of_flat_tree == OF_DT_HEADER) {
#ifndef CFG_NO_FLASH #ifndef CFG_NO_FLASH
if (addr2info((ulong)of_flat_tree) != NULL) { if (addr2info((ulong)of_flat_tree) != NULL)
printf ("Cannot modify flat device tree stored in flash\n" \ of_data = (ulong)of_flat_tree;
"Copy to memory before using the bootm command\n");
return;
}
#endif #endif
} else if (ntohl(hdr->ih_magic) == IH_MAGIC) { } else if (ntohl(hdr->ih_magic) == IH_MAGIC) {
printf("## Flat Device Tree Image at %08lX\n", hdr); printf("## Flat Device Tree Image at %08lX\n", hdr);
...@@ -804,7 +802,39 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, ...@@ -804,7 +802,39 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
} }
printf (" Booting using flat device tree at 0x%x\n", printf (" Booting using flat device tree at 0x%x\n",
of_flat_tree); of_flat_tree);
} else if(getenv("disable_of") == NULL) { } else if ((hdr->ih_type==IH_TYPE_MULTI) && (len_ptr[1]) && (len_ptr[2])) {
u_long tail = ntohl(len_ptr[0]) % 4;
int i;
/* skip kernel length, initrd length, and terminator */
of_data = (ulong)(&len_ptr[3]);
/* skip any additional image length fields */
for (i=2; len_ptr[i]; ++i)
of_data += 4;
/* add kernel length, and align */
of_data += ntohl(len_ptr[0]);
if (tail) {
of_data += 4 - tail;
}
/* add initrd length, and align */
tail = ntohl(len_ptr[1]) % 4;
of_data += ntohl(len_ptr[1]);
if (tail) {
of_data += 4 - tail;
}
if (((struct boot_param_header *)of_data)->magic != OF_DT_HEADER) {
printf ("ERROR: image is not a flat device tree\n");
return;
}
if (((struct boot_param_header *)of_data)->totalsize != ntohl(len_ptr[2])) {
printf ("ERROR: flat device tree size does not agree with image\n");
return;
}
} else if (getenv("disable_of") == NULL) {
printf ("ERROR: bootm needs flat device tree as third argument\n"); printf ("ERROR: bootm needs flat device tree as third argument\n");
return; return;
} }
...@@ -900,6 +930,25 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, ...@@ -900,6 +930,25 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,
(*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end); (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end);
#else #else
/* move of_flat_tree if needed */
if (of_data) {
ulong of_start, of_len;
of_len = ((struct boot_param_header *)of_data)->totalsize;
/* provide extra 8k pad */
if (initrd_start)
of_start = initrd_start - of_len - 8192;
else
of_start = (ulong)kbd - of_len - 8192;
of_start &= ~(4096 - 1); /* align on page */
debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
of_data, of_data + of_len - 1, of_len, of_len);
of_flat_tree = (char *)of_start;
printf (" Loading Device Tree to %08lx, end %08lx ... ",
of_start, of_start + of_len - 1);
memmove ((void *)of_start, (void *)of_data, of_len);
}
ft_setup(of_flat_tree, kbd, initrd_start, initrd_end); ft_setup(of_flat_tree, kbd, initrd_start, initrd_end);
/* ft_dump_blob(of_flat_tree); */ /* ft_dump_blob(of_flat_tree); */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment