[PATCH 1/1] Change the default link address for pSeries zImage kernels.

Subsystems: linux for powerpc (32-bit and 64-bit), the rest

STALE6610d

8 messages, 5 authors, 2008-07-04 · open the first message on its own page

[PATCH 1/1] Change the default link address for pSeries zImage kernels.

From: Tony Breeds <hidden>
Date: 2008-06-23 08:13:20

Currently we set the start of the .text section to be 4Mb for pSeries.
In situations where the zImage is > 8Mb we'll fail to boot (due to
overlapping with OF).  Move .text in a zImage from 4MB to 64MB (well past OF).

We still will not be able to load large zImage unless we also move OF,
to that end, add a note to the zImage ELF to move OF to 32Mb.  If this
is the very first kernel booted then we'll need to moev OF manually by
setting real-base.

Signed-off-by: Tony Breeds <redacted>
---
 arch/powerpc/boot/addnote.c         |    2 +-
 arch/powerpc/boot/oflib.c           |   15 +++++++++++++--
 arch/powerpc/boot/wrapper           |   14 ++++++++++++--
 arch/powerpc/boot/zImage.coff.lds.S |    1 -
 arch/powerpc/boot/zImage.lds.S      |    1 -
 5 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/boot/addnote.c b/arch/powerpc/boot/addnote.c
index 8041a98..b1e5611 100644
--- a/arch/powerpc/boot/addnote.c
+++ b/arch/powerpc/boot/addnote.c
@@ -25,7 +25,7 @@ char arch[] = "PowerPC";
 #define N_DESCR	6
 unsigned int descr[N_DESCR] = {
 	0xffffffff,		/* real-mode = true */
-	0x00c00000,		/* real-base, i.e. where we expect OF to be */
+	0x02000000,		/* real-base, i.e. where we expect OF to be */
 	0xffffffff,		/* real-size */
 	0xffffffff,		/* virt-base */
 	0xffffffff,		/* virt-size */
diff --git a/arch/powerpc/boot/oflib.c b/arch/powerpc/boot/oflib.c
index 95b8fd6..93a1a84 100644
--- a/arch/powerpc/boot/oflib.c
+++ b/arch/powerpc/boot/oflib.c
@@ -168,8 +168,19 @@ void *of_claim(unsigned long virt, unsigned long size, unsigned long align)
 
 void *of_vmlinux_alloc(unsigned long size)
 {
-	void *p = malloc(size);
-
+	unsigned long start = (unsigned long)_start, end = (unsigned long)_end;
+	void *addr;
+	void *p;
+
+	/* With some older POWER4 firmware the we need to claim the area
+	 * the kernel will reside in.  Newer firmwares don't need this so we
+	 * just ignore the return value.
+	 */
+	addr = of_claim(start, end - start, 0);
+	printf("Trying to claim from 0x%lx to 0x%lx (0x%lx) got %p\r\n",
+	       start, end, end - start, addr);
+
+	p = malloc(size);
 	if (!p)
 		fatal("Can't allocate memory for kernel image!\n\r");
 
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index d6c96d9..22bc26e 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -138,14 +138,20 @@ objflags=-S
 tmp=$tmpdir/zImage.$$.o
 ksection=.kernel:vmlinux.strip
 isection=.kernel:initrd
+link_address='0x400000'
 
 case "$platform" in
-pmac|pseries|chrp)
+pseries)
+    platformo=$object/of.o
+    link_address='0x4000000'
+    ;;
+pmac|chrp)
     platformo=$object/of.o
     ;;
 coff)
     platformo=$object/of.o
     lds=$object/zImage.coff.lds
+    link_address='0x500000'
     ;;
 miboot|uboot)
     # miboot and U-boot want just the bare bits, not an ELF binary
@@ -190,6 +196,7 @@ ps3)
     objflags="-O binary --set-section-flags=.bss=contents,alloc,load,data"
     ksection=.kernel:vmlinux.bin
     isection=.kernel:initrd
+    link_address=''
     ;;
 ep88xc|ep405|ep8248e)
     platformo="$object/fixed-head.o $object/$platform.o"
@@ -268,7 +275,10 @@ if [ -n "$dtb" ]; then
 fi
 
 if [ "$platform" != "miboot" ]; then
-    ${CROSS}ld -m elf32ppc -T $lds -o "$ofile" \
+    if [ -n "$link_address" ] ; then
+        text_start="-Ttext $link_address --defsym _start=$link_address"
+    fi
+    ${CROSS}ld -m elf32ppc -T $lds $text_start -o "$ofile" \
 	$platformo $tmp $object/wrapper.a
     rm $tmp
 fi
