All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/2] rpi: Change load addresses to make more room for the kernel
@ 2017-06-19 11:08 Tuomas Tynkkynen
  2017-06-19 11:08 ` [U-Boot] [PATCH 2/2] rpi: Fix fdt_high & initrd_high for 64-bit builds Tuomas Tynkkynen
  2017-06-19 12:28 ` [U-Boot] [PATCH 1/2] rpi: Change load addresses to make more room for the kernel Tom Rini
  0 siblings, 2 replies; 3+ messages in thread
From: Tuomas Tynkkynen @ 2017-06-19 11:08 UTC (permalink / raw)
  To: u-boot

According to the comment in rpi.h, the current kernel load address is
picked such that the compressed kernel and the uncompressed kernel don't
overlap in memory to avoid unnecessary relocation of the compressed
image in the decompressor stub. However, as is evident from the
kernel boot log snipped below, a full-blown ARMv7 distro kernel
(v4.11.3) can use as much as 17063 kB uncompressed. That is larger
than the current 16M reservation which means that the relocation
indeed is happening.

[    0.000000] Virtual kernel memory layout:
                 .text : 0xc0208000 - 0xc0f00000   (13280 kB)
                 .init : 0xc1500000 - 0xc1700000   (2048 kB)
                 .data : 0xc1700000 - 0xc18b1978   (1735 kB)

Additionally, on AArch64 the kernel images are much larger than
on ARM. A full-blown 4.11.3 distro kernel takes 24M, which with the
current load addresses (reserving only 17M) stomps over the initrd,
breaking the boot of such large kernels.

Fix both of these problems by tweaking the load addresses as appropriate
depending on the CPU architecture. To make things simpler, pxefile_addr_r
is moved from low memory next to scriptaddr.

After this patch we end up with this memory map on ARM (assuming the
most conservative CPU-GPU memory split of 128M for the CPU):
0x00000100 - 0x00008000 (    31 kB): fdt_addr_r - decompressed_kernel_start
0x00008000 - 0x03000000 ( 49120 kB): decompressed_kernel - kernel_addr_r
0x03000000 - 0x04000000 ( 16384 kB): kernel_addr_r - scriptaddr
0x04000000 - 0x04100000 (  1024 kB): scriptaddr - pxefile_addr_r
0x04100000 - 0x04200000 (  1024 kB): pxefile_addr_r - ramdisk_addr_r
0x04200000 - 0x08000000 ( 63488 kB): ramdisk_addr_r - top_of_ram

And this for AArch64:
0x00000100 - 0x00080000 (   511 kB): fdt_addr_r - kernel_addr_r
0x00080000 - 0x04000000 ( 65024 kB): kernel_addr_r - scriptaddr
0x04000000 - 0x04100000 (  1024 kB): scriptaddr - pxefile_addr_r
0x04100000 - 0x04200000 (  1024 kB): pxefile_addr_r - ramdisk_addr_r
0x04200000 - 0x08000000 ( 63488 kB): ramdisk_addr_r - top_of_ram

Signed-off-by: Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
---
This has been tested on:
 - RPi 1 booting the RPi Foundation downstream kernel
 - RPi 3 booting a distro multi_v7_defconfig in 32-bit mode
 - RPi 3 booting a AArch64 distro defconfig in 64-bit mode
---
 include/configs/rpi.h | 36 +++++++++++++++++++++++++-----------
 1 file changed, 25 insertions(+), 11 deletions(-)

diff --git a/include/configs/rpi.h b/include/configs/rpi.h
index d715eaad14..a2d82a9146 100644
--- a/include/configs/rpi.h
+++ b/include/configs/rpi.h
@@ -131,32 +131,46 @@
  *   U-Boot (and scripts it executes) typicaly ignore the DT loaded by the FW
  *   and loads its own DT from disk (triggered by boot.scr or extlinux.conf).
  *
- * pxefile_addr_r can be pretty much anywhere that doesn't conflict with
- *   something else. Put it low in memory to avoid conflicts.
+ * kernel_addr_r has different constraints on ARM and Aarch64.
+ *   For Aarch64, the kernel image is uncompressed and must be loaded at
+ *   text_offset bytes (specified in the header of the Image) into a
+ *   2MB boundary. As Linux uses a default text_offset of 0x80000, load
+ *   the kernel at 0x80000 so that the 'booti' command does not need
+ *   to perform any relocation of the Image in the typical case.
  *
