From 590d3cacb98cb377b127869b58507d2afe9c904a Mon Sep 17 00:00:00 2001 From: Grant Likely <grant.likely@linaro.org> Date: Mon, 28 Mar 2011 09:58:34 +0000 Subject: [PATCH 1/5] Stop passing around bootmem_base value. For the calls to boot_relocate_fdt(), boot_get_cmdline(), and boot_get_kbd(), the value of bootmem_base is always obtained by calling getenv_bootm_low(). Since the value always comes from the same source, the calling signature for those functions can be simplified by making them call getenv_bootm_low() directly. Signed-off-by: Grant Likely <grant.likely@linaro.org> --- arch/arm/lib/bootm.c | 3 +-- arch/m68k/lib/bootm.c | 7 ++----- arch/powerpc/lib/bootm.c | 9 +++------ common/cmd_bootm.c | 3 +-- common/image.c | 25 +++++++++---------------- include/image.h | 8 +++----- 6 files changed, 19 insertions(+), 36 deletions(-) diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 77349530f0..aba13f4e86 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -178,7 +178,6 @@ static int bootm_linux_fdt(int machid, bootm_headers_t *images) { ulong rd_len; void (*kernel_entry)(int zero, int dt_machid, void *dtblob); - ulong bootmap_base = getenv_bootm_low(); ulong of_size = images->ft_len; char **of_flat_tree = &images->ft_addr; ulong *initrd_start = &images->initrd_start; @@ -194,7 +193,7 @@ static int bootm_linux_fdt(int machid, bootm_headers_t *images) if (ret) return ret; - ret = boot_relocate_fdt(lmb, bootmap_base, of_flat_tree, &of_size); + ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); if (ret) return ret; diff --git a/arch/m68k/lib/bootm.c b/arch/m68k/lib/bootm.c index 76a2fb27c1..1229ac7f25 100644 --- a/arch/m68k/lib/bootm.c +++ b/arch/m68k/lib/bootm.c @@ -71,7 +71,6 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima int ret; ulong cmd_start, cmd_end; - ulong bootmap_base; bd_t *kbd; void (*kernel) (bd_t *, ulong, ulong, ulong, ulong); struct lmb *lmb = &images->lmb; @@ -79,17 +78,15 @@ int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *ima if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1; - bootmap_base = getenv_bootm_low(); - /* allocate space and init command line */ - ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base); + ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end); if (ret) { puts("ERROR with allocation of cmdline\n"); goto error; } /* allocate space for kernel copy of board info */ - ret = boot_get_kbd (lmb, &kbd, bootmap_base); + ret = boot_get_kbd (lmb, &kbd); if (ret) { puts("ERROR with allocation of kernel bd\n"); goto error; diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index c7f3d084a3..6e2a81b9aa 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -186,7 +186,6 @@ static void boot_prep_linux(void) static int boot_cmdline_linux(bootm_headers_t *images) { - ulong bootmap_base = getenv_bootm_low(); ulong of_size = images->ft_len; struct lmb *lmb = &images->lmb; ulong *cmd_start = &images->cmdline_start; @@ -196,7 +195,7 @@ static int boot_cmdline_linux(bootm_headers_t *images) if (!of_size) { /* allocate space and init command line */ - ret = boot_get_cmdline (lmb, cmd_start, cmd_end, bootmap_base); + ret = boot_get_cmdline (lmb, cmd_start, cmd_end); if (ret) { puts("ERROR with allocation of cmdline\n"); return ret; @@ -208,7 +207,6 @@ static int boot_cmdline_linux(bootm_headers_t *images) static int boot_bd_t_linux(bootm_headers_t *images) { - ulong bootmap_base = getenv_bootm_low(); ulong of_size = images->ft_len; struct lmb *lmb = &images->lmb; bd_t **kbd = &images->kbd; @@ -217,7 +215,7 @@ static int boot_bd_t_linux(bootm_headers_t *images) if (!of_size) { /* allocate space for kernel copy of board info */ - ret = boot_get_kbd (lmb, kbd, bootmap_base); + ret = boot_get_kbd (lmb, kbd); if (ret) { puts("ERROR with allocation of kernel bd\n"); return ret; @@ -235,7 +233,6 @@ static int boot_body_linux(bootm_headers_t *images) ulong *initrd_start = &images->initrd_start; ulong *initrd_end = &images->initrd_end; #if defined(CONFIG_OF_LIBFDT) - ulong bootmap_base = getenv_bootm_low(); ulong of_size = images->ft_len; char **of_flat_tree = &images->ft_addr; #endif @@ -258,7 +255,7 @@ static int boot_body_linux(bootm_headers_t *images) return ret; #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_SYS_BOOTMAPSZ) - ret = boot_relocate_fdt(lmb, bootmap_base, of_flat_tree, &of_size); + ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); if (ret) return ret; diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 778f6a4296..989bf737ff 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -547,8 +547,7 @@ int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv #if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_SYS_BOOTMAPSZ) case BOOTM_STATE_FDT: { - ulong bootmap_base = getenv_bootm_low(); - ret = boot_relocate_fdt(&images.lmb, bootmap_base, + ret = boot_relocate_fdt(&images.lmb, &images.ft_addr, &images.ft_len); break; } diff --git a/common/image.c b/common/image.c index f63a2ff1a0..c86b86fbe7 100644 --- a/common/image.c +++ b/common/image.c @@ -1172,7 +1172,6 @@ static int fit_check_fdt (const void *fit, int fdt_noffset, int verify) /** * boot_relocate_fdt - relocate flat device tree * @lmb: pointer to lmb handle, will be used for memory mgmt - * @bootmap_base: base address of the bootmap region * @of_flat_tree: pointer to a char* variable, will hold fdt start address * @of_size: pointer to a ulong variable, will hold fdt length * @@ -1188,8 +1187,7 @@ static int fit_check_fdt (const void *fit, int fdt_noffset, int verify) * 1 - failure */ #if defined(CONFIG_SYS_BOOTMAPSZ) -int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, - char **of_flat_tree, ulong *of_size) +int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size) { void *fdt_blob = *of_flat_tree; void *of_start = 0; @@ -1209,7 +1207,7 @@ int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, /* Pad the FDT by a specified amount */ of_len = *of_size + CONFIG_SYS_FDT_PAD; of_start = (void *)(unsigned long)lmb_alloc_base(lmb, of_len, 0x1000, - (CONFIG_SYS_BOOTMAPSZ + bootmap_base)); + CONFIG_SYS_BOOTMAPSZ + getenv_bootm_low()); if (of_start == 0) { puts("device tree - allocation error\n"); @@ -1567,11 +1565,9 @@ error: * @lmb: pointer to lmb handle, will be used for memory mgmt * @cmd_start: pointer to a ulong variable, will hold cmdline start * @cmd_end: pointer to a ulong variable, will hold cmdline end - * @bootmap_base: ulong variable, holds offset in physical memory to - * base of bootmap * * boot_get_cmdline() allocates space for kernel command line below - * BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt + * BOOTMAPSZ + getenv_bootm_low() address. If "bootargs" U-boot environemnt * variable is present its contents is copied to allocated kernel * command line. * @@ -1579,14 +1575,13 @@ error: * 0 - success * -1 - failure */ -int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, - ulong bootmap_base) +int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) { char *cmdline; char *s; cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf, - CONFIG_SYS_BOOTMAPSZ + bootmap_base); + CONFIG_SYS_BOOTMAPSZ + getenv_bootm_low()); if (cmdline == NULL) return -1; @@ -1610,21 +1605,19 @@ int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, * boot_get_kbd - allocate and initialize kernel copy of board info * @lmb: pointer to lmb handle, will be used for memory mgmt * @kbd: double pointer to board info data - * @bootmap_base: ulong variable, holds offset in physical memory to - * base of bootmap * * boot_get_kbd() allocates space for kernel copy of board info data below - * BOOTMAPSZ + bootmap_base address and kernel board info is initialized with - * the current u-boot board info data. + * BOOTMAPSZ + getenv_bootm_low() address and kernel board info is initialized + * with the current u-boot board info data. * * returns: * 0 - success * -1 - failure */ -int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base) +int boot_get_kbd (struct lmb *lmb, bd_t **kbd) { *kbd = (bd_t *)(ulong)lmb_alloc_base(lmb, sizeof(bd_t), 0xf, - CONFIG_SYS_BOOTMAPSZ + bootmap_base); + CONFIG_SYS_BOOTMAPSZ + getenv_bootm_low()); if (*kbd == NULL) return -1; diff --git a/include/image.h b/include/image.h index 005e0d24e4..792de25104 100644 --- a/include/image.h +++ b/include/image.h @@ -336,8 +336,7 @@ int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images, #ifdef CONFIG_OF_LIBFDT int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size); -int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base, - char **of_flat_tree, ulong *of_size); +int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size); #endif #ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH @@ -345,11 +344,10 @@ int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len, ulong *initrd_start, ulong *initrd_end); #endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */ #ifdef CONFIG_SYS_BOOT_GET_CMDLINE -int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end, - ulong bootmap_base); +int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end); #endif /* CONFIG_SYS_BOOT_GET_CMDLINE */ #ifdef CONFIG_SYS_BOOT_GET_KBD -int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base); +int boot_get_kbd (struct lmb *lmb, bd_t **kbd); #endif /* CONFIG_SYS_BOOT_GET_KBD */ #endif /* !USE_HOSTCC */ From c3624e6ed0a36f54aa0b3e7f32d30a6fde434f51 Mon Sep 17 00:00:00 2001 From: Grant Likely <grant.likely@linaro.org> Date: Mon, 28 Mar 2011 09:58:43 +0000 Subject: [PATCH 2/5] Default to bootm_size() when CONFIG_SYS_BOOTMAPSZ is not defined This patch adds a function getenv_bootm_mapsize() for obtaining the size of the early mapped region accessible by the kernel during early boot. It defaults to CONFIG_SYS_BOOTMAPSZ, or if not defined, defaults to getenv_bootm_size(), which in turn defaults to the size of RAM. getenv_bootm_mapsize() can also be overridden with a "bootm_mapsize" environmental variable. Signed-off-by: Grant Likely <grant.likely@linaro.org> --- README | 16 ++++++++++++++-- arch/powerpc/lib/bootm.c | 2 +- common/image.c | 22 +++++++++++++++++++--- include/image.h | 1 + 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/README b/README index cdbb9de02c..b647ecac34 100644 --- a/README +++ b/README @@ -2348,7 +2348,10 @@ Configuration Settings: used) must be put below this limit, unless "bootm_low" enviroment variable is defined and non-zero. In such case all data for the Linux kernel must be between "bootm_low" - and "bootm_low" + CONFIG_SYS_BOOTMAPSZ. + and "bootm_low" + CONFIG_SYS_BOOTMAPSZ. The environment + variable "bootm_mapsize" will override the value of + CONFIG_SYS_BOOTMAPSZ. If CONFIG_SYS_BOOTMAPSZ is undefined, + then the value in "bootm_size" will be used instead. - CONFIG_SYS_BOOT_RAMDISK_HIGH: Enable initrd_high functionality. If defined then the @@ -3184,7 +3187,16 @@ List of environment variables (most likely not complete): for use by the bootm command. See also "bootm_size" environment variable. Address defined by "bootm_low" is also the base of the initial memory mapping for the Linux - kernel -- see the description of CONFIG_SYS_BOOTMAPSZ. + kernel -- see the description of CONFIG_SYS_BOOTMAPSZ and + bootm_mapsize. + + bootm_mapsize - Size of the initial memory mapping for the Linux kernel. + This variable is given as a hexadecimal number and it + defines the size of the memory region starting at base + address bootm_low that is accessible by the Linux kernel + during early boot. If unset, CONFIG_SYS_BOOTMAPSZ is used + as the default value if it is defined, and bootm_size is + used otherwise. bootm_size - Memory range available for image processing in the bootm command can be restricted. This variable is given as diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index 6e2a81b9aa..02e544fcdd 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -96,7 +96,7 @@ static void boot_jump_linux(bootm_headers_t *images) debug (" Booting using OF flat tree...\n"); WATCHDOG_RESET (); (*kernel) ((bd_t *)of_flat_tree, 0, 0, EPAPR_MAGIC, - CONFIG_SYS_BOOTMAPSZ, 0, 0); + getenv_bootm_mapsize(), 0, 0); /* does not return */ } else #endif diff --git a/common/image.c b/common/image.c index c86b86fbe7..d8ba2ab90a 100644 --- a/common/image.c +++ b/common/image.c @@ -454,6 +454,22 @@ phys_size_t getenv_bootm_size(void) #endif } +phys_size_t getenv_bootm_mapsize(void) +{ + phys_size_t tmp; + char *s = getenv ("bootm_mapsize"); + if (s) { + tmp = (phys_size_t)simple_strtoull (s, NULL, 16); + return tmp; + } + +#if defined(CONFIG_SYS_BOOTMAPSZ) + return CONFIG_SYS_BOOTMAPSZ; +#else + return getenv_bootm_size(); +#endif +} + void memmove_wd (void *to, void *from, size_t len, ulong chunksz) { if (to == from) @@ -1207,7 +1223,7 @@ int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size) /* Pad the FDT by a specified amount */ of_len = *of_size + CONFIG_SYS_FDT_PAD; of_start = (void *)(unsigned long)lmb_alloc_base(lmb, of_len, 0x1000, - CONFIG_SYS_BOOTMAPSZ + getenv_bootm_low()); + getenv_bootm_mapsize() + getenv_bootm_low()); if (of_start == 0) { puts("device tree - allocation error\n"); @@ -1581,7 +1597,7 @@ int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) char *s; cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf, - CONFIG_SYS_BOOTMAPSZ + getenv_bootm_low()); + getenv_bootm_mapsize() + getenv_bootm_low()); if (cmdline == NULL) return -1; @@ -1617,7 +1633,7 @@ int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) int boot_get_kbd (struct lmb *lmb, bd_t **kbd) { *kbd = (bd_t *)(ulong)lmb_alloc_base(lmb, sizeof(bd_t), 0xf, - CONFIG_SYS_BOOTMAPSZ + getenv_bootm_low()); + getenv_bootm_mapsize() + getenv_bootm_low()); if (*kbd == NULL) return -1; diff --git a/include/image.h b/include/image.h index 792de25104..8c40557314 100644 --- a/include/image.h +++ b/include/image.h @@ -451,6 +451,7 @@ int image_check_dcrc (const image_header_t *hdr); int getenv_yesno (char *var); ulong getenv_bootm_low(void); phys_size_t getenv_bootm_size(void); +phys_size_t getenv_bootm_mapsize(void); void memmove_wd (void *to, void *from, size_t len, ulong chunksz); #endif From ed59e58786cae9f8afcb575649afc65985beed4d Mon Sep 17 00:00:00 2001 From: Grant Likely <grant.likely@linaro.org> Date: Mon, 28 Mar 2011 09:58:49 +0000 Subject: [PATCH 3/5] Remove device tree booting dependency on CONFIG_SYS_BOOTMAPSZ The previous patch makes u-boot use the full accessible size of ram as the default boot mapped size if CONFIG_SYS_BOOTMAPSZ is not defined, which means boot_relocate_fdt() can be changed to depend solely on CONFIG_OF_LIBFDT. Signed-off-by: Grant Likely <grant.likely@linaro.org> --- arch/powerpc/lib/bootm.c | 4 ++-- common/cmd_bootm.c | 2 +- common/image.c | 4 ++-- include/configs/omap3_beagle.h | 7 ------- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index 02e544fcdd..6be22c474a 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -254,7 +254,7 @@ static int boot_body_linux(bootm_headers_t *images) if (ret) return ret; -#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_SYS_BOOTMAPSZ) +#if defined(CONFIG_OF_LIBFDT) ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size); if (ret) return ret; @@ -293,7 +293,7 @@ static int boot_body_linux(bootm_headers_t *images) if (*initrd_start && *initrd_end) fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1); } -#endif /* CONFIG_OF_LIBFDT && CONFIG_SYS_BOOTMAPSZ */ +#endif /* CONFIG_OF_LIBFDT */ return 0; } diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 989bf737ff..a23e465696 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -544,7 +544,7 @@ int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv } break; #endif -#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_SYS_BOOTMAPSZ) +#if defined(CONFIG_OF_LIBFDT) case BOOTM_STATE_FDT: { ret = boot_relocate_fdt(&images.lmb, diff --git a/common/image.c b/common/image.c index d8ba2ab90a..5ce4b1bd24 100644 --- a/common/image.c +++ b/common/image.c @@ -1202,7 +1202,7 @@ static int fit_check_fdt (const void *fit, int fdt_noffset, int verify) * 0 - success * 1 - failure */ -#if defined(CONFIG_SYS_BOOTMAPSZ) +#if defined(CONFIG_OF_LIBFDT) int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size) { void *fdt_blob = *of_flat_tree; @@ -1252,7 +1252,7 @@ int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size) error: return 1; } -#endif /* CONFIG_SYS_BOOTMAPSZ */ +#endif /* CONFIG_OF_LIBFDT */ /** * boot_get_fdt - main fdt handling routine diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h index 5cfa4cb69a..a0f6829625 100644 --- a/include/configs/omap3_beagle.h +++ b/include/configs/omap3_beagle.h @@ -56,13 +56,6 @@ #define CONFIG_MISC_INIT_R #define CONFIG_OF_LIBFDT 1 -/* - * The early kernel mapping on ARM currently only maps from the base of DRAM - * to the end of the kernel image. The kernel is loaded at DRAM base + 0x8000. - * The early kernel pagetable uses DRAM base + 0x4000 to DRAM base + 0x8000, - * so that leaves DRAM base to DRAM base + 0x4000 available. - */ -#define CONFIG_SYS_BOOTMAPSZ 0x4000 #define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */ #define CONFIG_SETUP_MEMORY_TAGS 1 From ce6b27a874fe30e7126ae93c060277770ee85ced Mon Sep 17 00:00:00 2001 From: Grant Likely <grant.likely@linaro.org> Date: Mon, 28 Mar 2011 09:58:55 +0000 Subject: [PATCH 4/5] Fix off-by-one error in passing initrd end address via device tree The initrd_end variable contains the address immediately *after* the initrd blob, not the last address containing data. This patch fixes an inadvertent off-by-one when setting up the initrd reserved map. Signed-off-by: Grant Likely <grant.likely@linaro.org> --- common/fdt_support.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/fdt_support.c b/common/fdt_support.c index edcf04a21b..496040b54c 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -183,7 +183,7 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force) } } - err = fdt_add_mem_rsv(fdt, initrd_start, initrd_end - initrd_start + 1); + err = fdt_add_mem_rsv(fdt, initrd_start, initrd_end - initrd_start); if (err < 0) { printf("fdt_initrd: %s\n", fdt_strerror(err)); return err; From 55b0a39314562087143f439ecae57379b97db9aa Mon Sep 17 00:00:00 2001 From: Grant Likely <grant.likely@linaro.org> Date: Mon, 28 Mar 2011 09:59:01 +0000 Subject: [PATCH 5/5] Respect memreserve regions specified in the device tree If a regions is reserved in the fdt, then it should not be used. Add the memreserve regions to the lmb so that u-boot doesn't use them to store the initrd. Signed-off-by: Grant Likely <grant.likely@linaro.org> --- arch/arm/lib/bootm.c | 2 ++ arch/powerpc/lib/bootm.c | 4 ++++ common/cmd_bootm.c | 2 ++ common/image.c | 29 ++++++++++++++++++++++++++++- include/image.h | 1 + 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index aba13f4e86..802e833a2e 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -187,6 +187,8 @@ static int bootm_linux_fdt(int machid, bootm_headers_t *images) kernel_entry = (void (*)(int, int, void *))images->ep; + boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); + rd_len = images->rd_end - images->rd_start; ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, initrd_start, initrd_end); diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index 6be22c474a..e01787dcb7 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -239,6 +239,10 @@ static int boot_body_linux(bootm_headers_t *images) int ret; +#if defined(CONFIG_OF_LIBFDT) + boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); +#endif + /* allocate space and init command line */ ret = boot_cmdline_linux(images); if (ret) diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index a23e465696..1966da48ca 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -547,6 +547,8 @@ int do_bootm_subcommand (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv #if defined(CONFIG_OF_LIBFDT) case BOOTM_STATE_FDT: { + boot_fdt_add_mem_rsv_regions(&images.lmb, + images.ft_addr); ret = boot_relocate_fdt(&images.lmb, &images.ft_addr, &images.ft_len); break; diff --git a/common/image.c b/common/image.c index 5ce4b1bd24..e542a57367 100644 --- a/common/image.c +++ b/common/image.c @@ -1185,6 +1185,34 @@ static int fit_check_fdt (const void *fit, int fdt_noffset, int verify) #define CONFIG_SYS_FDT_PAD 0x3000 #endif +#if defined(CONFIG_OF_LIBFDT) +/** + * boot_fdt_add_mem_rsv_regions - Mark the memreserve sections as unusable + * @lmb: pointer to lmb handle, will be used for memory mgmt + * @fdt_blob: pointer to fdt blob base address + * + * Adds the memreserve regions in the dtb to the lmb block. Adding the + * memreserve regions prevents u-boot from using them to store the initrd + * or the fdt blob. + */ +void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) +{ + uint64_t addr, size; + int i, total; + + if (fdt_check_header (fdt_blob) != 0) + return; + + total = fdt_num_mem_rsv(fdt_blob); + for (i = 0; i < total; i++) { + if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0) + continue; + printf(" reserving fdt memory region: addr=%llx size=%llx\n", + (unsigned long long)addr, (unsigned long long)size); + lmb_reserve(lmb, addr, size); + } +} + /** * boot_relocate_fdt - relocate flat device tree * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -1202,7 +1230,6 @@ static int fit_check_fdt (const void *fit, int fdt_noffset, int verify) * 0 - success * 1 - failure */ -#if defined(CONFIG_OF_LIBFDT) int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size) { void *fdt_blob = *of_flat_tree; diff --git a/include/image.h b/include/image.h index 8c40557314..c31e862d32 100644 --- a/include/image.h +++ b/include/image.h @@ -336,6 +336,7 @@ int boot_get_ramdisk (int argc, char * const argv[], bootm_headers_t *images, #ifdef CONFIG_OF_LIBFDT int boot_get_fdt (int flag, int argc, char * const argv[], bootm_headers_t *images, char **of_flat_tree, ulong *of_size); +void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob); int boot_relocate_fdt (struct lmb *lmb, char **of_flat_tree, ulong *of_size); #endif