diff --git a/arch/powerpc/boot/zImage.coff.lds.S b/arch/powerpc/boot/zImage.coff.lds.S
index fe87a90..856dc78 100644
--- a/arch/powerpc/boot/zImage.coff.lds.S
+++ b/arch/powerpc/boot/zImage.coff.lds.S
@@ -3,7 +3,6 @@ ENTRY(_zimage_start_opd)
 EXTERN(_zimage_start_opd)
 SECTIONS
 {
-  . = (5*1024*1024);
   _start = .;
   .text      :
   {
diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S
index f6e380f..0962d62 100644
--- a/arch/powerpc/boot/zImage.lds.S
+++ b/arch/powerpc/boot/zImage.lds.S
@@ -3,7 +3,6 @@ ENTRY(_zimage_start)
 EXTERN(_zimage_start)
 SECTIONS
 {
-  . = (4*1024*1024);
   _start = .;
   .text      :
   {
-- 
1.5.5.4

Re: [PATCH 1/1] Change the default link address for pSeries zImage kernels.

From: Tony Breeds <hidden>
Date: 2008-06-23 08:16:46

On Mon, Jun 23, 2008 at 06:13:23PM +1000, Tony Breeds wrote:
Currently we set the start of the .text section to be 4Mb for pSeries.
In situations where the zImage is > 8Mb we'll fail to boot (due to
overlapping with OF).  Move .text in a zImage from 4MB to 64MB (well past OF).

We still will not be able to load large zImage unless we also move OF,
to that end, add a note to the zImage ELF to move OF to 32Mb.  If this
is the very first kernel booted then we'll need to moev OF manually by
setting real-base.

Signed-off-by: Tony Breeds <redacted>
---
Ooops should have said that this has been boot tested on power
3,4,5,5+,6 and JS20.  POWER4 firmware seems to have aproblem manually
reloacting realbase but asside from that it booted.

Yours Tony

  linux.conf.au    http://www.marchsouth.org/
  Jan 19 - 24 2009 The Australian Linux Technical Conference!

Re: [PATCH 1/1] Change the default link address for pSeries zImage kernels.

From: Adrian Reber <hidden>
Date: 2008-06-23 09:36:23

On Mon, Jun 23, 2008 at 06:13:23PM +1000, Tony Breeds wrote:
Currently we set the start of the .text section to be 4Mb for pSeries.
In situations where the zImage is > 8Mb we'll fail to boot (due to
overlapping with OF).  Move .text in a zImage from 4MB to 64MB (well past OF).

We still will not be able to load large zImage unless we also move OF,
to that end, add a note to the zImage ELF to move OF to 32Mb.  If this
is the very first kernel booted then we'll need to moev OF manually by
setting real-base.
Does this change also affect kernels for SLOF based systems (JS20, JS21,
Bimini/Powerstation, QS21, QS22)?

To avoid exactly that problem SLOF moved to a bit below 256MB on all
those platforms (about 220MB). There should be still enough space
between 64MB and 220MB to boot large kernels. It is, however, decreased
by 60MB.

		Adrian

Re: [PATCH 1/1] Change the default link address for pSeries zImage kernels.

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: 2008-06-23 09:57:51

On Mon, 2008-06-23 at 11:30 +0200, Adrian Reber wrote:
On Mon, Jun 23, 2008 at 06:13:23PM +1000, Tony Breeds wrote:
quoted
Currently we set the start of the .text section to be 4Mb for pSeries.
In situations where the zImage is > 8Mb we'll fail to boot (due to
overlapping with OF).  Move .text in a zImage from 4MB to 64MB (well past OF).

We still will not be able to load large zImage unless we also move OF,
to that end, add a note to the zImage ELF to move OF to 32Mb.  If this
is the very first kernel booted then we'll need to moev OF manually by
setting real-base.
Does this change also affect kernels for SLOF based systems (JS20, JS21,
Bimini/Powerstation, QS21, QS22)?
Yes, they use the same zImage.
To avoid exactly that problem SLOF moved to a bit below 256MB on all
those platforms (about 220MB). There should be still enough space
between 64MB and 220MB to boot large kernels. It is, however, decreased
by 60MB.
That should leave plenty of space...

Cheers,
Ben.

Re: [PATCH 1/1] Change the default link address for pSeries zImage kernels.

From: Michael Ellerman <hidden>
Date: 2008-06-23 12:20:37

On Mon, 2008-06-23 at 18:13 +1000, Tony Breeds wrote:
Currently we set the start of the .text section to be 4Mb for pSeries.
In situations where the zImage is > 8Mb we'll fail to boot (due to
overlapping with OF).  Move .text in a zImage from 4MB to 64MB (well past OF).
...
quoted hunk
diff --git a/arch/powerpc/boot/oflib.c b/arch/powerpc/boot/oflib.c
index 95b8fd6..93a1a84 100644
--- a/arch/powerpc/boot/oflib.c
+++ b/arch/powerpc/boot/oflib.c
@@ -168,8 +168,19 @@ void *of_claim(unsigned long virt, unsigned long size, unsigned long align)
 
 void *of_vmlinux_alloc(unsigned long size)
 {
-	void *p = malloc(size);
-
+	unsigned long start = (unsigned long)_start, end = (unsigned long)_end;
+	void *addr;
+	void *p;
+
+	/* With some older POWER4 firmware the we need to claim the area
Sorry, typo/grammaro :/                     ^^^^^^

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[PATCH v2] Change the default link address for pSeries zImage kernels.

From: Tony Breeds <hidden>
Date: 2008-06-24 04:20:26

Currently we set the start of the .text section to be 4Mb for pSeries.
In situations where the zImage is > 8Mb we'll fail to boot (due to
overlapping with OF).  Move .text in a zImage from 4MB to 64MB (well past OF).

We still will not be able to load large zImage unless we also move OF,
to that end, add a note to the zImage ELF to move OF to 32Mb.  If this
is the very first kernel booted then we'll need to move OF manually by
setting real-base.

Signed-off-by: Tony Breeds <redacted>
---
Booted on:
	3,4,5,5+,6,JS20 and JS21 (running slof 1.7.0-1)
Changes since v1:
	typo fixes in commit message and comments

 arch/powerpc/boot/addnote.c         |    2 +-
 arch/powerpc/boot/oflib.c           |   15 +++++++++++++--
 arch/powerpc/boot/wrapper           |   14 ++++++++++++--
 arch/powerpc/boot/zImage.coff.lds.S |    1 -
 arch/powerpc/boot/zImage.lds.S      |    1 -
 5 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/boot/addnote.c b/arch/powerpc/boot/addnote.c
index 8041a98..b1e5611 100644
--- a/arch/powerpc/boot/addnote.c
+++ b/arch/powerpc/boot/addnote.c
@@ -25,7 +25,7 @@ char arch[] = "PowerPC";
 #define N_DESCR	6
 unsigned int descr[N_DESCR] = {
 	0xffffffff,		/* real-mode = true */
-	0x00c00000,		/* real-base, i.e. where we expect OF to be */
+	0x02000000,		/* real-base, i.e. where we expect OF to be */
 	0xffffffff,		/* real-size */
 	0xffffffff,		/* virt-base */
 	0xffffffff,		/* virt-size */
diff --git a/arch/powerpc/boot/oflib.c b/arch/powerpc/boot/oflib.c
index 95b8fd6..b0ec9cf 100644
--- a/arch/powerpc/boot/oflib.c
+++ b/arch/powerpc/boot/oflib.c
@@ -168,8 +168,19 @@ void *of_claim(unsigned long virt, unsigned long size, unsigned long align)
 
 void *of_vmlinux_alloc(unsigned long size)
 {
-	void *p = malloc(size);
-
+	unsigned long start = (unsigned long)_start, end = (unsigned long)_end;
+	void *addr;
+	void *p;
+
+	/* With some older POWER4 firmware we need to claim the area the kernel
+	 * will reside in.  Newer firmwares don't need this so we just ignore
+	 * the return value.
+	 */
+	addr = of_claim(start, end - start, 0);
+	printf("Trying to claim from 0x%lx to 0x%lx (0x%lx) got %p\r\n",
+	       start, end, end - start, addr);
+
+	p = malloc(size);
 	if (!p)
 		fatal("Can't allocate memory for kernel image!\n\r");
 
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index d6c96d9..22bc26e 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -138,14 +138,20 @@ objflags=-S
 tmp=$tmpdir/zImage.$$.o
 ksection=.kernel:vmlinux.strip
 isection=.kernel:initrd
+link_address='0x400000'
 
 case "$platform" in
-pmac|pseries|chrp)
+pseries)
+    platformo=$object/of.o
+    link_address='0x4000000'
+    ;;
+pmac|chrp)
     platformo=$object/of.o
     ;;
 coff)
     platformo=$object/of.o
     lds=$object/zImage.coff.lds