- * kernel_addr_r must be within the first 128M of RAM in order for the
+ *   For 32-bit ARM, it must be within the first 128M of RAM in order for the
  *   kernel's CONFIG_AUTO_ZRELADDR option to work. Since the kernel will
  *   decompress itself to 0x8000 after the start of RAM, kernel_addr_r
  *   should not overlap that area, or the kernel will have to copy itself
  *   somewhere else before decompression. Similarly, the address of any other
  *   data passed to the kernel shouldn't overlap the start of RAM. Pushing
- *   this up to 16M allows for a sizable kernel to be decompressed below the
+ *   this up to 48M allows for a sizable kernel to be decompressed below the
  *   compressed load address.
  *
  * scriptaddr can be pretty much anywhere that doesn't conflict with something
- *   else. Choosing 32M allows for the compressed kernel to be up to 16M.
+ *   else. Choosing 64M allows for the compressed kernel to be up to 16M on
+ *   32-bit ARM and roughly 64M for the uncompressed kernel on Aarch64.
+ *
+ * pxefile_addr_r can be pretty much anywhere that doesn't conflict with
+ *   something else. Choosing 65M allows for any boot script to be up to 1M,
+ *   which is hopefully plenty.
  *
- * ramdisk_addr_r simply shouldn't overlap anything else. Choosing 33M allows
- *   for any boot script to be up to 1M, which is hopefully plenty.
+ * ramdisk_addr_r simply shouldn't overlap anything else. Choosing 66M allows
+ *   for any PXE configuration file to be up to 1M, which is hopefully plenty.
  */
+#ifdef CONFIG_ARM64
+# define KERNEL_ADDR_R "0x00080000"
+#else
+# define KERNEL_ADDR_R "0x03000000"
+#endif
 #define ENV_MEM_LAYOUT_SETTINGS \
 	"fdt_high=ffffffff\0" \
 	"initrd_high=ffffffff\0" \
 	"fdt_addr_r=0x00000100\0" \
-	"pxefile_addr_r=0x00100000\0" \
-	"kernel_addr_r=0x01000000\0" \
-	"scriptaddr=0x02000000\0" \
-	"ramdisk_addr_r=0x02100000\0" \
+	"kernel_addr_r=" KERNEL_ADDR_R "\0" \
+	"scriptaddr=0x04000000\0" \
+	"pxefile_addr_r=0x04100000\0" \
+	"ramdisk_addr_r=0x04200000\0" \
 
 #define BOOT_TARGET_DEVICES(func) \
 	func(MMC, mmc, 0) \
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [U-Boot] [PATCH 2/2] rpi: Fix fdt_high & initrd_high for 64-bit builds
  2017-06-19 11:08 [U-Boot] [PATCH 1/2] rpi: Change load addresses to make more room for the kernel Tuomas Tynkkynen
@ 2017-06-19 11:08 ` Tuomas Tynkkynen
  2017-06-19 12:28 ` [U-Boot] [PATCH 1/2] rpi: Change load addresses to make more room for the kernel Tom Rini
  1 sibling, 0 replies; 3+ messages in thread
From: Tuomas Tynkkynen @ 2017-06-19 11:08 UTC (permalink / raw)
  To: u-boot

The magic value that disables relocation is dependent on the CPU word
size, so the current 'ffffffff' is doing the wrong thing on aarch64.

Signed-off-by: Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
---
These two patches aren't really related except for touching the same
parts of the code, I just noticed this by coincidence. For me there's no
visible effects with this patch.

Instead of spreading this #ifdef pattern further,
http://patchwork.ozlabs.org/patch/716487/ would be a cleaner way of
solving this...
---
 include/configs/rpi.h | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/include/configs/rpi.h b/include/configs/rpi.h
index a2d82a9146..153b2463a7 100644
--- a/include/configs/rpi.h
+++ b/include/configs/rpi.h
@@ -119,6 +119,14 @@
 	"stdout=serial,vidconsole\0" \
 	"stderr=serial,vidconsole\0"
 
