Reserve any memory above 768MB to prevent u-boot from relocating fdt or initrd data into memory that Linux cannot reference during early boot. Code taken (with modifications) from the powerpc bootm.c.
Signed-off-by: David A. Long dave.long@linaro.org --- arch/arm/lib/bootm.c | 24 +++++++++++++++++++++++- 1 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 802e833..437ef35 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -32,6 +32,10 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifndef CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE +#define CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE (768*1024*1024) +#endif + #if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ defined (CONFIG_INITRD_TAG) || \ @@ -60,7 +64,25 @@ static int bootm_linux_fdt(int machid, bootm_headers_t *images);
void arch_lmb_reserve(struct lmb *lmb) { - ulong sp; + phys_size_t bootm_size; + ulong size, sp, bootmap_base; + + bootmap_base = getenv_bootm_low(); + bootm_size = getenv_bootm_size(); + +#ifdef DEBUG + if (((u64)bootmap_base + bootm_size) > + (CONFIG_SYS_SDRAM_BASE + (u64) gd->ram_size)) + puts("WARNING: bootm_low + bootm_size exceed total memory\n"); +#endif + + size = min(bootm_size, CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE); + + if (size < bootm_size) { + ulong base = bootmap_base + size; + printf("WARNING: adjusting available memory to %lx\n", size); + lmb_reserve(lmb, base, bootm_size - size); + }
/* * Booting a (Linux) kernel image
Hi David,
Le 19/08/2011 19:57, David Long a écrit :
Reserve any memory above 768MB to prevent u-boot from relocating fdt or initrd data into memory that Linux cannot reference during early boot. Code taken (with modifications) from the powerpc bootm.c.
What exactly prevents ARM Linux from booting when FDT or initrd are above 768MB? Can this limitation not be lifter on the Linux side?
Also:
Signed-off-by: David A. Longdave.long@linaro.org
arch/arm/lib/bootm.c | 24 +++++++++++++++++++++++- 1 files changed, 23 insertions(+), 1 deletions(-)
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 802e833..437ef35 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -32,6 +32,10 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifndef CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE +#define CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE (768*1024*1024) +#endif
I'd tend to think that if no max size was defined, then we should not limit.
- #if defined (CONFIG_SETUP_MEMORY_TAGS) || \ defined (CONFIG_CMDLINE_TAG) || \ defined (CONFIG_INITRD_TAG) || \
@@ -60,7 +64,25 @@ static int bootm_linux_fdt(int machid, bootm_headers_t *images);
void arch_lmb_reserve(struct lmb *lmb) {
- ulong sp;
- phys_size_t bootm_size;
- ulong size, sp, bootmap_base;
- bootmap_base = getenv_bootm_low();
- bootm_size = getenv_bootm_size();
+#ifdef DEBUG
- if (((u64)bootmap_base + bootm_size)>
(CONFIG_SYS_SDRAM_BASE + (u64) gd->ram_size))
puts("WARNING: bootm_low + bootm_size exceed total memory\n");
+#endif
size = min(bootm_size, CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE);
if (size< bootm_size) {
ulong base = bootmap_base + size;
printf("WARNING: adjusting available memory to %lx\n", size);
lmb_reserve(lmb, base, bootm_size - size);
}
/*
- Booting a (Linux) kernel image
Amicalement,
On Sat, 2011-08-20 at 08:01 +0200, Albert ARIBAUD wrote:
What exactly prevents ARM Linux from booting when FDT or initrd are above 768MB? Can this limitation not be lifter on the Linux side?
I don't think it reasonably can be.
I have to start by saying that I am in no way a Linux VM expert. But...
With Linux HIGHMEM configured the last 1/4GB of the kernel virtual address space is reserved for a few things, including explicitly mapping in parts of the last 1/4GB of physical memory as needed. I just don't think the VM subsystem is initialized enough to do this remapping so early, even if one wanted to make the calls. Indeed, I don't see how it could be initialized this early since the FDT can contain information about physical memory.
Some other platforms limit u-boot to accessing the first 8MB of RAM using CONFIG_SYS_BOOTMAPSZ, but that resulted in a failure to boot in my test. I did not chase down exactly why that approach failed.
+#ifndef CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE +#define CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE (768*1024*1024) +#endif
I'd tend to think that if no max size was defined, then we should not limit.
I was just going with the example already in place for powerpc. I'm reluctant to change this without having more background on why it's this way now.
-dl