[U-Boot-Users] [PATCH] Fix initrd booting

The device tree needs to be passed to Linux within CFG_BOOTMAPSZ. The current code places the device tree right before the initrd if it exists, and that will usually be closer to the end of memory. Instead, we should always put the device tree right before the bd_info structure, thus ensuring it is within CFG_BOOTMAPSZ.
We do, however, allow for FDTs in uImages to shoot themselves in the foot by requesting a location outside of CFG_BOOTMAPSZ.
Signed-off-by: Andy Fleming afleming@freescale.com --- common/cmd_bootm.c | 20 ++++++++------------ 1 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index a6499e8..d12ef76 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -753,10 +753,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, #else if (*(ulong *)of_flat_tree == OF_DT_HEADER) { #endif -#ifndef CFG_NO_FLASH - if (addr2info((ulong)of_flat_tree) != NULL) - of_data = (ulong)of_flat_tree; -#endif + of_data = (ulong)of_flat_tree; } else if (ntohl(hdr->ih_magic) == IH_MAGIC) { printf("## Flat Device Tree Image at %08lX\n", hdr); print_image_hdr(hdr); @@ -939,11 +936,9 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, ulong of_start, of_len;
of_len = be32_to_cpu(fdt_totalsize(of_data)); + /* position on a 4K boundary before the initrd/kbd */ - if (initrd_start) - of_start = initrd_start - of_len; - else - of_start = (ulong)kbd - of_len; + of_start = (ulong)kbd - of_len; 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); @@ -955,6 +950,8 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, if (err != 0) { printf ("libfdt: %s " __FILE__ " %d\n", fdt_strerror(err), __LINE__); } + printf("OK\n"); + /* * Add the chosen node if it doesn't exist, add the env and bd_t * if the user wants it (the logic is in the subroutines). @@ -982,11 +979,9 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, 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 = (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); @@ -995,6 +990,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, printf (" Loading Device Tree to %08lx, end %08lx ... ", of_start, of_start + of_len - 1); memmove ((void *)of_start, (void *)of_data, of_len); + printf ("OK\n"); } #endif

The device tree needs to be passed to Linux within CFG_BOOTMAPSZ. The current code places the device tree right before the initrd if it exists, and that will usually be closer to the end of memory. Instead, we should always put the device tree right before the bd_info structure, thus ensuring it is within CFG_BOOTMAPSZ.
We do, however, allow for FDTs in uImages to shoot themselves in the foot by requesting a location outside of CFG_BOOTMAPSZ.
Signed-off-by: Andy Fleming afleming@freescale.com ---
Could we please put this in? It fixes a rather obnoxious bug in bootm. Resending with Wolfgang copied this time.
common/cmd_bootm.c | 20 ++++++++------------ 1 files changed, 8 insertions(+), 12 deletions(-)
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index a6499e8..d12ef76 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -753,10 +753,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, #else if (*(ulong *)of_flat_tree == OF_DT_HEADER) { #endif -#ifndef CFG_NO_FLASH - if (addr2info((ulong)of_flat_tree) != NULL) - of_data = (ulong)of_flat_tree; -#endif + of_data = (ulong)of_flat_tree; } else if (ntohl(hdr->ih_magic) == IH_MAGIC) { printf("## Flat Device Tree Image at %08lX\n", hdr); print_image_hdr(hdr); @@ -939,11 +936,9 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, ulong of_start, of_len;
of_len = be32_to_cpu(fdt_totalsize(of_data)); + /* position on a 4K boundary before the initrd/kbd */ - if (initrd_start) - of_start = initrd_start - of_len; - else - of_start = (ulong)kbd - of_len; + of_start = (ulong)kbd - of_len; 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); @@ -955,6 +950,8 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, if (err != 0) { printf ("libfdt: %s " __FILE__ " %d\n", fdt_strerror(err), __LINE__); } + printf("OK\n"); + /* * Add the chosen node if it doesn't exist, add the env and bd_t * if the user wants it (the logic is in the subroutines). @@ -982,11 +979,9 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, 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 = (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); @@ -995,6 +990,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, printf (" Loading Device Tree to %08lx, end %08lx ... ", of_start, of_start + of_len - 1); memmove ((void *)of_start, (void *)of_data, of_len); + printf ("OK\n"); } #endif
-- 1.5.0.2.230.gfbe3d-dirty
------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ U-Boot-Users mailing list U-Boot-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users
participants (2)
-
Andy Fleming
-
Andy Fleming