+#ifdef CONFIG_ARM64
+#define FDT_HIGH "ffffffffffffffff"
+#define INITRD_HIGH "ffffffffffffffff"
+#else
+#define FDT_HIGH "ffffffff"
+#define INITRD_HIGH "ffffffff"
+#endif
+
 /*
  * Memory layout for where various images get loaded by boot scripts:
  *
@@ -164,8 +172,8 @@
 # define KERNEL_ADDR_R "0x03000000"
 #endif
 #define ENV_MEM_LAYOUT_SETTINGS \
-	"fdt_high=ffffffff\0" \
-	"initrd_high=ffffffff\0" \
+	"fdt_high=" FDT_HIGH "\0" \
+	"initrd_high=" INITRD_HIGH "\0" \
 	"fdt_addr_r=0x00000100\0" \
 	"kernel_addr_r=" KERNEL_ADDR_R "\0" \
 	"scriptaddr=0x04000000\0" \
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [U-Boot] [PATCH 1/2] rpi: Change load addresses to make more room for the kernel
  2017-06-19 11:08 [U-Boot] [PATCH 1/2] rpi: Change load addresses to make more room for the kernel Tuomas Tynkkynen
  2017-06-19 11:08 ` [U-Boot] [PATCH 2/2] rpi: Fix fdt_high & initrd_high for 64-bit builds Tuomas Tynkkynen
@ 2017-06-19 12:28 ` Tom Rini
  1 sibling, 0 replies; 3+ messages in thread
From: Tom Rini @ 2017-06-19 12:28 UTC (permalink / raw)
  To: u-boot

On Mon, Jun 19, 2017 at 02:08:03PM +0300, Tuomas Tynkkynen wrote:
> According to the comment in rpi.h, the current kernel load address is
> picked such that the compressed kernel and the uncompressed kernel don't
> overlap in memory to avoid unnecessary relocation of the compressed
> image in the decompressor stub. However, as is evident from the
> kernel boot log snipped below, a full-blown ARMv7 distro kernel
> (v4.11.3) can use as much as 17063 kB uncompressed. That is larger
> than the current 16M reservation which means that the relocation
> indeed is happening.
> 
> [    0.000000] Virtual kernel memory layout:
>                  .text : 0xc0208000 - 0xc0f00000   (13280 kB)
>                  .init : 0xc1500000 - 0xc1700000   (2048 kB)
>                  .data : 0xc1700000 - 0xc18b1978   (1735 kB)
> 
> Additionally, on AArch64 the kernel images are much larger than
> on ARM. A full-blown 4.11.3 distro kernel takes 24M, which with the
> current load addresses (reserving only 17M) stomps over the initrd,
> breaking the boot of such large kernels.
> 
> Fix both of these problems by tweaking the load addresses as appropriate
> depending on the CPU architecture. To make things simpler, pxefile_addr_r
> is moved from low memory next to scriptaddr.
> 
> After this patch we end up with this memory map on ARM (assuming the
> most conservative CPU-GPU memory split of 128M for the CPU):
> 0x00000100 - 0x00008000 (    31 kB): fdt_addr_r - decompressed_kernel_start
> 0x00008000 - 0x03000000 ( 49120 kB): decompressed_kernel - kernel_addr_r
> 0x03000000 - 0x04000000 ( 16384 kB): kernel_addr_r - scriptaddr
> 0x04000000 - 0x04100000 (  1024 kB): scriptaddr - pxefile_addr_r
> 0x04100000 - 0x04200000 (  1024 kB): pxefile_addr_r - ramdisk_addr_r
> 0x04200000 - 0x08000000 ( 63488 kB): ramdisk_addr_r - top_of_ram
> 
> And this for AArch64:
> 0x00000100 - 0x00080000 (   511 kB): fdt_addr_r - kernel_addr_r
> 0x00080000 - 0x04000000 ( 65024 kB): kernel_addr_r - scriptaddr
> 0x04000000 - 0x04100000 (  1024 kB): scriptaddr - pxefile_addr_r
> 0x04100000 - 0x04200000 (  1024 kB): pxefile_addr_r - ramdisk_addr_r
> 0x04200000 - 0x08000000 ( 63488 kB): ramdisk_addr_r - top_of_ram
> 
> Signed-off-by: Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
> ---
> This has been tested on:
>  - RPi 1 booting the RPi Foundation downstream kernel
>  - RPi 3 booting a distro multi_v7_defconfig in 32-bit mode
>  - RPi 3 booting a AArch64 distro defconfig in 64-bit mode

Can we try using bootm_size instead so that things are relocated
appropriately?  See DEFAULT_LINUX_BOOT_ENV in
include/configs/ti_armv7_common.h (and then Documentation/arm/Booting
and Documentation/arm64/booting.txt in the kernel).  Thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170619/cfbe3ae3/attachment.sig>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-06-19 12:28 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-19 11:08 [U-Boot] [PATCH 1/2] rpi: Change load addresses to make more room for the kernel Tuomas Tynkkynen
2017-06-19 11:08 ` [U-Boot] [PATCH 2/2] rpi: Fix fdt_high & initrd_high for 64-bit builds Tuomas Tynkkynen
2017-06-19 12:28 ` [U-Boot] [PATCH 1/2] rpi: Change load addresses to make more room for the kernel Tom Rini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.