+    link_address='0x500000'
     ;;
 miboot|uboot)
     # miboot and U-boot want just the bare bits, not an ELF binary
@@ -190,6 +196,7 @@ ps3)
     objflags="-O binary --set-section-flags=.bss=contents,alloc,load,data"
     ksection=.kernel:vmlinux.bin
     isection=.kernel:initrd
+    link_address=''
     ;;
 ep88xc|ep405|ep8248e)
     platformo="$object/fixed-head.o $object/$platform.o"
@@ -268,7 +275,10 @@ if [ -n "$dtb" ]; then
 fi
 
 if [ "$platform" != "miboot" ]; then
-    ${CROSS}ld -m elf32ppc -T $lds -o "$ofile" \
+    if [ -n "$link_address" ] ; then
+        text_start="-Ttext $link_address --defsym _start=$link_address"
+    fi
+    ${CROSS}ld -m elf32ppc -T $lds $text_start -o "$ofile" \
 	$platformo $tmp $object/wrapper.a
     rm $tmp
 fi
diff --git a/arch/powerpc/boot/zImage.coff.lds.S b/arch/powerpc/boot/zImage.coff.lds.S
index fe87a90..856dc78 100644
--- a/arch/powerpc/boot/zImage.coff.lds.S
+++ b/arch/powerpc/boot/zImage.coff.lds.S
@@ -3,7 +3,6 @@ ENTRY(_zimage_start_opd)
 EXTERN(_zimage_start_opd)
 SECTIONS
 {
-  . = (5*1024*1024);
   _start = .;
   .text      :
   {
diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S
index f6e380f..0962d62 100644
--- a/arch/powerpc/boot/zImage.lds.S
+++ b/arch/powerpc/boot/zImage.lds.S
@@ -3,7 +3,6 @@ ENTRY(_zimage_start)
 EXTERN(_zimage_start)
 SECTIONS
 {
-  . = (4*1024*1024);
   _start = .;
   .text      :
   {
-- 
1.5.5.4

Re: [PATCH v2] Change the default link address for pSeries zImage kernels.

From: Olaf Hering <hidden>
Date: 2008-07-02 15:04:35

On Tue, Jun 24, Tony Breeds wrote:
Currently we set the start of the .text section to be 4Mb for pSeries.
In situations where the zImage is > 8Mb we'll fail to boot (due to
overlapping with OF).  Move .text in a zImage from 4MB to 64MB (well past OF).

We still will not be able to load large zImage unless we also move OF,
to that end, add a note to the zImage ELF to move OF to 32Mb.  If this
is the very first kernel booted then we'll need to move OF manually by
setting real-base.
Setting real-base to what?

What currently happens with a large boot file is:
Firmware loads the zImage at load-base, finds that the ELF file is too
large to fit into the memory window and stops.

With your patch, firmware loads 12566528 bytes, and starts the zImage.
The result is a truncated file, the initrd will be corrupted, kernel
panic in populate_rootfs().

The only system where firmware relocates itself from 12MB to 32MB is a
p640 with firmware version NAN04194.
All other systems seem to ignore the NOTE section, real-base remains at
0xc00000

So I do not think your patch is a real improvement,
clear error vs. silent corruption.

Do you happen to know how to automate the changing the value of
real-base? The addnote change has appearently no effect on recent
systems.

Olaf

Re: [PATCH v2] Change the default link address for pSeries zImage kernels.

From: Tony Breeds <hidden>
Date: 2008-07-04 03:14:50

On Wed, Jul 02, 2008 at 05:04:32PM +0200, Olaf Hering wrote:
 
Setting real-base to what?
32Mb, or any other value big enough to allow the tftp to fit in
${real-base} - ${load-base}.  I admitt it's far from ideal.
 
What currently happens with a large boot file is:
Firmware loads the zImage at load-base, finds that the ELF file is too
large to fit into the memory window and stops.

With your patch, firmware loads 12566528 bytes, and starts the zImage.
The result is a truncated file, the initrd will be corrupted, kernel
panic in populate_rootfs().
Okay that's not the behaviour I see here on the POWER4 machines, they
grab the firt n bytes (probabbly 12566528), and then abort with a
message about image being too large and it cannot be split.
(something akin to https://bugzilla.novell.com/show_bug.cgi?id=350212 )
 
The only system where firmware relocates itself from 12MB to 32MB is a
p640 with firmware version NAN04194.
All other systems seem to ignore the NOTE section, real-base remains at
0xc00000
Add I thought /all/ POWER4 systems were unable to relocate OF
(regardless of whether the request is from the NOTE or from set-env
real-base).
 
So I do not think your patch is a real improvement,
clear error vs. silent corruption.

Do you happen to know how to automate the changing the value of
real-base? The addnote change has appearently no effect on recent
systems.
It's there for POWER5 and on.  I was sure that no POWER4 machines could
be reloacted, but you say that your p640 can.

Yours Tony

  linux.conf.au    http://www.marchsouth.org/
  Jan 19 - 24 2009 The Australian Linux Technical Conference!
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help