Patchwork [U-Boot,u-boot] arm, lib/bootm.c: Exclude HIGHMEM from being used by u-boot

login
register
mail settings
Submitter David A. Long
Date Aug. 19, 2011, 5:57 p.m.
Message ID <1313776646.21313.6.camel@dave-Dell-System-XPS-L502X>
Download mbox | patch
Permalink /patch/110710/
State Rejected
Delegated to: Albert ARIBAUD
Headers show

Comments

David A. Long - Aug. 19, 2011, 5:57 p.m.
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(-)
Albert ARIBAUD - Aug. 20, 2011, 6:01 a.m.
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. 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

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,
David A. Long - Aug. 20, 2011, 8:39 p.m.
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

Patch

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