Skip to contentSkip to conversation

arm, lib/bootm.c: Exclude HIGHMEM from being used by u-boot

PATCH New David Long 2 participants 3 messages Aug 19, 2011 – Aug 20, 2011 Arm (32-bit)

lore
Share & tools
lore

David Long

author
#0 lore raw

PATCH 1/1 arm, lib/bootm.c: Exclude HIGHMEM from being used by u-boot

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.

---
 arch/arm/lib/bootm.c |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)
arch/arm/lib/bootm.c +23 -1
index 802e833..437ef35 100644
@@ -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
Signature · 1 line
1.7.4.1
#1 lore raw

PATCH 1/1 arm, lib/bootm.c: Exclude HIGHMEM from being used by u-boot

Hi David,

Le 19/08/2011 19:57, David Long a ?crit :

Quoted 4 lines

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:

Quoted 10 lines
---
  arch/arm/lib/bootm.c |   24 +++++++++++++++++++++++-
  1 files changed, 23 insertions(+), 1 deletions(-)
arch/arm/lib/bootm.c +0 -0
index 802e833..437ef35 100644

arch/arm/lib/bootm.c line 37

Quoted 6 lines
arch/arm/lib/bootm.c +3 -0
@@ -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.

Quoted 21 lines
arch/arm/lib/bootm.c +13 -1
+
  #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
+

arch/arm/lib/bootm.c static int bootm_linux_fdt(int machid, bootm_headers_t *images); · line 88

Quoted 10 lines
arch/arm/lib/bootm.c +7 -0
+	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,

Signature · 1 line
Albert.
author
#2 lore raw

PATCH 1/1 arm, lib/bootm.c: Exclude HIGHMEM from being used by u-boot

Quoted 2 lines · Albert ARIBAUD

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.

Quoted 6 lines

arch/arm/lib/bootm.c line 37

Quoted 4 lines
arch/arm/lib/bootm.c +3 -0
+#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