2010-08-25 15:57:24

by Michael Holzheu

[permalink] [raw]
Subject: [PATCH] Fix initramfs size calculation

The size of a built-in initramfs is calculated in init/initramfs.c by
"__initramfs_end - __initramfs_start". Those symbols are defined in the
linker script include/asm-generic/vmlinux.lds.h:

#define INIT_RAM_FS \
. = ALIGN(PAGE_SIZE); \
VMLINUX_SYMBOL(__initramfs_start) = .; \
*(.init.ramfs) \
VMLINUX_SYMBOL(__initramfs_end) = .;

If the initramfs file has an odd number of bytes, the "__initramfs_end"
symbol points to an odd address, for example, the symbols in the System.map
might look like:

0000000000572000 T __initramfs_start
00000000005bcd05 T __initramfs_end <-- odd address

At least on s390 this is a problem:

Certain s390 instructions, especially instructions for loading addresses
(larl) or branch addresses must be on even addresses.
The compiler loads the symbol addresses with the "larl". This instruction sets the
last bit to 0, therefore, for odd size files, the calculated size is one byte
less than it should be:

0000000000540a9c <populate_rootfs>:
540a9c: eb cf f0 78 00 24 stmg %r12,%r15,120(%r15),
540aa2: c0 10 00 01 8a af larl %r1,572000 <__initramfs_start>
540aa8: c0 c0 00 03 e1 2e larl %r12,5bcd04 <initramfs_end>
(Instead of 5bcd05)
...
540abe: 1b c1 sr %r12,%r1

To fix the problem, this patch introduces the global variable
__initramfs_size, which is calculated in the "usr/initramfs_data.xxx.S" files.
The populate_rootfs() function can then use the init.ramfs section start and
the value of __initramfs_size for loading the initramfs.

The patch also restructures the "usr/initramfs_data.xxx.S" files to use a
common macro that includes the (compressed) initramfs file and calculates
the __initramfs_size.

Signed-off-by: Michael Holzheu <[email protected]>
---
include/asm-generic/vmlinux.lds.h | 3 +-
init/initramfs.c | 9 +++-----
usr/initramfs_data.S | 32 +---------------------------
usr/initramfs_data.bz2.S | 31 +---------------------------
usr/initramfs_data.gz.S | 31 +---------------------------
usr/initramfs_data.h | 42 ++++++++++++++++++++++++++++++++++++++
usr/initramfs_data.lzma.S | 31 +---------------------------
7 files changed, 56 insertions(+), 123 deletions(-)

--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -629,7 +629,8 @@
. = ALIGN(PAGE_SIZE); \
VMLINUX_SYMBOL(__initramfs_start) = .; \
*(.init.ramfs) \
- VMLINUX_SYMBOL(__initramfs_end) = .;
+ . = ALIGN(8); \
+ *(.init.ramfs.info)
#else
#define INIT_RAM_FS
#endif
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -483,7 +483,8 @@ static int __init retain_initrd_param(ch
}
__setup("retain_initrd", retain_initrd_param);

-extern char __initramfs_start[], __initramfs_end[];
+extern char __initramfs_start[];
+extern unsigned long __initramfs_size;
#include <linux/initrd.h>
#include <linux/kexec.h>

@@ -570,8 +571,7 @@ static void __init clean_rootfs(void)

static int __init populate_rootfs(void)
{
- char *err = unpack_to_rootfs(__initramfs_start,
- __initramfs_end - __initramfs_start);
+ char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
if (err)
panic(err); /* Failed to decompress INTERNAL initramfs */
if (initrd_start) {
@@ -585,8 +585,7 @@ static int __init populate_rootfs(void)
return 0;
} else {
clean_rootfs();
- unpack_to_rootfs(__initramfs_start,
- __initramfs_end - __initramfs_start);
+ unpack_to_rootfs(__initramfs_start, __initramfs_size);
}
printk(KERN_INFO "rootfs image is not initramfs (%s)"
"; looks like an initrd\n", err);
--- a/usr/initramfs_data.S
+++ b/usr/initramfs_data.S
@@ -1,30 +1,2 @@
-/*
- initramfs_data includes the compressed binary that is the
- filesystem used for early user space.
- Note: Older versions of "as" (prior to binutils 2.11.90.0.23
- released on 2001-07-14) dit not support .incbin.
- If you are forced to use older binutils than that then the
- following trick can be applied to create the resulting binary:
-
-
- ld -m elf_i386 --format binary --oformat elf32-i386 -r \
- -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
- ld -m elf_i386 -r -o built-in.o initramfs_data.o
-
- initramfs_data.scr looks like this:
-SECTIONS
-{
- .init.ramfs : { *(.data) }
-}
-
- The above example is for i386 - the parameters vary from architectures.
- Eventually look up LDFLAGS_BLOB in an older version of the
- arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
-
- Using .incbin has the advantage over ld that the correct flags are set
- in the ELF header, as required by certain architectures.
-*/
-
-.section .init.ramfs,"a"
-.incbin "usr/initramfs_data.cpio"
-
+#include "initramfs_data.h"
+initramfs_inc "usr/initramfs_data.cpio";
--- a/usr/initramfs_data.bz2.S
+++ b/usr/initramfs_data.bz2.S
@@ -1,29 +1,2 @@
-/*
- initramfs_data includes the compressed binary that is the
- filesystem used for early user space.
- Note: Older versions of "as" (prior to binutils 2.11.90.0.23
- released on 2001-07-14) dit not support .incbin.
- If you are forced to use older binutils than that then the
- following trick can be applied to create the resulting binary:
-
-
- ld -m elf_i386 --format binary --oformat elf32-i386 -r \
- -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
- ld -m elf_i386 -r -o built-in.o initramfs_data.o
-
- initramfs_data.scr looks like this:
-SECTIONS
-{
- .init.ramfs : { *(.data) }
-}
-
- The above example is for i386 - the parameters vary from architectures.
- Eventually look up LDFLAGS_BLOB in an older version of the
- arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
-
- Using .incbin has the advantage over ld that the correct flags are set
- in the ELF header, as required by certain architectures.
-*/
-
-.section .init.ramfs,"a"
-.incbin "usr/initramfs_data.cpio.bz2"
+#include "initramfs_data.h"
+initramfs_inc "usr/initramfs_data.cpio.bz2";
--- a/usr/initramfs_data.gz.S
+++ b/usr/initramfs_data.gz.S
@@ -1,29 +1,2 @@
-/*
- initramfs_data includes the compressed binary that is the
- filesystem used for early user space.
- Note: Older versions of "as" (prior to binutils 2.11.90.0.23
- released on 2001-07-14) dit not support .incbin.
- If you are forced to use older binutils than that then the
- following trick can be applied to create the resulting binary:
-
-
- ld -m elf_i386 --format binary --oformat elf32-i386 -r \
- -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
- ld -m elf_i386 -r -o built-in.o initramfs_data.o
-
- initramfs_data.scr looks like this:
-SECTIONS
-{
- .init.ramfs : { *(.data) }
-}
-
- The above example is for i386 - the parameters vary from architectures.
- Eventually look up LDFLAGS_BLOB in an older version of the
- arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
-
- Using .incbin has the advantage over ld that the correct flags are set
- in the ELF header, as required by certain architectures.
-*/
-
-.section .init.ramfs,"a"
-.incbin "usr/initramfs_data.cpio.gz"
+#include "initramfs_data.h"
+initramfs_inc "usr/initramfs_data.cpio.gz";
--- /dev/null
+++ b/usr/initramfs_data.h
@@ -0,0 +1,42 @@
+/*
+ initramfs_data includes the compressed binary that is the
+ filesystem used for early user space.
+ Note: Older versions of "as" (prior to binutils 2.11.90.0.23
+ released on 2001-07-14) dit not support .incbin.
+ If you are forced to use older binutils than that then the
+ following trick can be applied to create the resulting binary:
+
+
+ ld -m elf_i386 --format binary --oformat elf32-i386 -r \
+ -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
+ ld -m elf_i386 -r -o built-in.o initramfs_data.o
+
+ For including the .init.ramfs sections, see include/asm-generic/vmlinux.lds.
+
+ The above example is for i386 - the parameters vary from architectures.
+ Eventually look up LDFLAGS_BLOB in an older version of the
+ arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
+
+ Using .incbin has the advantage over ld that the correct flags are set
+ in the ELF header, as required by certain architectures.
+*/
+
+#ifndef __INITRAMFS_DATA_H
+#define __INITRAMFS_DATA_H
+
+.macro initramfs_inc file:req
+.section .init.ramfs,"a"
+__irf_start:
+.incbin "\file"
+__irf_end:
+.section .init.ramfs.info,"a"
+.globl __initramfs_size
+__initramfs_size:
+#ifdef CONFIG_32BIT
+ .long __irf_end - __irf_start
+#else
+ .quad __irf_end - __irf_start
+#endif
+.endm
+
+#endif /* __INITRAMFS_DATA_H */
--- a/usr/initramfs_data.lzma.S
+++ b/usr/initramfs_data.lzma.S
@@ -1,29 +1,2 @@
-/*
- initramfs_data includes the compressed binary that is the
- filesystem used for early user space.
- Note: Older versions of "as" (prior to binutils 2.11.90.0.23
- released on 2001-07-14) dit not support .incbin.
- If you are forced to use older binutils than that then the
- following trick can be applied to create the resulting binary:
-
-
- ld -m elf_i386 --format binary --oformat elf32-i386 -r \
- -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
- ld -m elf_i386 -r -o built-in.o initramfs_data.o
-
- initramfs_data.scr looks like this:
-SECTIONS
-{
- .init.ramfs : { *(.data) }
-}
-
- The above example is for i386 - the parameters vary from architectures.
- Eventually look up LDFLAGS_BLOB in an older version of the
- arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
-
- Using .incbin has the advantage over ld that the correct flags are set
- in the ELF header, as required by certain architectures.
-*/
-
-.section .init.ramfs,"a"
-.incbin "usr/initramfs_data.cpio.lzma"
+#include "initramfs_data.h"
+initramfs_inc "usr/initramfs_data.cpio.lzma";


2010-08-25 18:06:08

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH] Fix initramfs size calculation

On Wed, Aug 25, 2010 at 05:57:12PM +0200, Michael Holzheu wrote:
> The size of a built-in initramfs is calculated in init/initramfs.c by
> "__initramfs_end - __initramfs_start". Those symbols are defined in the
> linker script include/asm-generic/vmlinux.lds.h:
>
> #define INIT_RAM_FS \
> . = ALIGN(PAGE_SIZE); \
> VMLINUX_SYMBOL(__initramfs_start) = .; \
> *(.init.ramfs) \
> VMLINUX_SYMBOL(__initramfs_end) = .;
>
> If the initramfs file has an odd number of bytes, the "__initramfs_end"
> symbol points to an odd address, for example, the symbols in the System.map
> might look like:
>
> 0000000000572000 T __initramfs_start
> 00000000005bcd05 T __initramfs_end <-- odd address
>
> At least on s390 this is a problem:

Another way to fix this could be to align . to an even
address like this:
> #define INIT_RAM_FS \
> . = ALIGN(PAGE_SIZE); \
> VMLINUX_SYMBOL(__initramfs_start) = .; \
> *(.init.ramfs) \
. = ALIGN(32); \
> VMLINUX_SYMBOL(__initramfs_end) = .;
>

32 was selected as this is what we will introduce as the default
alignment in linker scripts anyway.

This I guess is a problem we have had some time and a minimal fix is
easier to have backported by the stable team.

> The patch also restructures the "usr/initramfs_data.xxx.S" files to use a
> common macro that includes the (compressed) initramfs file and calculates
> the __initramfs_size.
I like this anyway. Could you do this as a separate patch?

Sam

2010-08-25 19:15:39

by Hendrik Brueckner

[permalink] [raw]
Subject: Re: [PATCH] Fix initramfs size calculation

Sam,

I have work together with Michael on this patch... see my comments below

On Wed, Aug 25, 2010 at 08:06:01PM +0200, Sam Ravnborg wrote:
> On Wed, Aug 25, 2010 at 05:57:12PM +0200, Michael Holzheu wrote:
>
> Another way to fix this could be to align . to an even
> address like this:
> > #define INIT_RAM_FS \
> > . = ALIGN(PAGE_SIZE); \
> > VMLINUX_SYMBOL(__initramfs_start) = .; \
> > *(.init.ramfs) \
> . = ALIGN(32); \
> > VMLINUX_SYMBOL(__initramfs_end) = .;
> >
>
> 32 was selected as this is what we will introduce as the default
> alignment in linker scripts anyway.
>
> This I guess is a problem we have had some time and a minimal fix is
> easier to have backported by the stable team.

The first thought was similar but using ALIGN(2). However, the current
implementation of populate_rootfs() passes the calculated size to the
decompress functions. If __initramfs_end is aligned, the resulting size
might be greater than the real size of the initramfs.
So I guess this might also cause problems.

> > The patch also restructures the "usr/initramfs_data.xxx.S" files to use a
> > common macro that includes the (compressed) initramfs file and calculates
> > the __initramfs_size.
> I like this anyway. Could you do this as a separate patch?

I think that Michael or me could do this.


Kind regards,
Hendrik

2010-08-25 19:56:51

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH] Fix initramfs size calculation

On Wed, Aug 25, 2010 at 09:15:32PM +0200, Hendrik Brueckner wrote:
> Sam,
>
> I have work together with Michael on this patch... see my comments below
>
> On Wed, Aug 25, 2010 at 08:06:01PM +0200, Sam Ravnborg wrote:
> > On Wed, Aug 25, 2010 at 05:57:12PM +0200, Michael Holzheu wrote:
> >
> > Another way to fix this could be to align . to an even
> > address like this:
> > > #define INIT_RAM_FS \
> > > . = ALIGN(PAGE_SIZE); \
> > > VMLINUX_SYMBOL(__initramfs_start) = .; \
> > > *(.init.ramfs) \
> > . = ALIGN(32); \
> > > VMLINUX_SYMBOL(__initramfs_end) = .;
> > >
> >
> > 32 was selected as this is what we will introduce as the default
> > alignment in linker scripts anyway.
> >
> > This I guess is a problem we have had some time and a minimal fix is
> > easier to have backported by the stable team.
>
> The first thought was similar but using ALIGN(2). However, the current
> implementation of populate_rootfs() passes the calculated size to the
> decompress functions. If __initramfs_end is aligned, the resulting size
> might be greater than the real size of the initramfs.
> So I guess this might also cause problems.
Another variant could be to explicit add alignment in the .S files
so the section is always aligned to a even byte boundary (or maybe 32 byte boundary).

That should also cover the above case.

Sam

2010-08-25 20:10:17

by H. Peter Anvin

[permalink] [raw]
Subject: Re: [PATCH] Fix initramfs size calculation

On 08/25/2010 08:57 AM, Michael Holzheu wrote:
> Certain s390 instructions, especially instructions for loading addresses
> (larl) or branch addresses must be on even addresses.

I have to admit to finding this fairly disturbing, as this is likely to
come up again and again. Is there any way to tell gcc (e.g. with an
alignment attribute) that a particular symbol is not safe to be loaded
with larl?

-hpa

2010-08-26 08:46:47

by Michael Holzheu

[permalink] [raw]
Subject: Re: [PATCH] Fix initramfs size calculation

Hello Peter,

On Wed, 2010-08-25 at 13:10 -0700, H. Peter Anvin wrote:
> On 08/25/2010 08:57 AM, Michael Holzheu wrote:
> > Certain s390 instructions, especially instructions for loading addresses
> > (larl) or branch addresses must be on even addresses.
>
> I have to admit to finding this fairly disturbing, as this is likely to
> come up again and again. Is there any way to tell gcc (e.g. with an
> alignment attribute) that a particular symbol is not safe to be loaded
> with larl?

I think, it is not possible the change that in the compiler. The fact
that the compiler on s390 assumes that symbols are 2 byte aligned was a
design decission and is part of the ABI.

Michael

2010-08-26 08:55:55

by Michael Holzheu

[permalink] [raw]
Subject: Re: [PATCH] Fix initramfs size calculation

Hello Sam,

On Wed, 2010-08-25 at 21:56 +0200, Sam Ravnborg wrote:
> On Wed, Aug 25, 2010 at 09:15:32PM +0200, Hendrik Brueckner wrote:
> > Sam,
> >
> > I have work together with Michael on this patch... see my comments below
> >
> > On Wed, Aug 25, 2010 at 08:06:01PM +0200, Sam Ravnborg wrote:
> > > On Wed, Aug 25, 2010 at 05:57:12PM +0200, Michael Holzheu wrote:
> > >
> > > Another way to fix this could be to align . to an even
> > > address like this:
> > > > #define INIT_RAM_FS \
> > > > . = ALIGN(PAGE_SIZE); \
> > > > VMLINUX_SYMBOL(__initramfs_start) = .; \
> > > > *(.init.ramfs) \
> > > . = ALIGN(32); \
> > > > VMLINUX_SYMBOL(__initramfs_end) = .;
> > > >
> > >
> > > 32 was selected as this is what we will introduce as the default
> > > alignment in linker scripts anyway.
> > >
> > > This I guess is a problem we have had some time and a minimal fix is
> > > easier to have backported by the stable team.
> >
> > The first thought was similar but using ALIGN(2). However, the current
> > implementation of populate_rootfs() passes the calculated size to the
> > decompress functions. If __initramfs_end is aligned, the resulting size
> > might be greater than the real size of the initramfs.
> > So I guess this might also cause problems.
> Another variant could be to explicit add alignment in the .S files
> so the section is always aligned to a even byte boundary (or maybe 32 byte boundary).

Then still the unpack_to_rootfs() function will not get the correct size
of the compressed file, because "__initramfs_end - __initramfs_start"
can be bigger than the real file size depending on the used the
alignment. I would assume that not all decompression functions will
work, if a bigger value is passed to decompress_method().

Michael



2010-08-26 11:48:00

by Hendrik Brueckner

[permalink] [raw]
Subject: [PATCH v2 2/2] initramfs: Fix initramfs size calculation

The size of a built-in initramfs is calculated in init/initramfs.c by
"__initramfs_end - __initramfs_start". Those symbols are defined in the
linker script include/asm-generic/vmlinux.lds.h:

#define INIT_RAM_FS \
. = ALIGN(PAGE_SIZE); \
VMLINUX_SYMBOL(__initramfs_start) = .; \
*(.init.ramfs) \
VMLINUX_SYMBOL(__initramfs_end) = .;

If the initramfs file has an odd number of bytes, the "__initramfs_end"
symbol points to an odd address, for example, the symbols in the System.map
might look like:

0000000000572000 T __initramfs_start
00000000005bcd05 T __initramfs_end <-- odd address

At least on s390 this causes a problem:

Certain s390 instructions, especially instructions for loading addresses
(larl) or branch addresses must be on even addresses.
The compiler loads the symbol addresses with the "larl" instruction. This
instruction sets the last bit to 0 and, therefore, for odd size files, the
calculated size is one byte less than it should be:

0000000000540a9c <populate_rootfs>:
540a9c: eb cf f0 78 00 24 stmg %r12,%r15,120(%r15),
540aa2: c0 10 00 01 8a af larl %r1,572000 <__initramfs_start>
540aa8: c0 c0 00 03 e1 2e larl %r12,5bcd04 <initramfs_end>
(Instead of 5bcd05)
...
540abe: 1b c1 sr %r12,%r1

To fix the problem, this patch introduces the global variable
__initramfs_size, which is calculated in the "usr/initramfs_data.S" file.
The populate_rootfs() function can then use the start marker of the
.init.ramfs section and the value of __initramfs_size for loading the
initramfs. Because the start marker and size is sufficient, the
__initramfs_end symbol is no longer needed and is removed.

Signed-off-by: Michael Holzheu <[email protected]>
Signed-off-by: Hendrik Brueckner <[email protected]>
---
include/asm-generic/vmlinux.lds.h | 3 ++-
init/initramfs.c | 9 ++++-----
usr/initramfs_data.S | 16 +++++++++++-----
3 files changed, 17 insertions(+), 11 deletions(-)

--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -629,7 +629,8 @@
. = ALIGN(PAGE_SIZE); \
VMLINUX_SYMBOL(__initramfs_start) = .; \
*(.init.ramfs) \
- VMLINUX_SYMBOL(__initramfs_end) = .;
+ . = ALIGN(8); \
+ *(.init.ramfs.info)
#else
#define INIT_RAM_FS
#endif
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -483,7 +483,8 @@ static int __init retain_initrd_param(ch
}
__setup("retain_initrd", retain_initrd_param);

-extern char __initramfs_start[], __initramfs_end[];
+extern char __initramfs_start[];
+extern unsigned long __initramfs_size;
#include <linux/initrd.h>
#include <linux/kexec.h>

@@ -570,8 +571,7 @@ static void __init clean_rootfs(void)

static int __init populate_rootfs(void)
{
- char *err = unpack_to_rootfs(__initramfs_start,
- __initramfs_end - __initramfs_start);
+ char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
if (err)
panic(err); /* Failed to decompress INTERNAL initramfs */
if (initrd_start) {
@@ -585,8 +585,7 @@ static int __init populate_rootfs(void)
return 0;
} else {
clean_rootfs();
- unpack_to_rootfs(__initramfs_start,
- __initramfs_end - __initramfs_start);
+ unpack_to_rootfs(__initramfs_start, __initramfs_size);
}
printk(KERN_INFO "rootfs image is not initramfs (%s)"
"; looks like an initrd\n", err);
--- a/usr/initramfs_data.S
+++ b/usr/initramfs_data.S
@@ -11,11 +11,7 @@
-T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
ld -m elf_i386 -r -o built-in.o initramfs_data.o

- initramfs_data.scr looks like this:
-SECTIONS
-{
- .init.ramfs : { *(.data) }
-}
+ For including the .init.ramfs sections, see include/asm-generic/vmlinux.lds.

The above example is for i386 - the parameters vary from architectures.
Eventually look up LDFLAGS_BLOB in an older version of the
@@ -28,4 +24,14 @@ SECTIONS
#include <linux/stringify.h>

.section .init.ramfs,"a"
+__irf_start:
.incbin __stringify(INITRAMFS_IMAGE)
+__irf_end:
+.section .init.ramfs.info,"a"
+.globl __initramfs_size
+__initramfs_size:
+#ifdef CONFIG_32BIT
+ .long __irf_end - __irf_start
+#else
+ .quad __irf_end - __irf_start
+#endif

--

2010-08-26 11:48:05

by Hendrik Brueckner

[permalink] [raw]
Subject: [PATCH v2 0/2] initramfs: Cleanup and fix initramfs size calculation

On Wed, Aug 25, 2010 at 08:06:01PM +0200, Sam Ravnborg wrote:
> On Wed, Aug 25, 2010 at 05:57:12PM +0200, Michael Holzheu wrote:
>
> > The patch also restructures the "usr/initramfs_data.xxx.S" files to use a
> > common macro that includes the (compressed) initramfs file and calculates
> > the __initramfs_size.
> I like this anyway. Could you do this as a separate patch?

Done ;-)

The first patch in this series introduces a common initramfs_data.S file
that is shared by the compression variants. The second patch adds the new
initramfs size calculation proposed in the initial patch.
See the patch description for more details.


Kind regards,
Hendrik

2010-08-26 11:48:06

by Hendrik Brueckner

[permalink] [raw]
Subject: [PATCH v2 1/2] initramfs: Generalize initramfs_data.xxx.S variants

Remove initramfs_data.{lzo,lzma,gz,bz2}.S variants and use a common
implementation in initramfs_data.S. The common implementation expects
the file name of the initramfs to be defined in INITRAMFS_IMAGE.

Change the Makefile to set the INITRAMFS_IMAGE define symbol according
to the selected compression method.

Signed-off-by: Hendrik Brueckner <[email protected]>
---
usr/Makefile | 6 ++++--
usr/initramfs_data.S | 5 +++--
usr/initramfs_data.bz2.S | 29 -----------------------------
usr/initramfs_data.gz.S | 29 -----------------------------
usr/initramfs_data.lzma.S | 29 -----------------------------
usr/initramfs_data.lzo.S | 29 -----------------------------
6 files changed, 7 insertions(+), 120 deletions(-)

--- a/usr/Makefile
+++ b/usr/Makefile
@@ -18,13 +18,15 @@ suffix_$(CONFIG_INITRAMFS_COMPRESSION_LZ
# Lzo
suffix_$(CONFIG_INITRAMFS_COMPRESSION_LZO) = .lzo

+AFLAGS_initramfs_data.o += -DINITRAMFS_IMAGE="usr/initramfs_data.cpio$(suffix_y)"
+
# Generate builtin.o based on initramfs_data.o
-obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data$(suffix_y).o
+obj-$(CONFIG_BLK_DEV_INITRD) := initramfs_data.o

# initramfs_data.o contains the compressed initramfs_data.cpio image.
# The image is included using .incbin, a dependency which is not
# tracked automatically.
-$(obj)/initramfs_data$(suffix_y).o: $(obj)/initramfs_data.cpio$(suffix_y) FORCE
+$(obj)/initramfs_data.o: $(obj)/initramfs_data.cpio$(suffix_y) FORCE

#####
# Generate the initramfs cpio archive
--- a/usr/initramfs_data.S
+++ b/usr/initramfs_data.S
@@ -25,6 +25,7 @@ SECTIONS
in the ELF header, as required by certain architectures.
*/

-.section .init.ramfs,"a"
-.incbin "usr/initramfs_data.cpio"
+#include <linux/stringify.h>

+.section .init.ramfs,"a"
+.incbin __stringify(INITRAMFS_IMAGE)
--- a/usr/initramfs_data.bz2.S
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- initramfs_data includes the compressed binary that is the
- filesystem used for early user space.
- Note: Older versions of "as" (prior to binutils 2.11.90.0.23
- released on 2001-07-14) dit not support .incbin.
- If you are forced to use older binutils than that then the
- following trick can be applied to create the resulting binary:
-
-
- ld -m elf_i386 --format binary --oformat elf32-i386 -r \
- -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
- ld -m elf_i386 -r -o built-in.o initramfs_data.o
-
- initramfs_data.scr looks like this:
-SECTIONS
-{
- .init.ramfs : { *(.data) }
-}
-
- The above example is for i386 - the parameters vary from architectures.
- Eventually look up LDFLAGS_BLOB in an older version of the
- arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
-
- Using .incbin has the advantage over ld that the correct flags are set
- in the ELF header, as required by certain architectures.
-*/
-
-.section .init.ramfs,"a"
-.incbin "usr/initramfs_data.cpio.bz2"
--- a/usr/initramfs_data.gz.S
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- initramfs_data includes the compressed binary that is the
- filesystem used for early user space.
- Note: Older versions of "as" (prior to binutils 2.11.90.0.23
- released on 2001-07-14) dit not support .incbin.
- If you are forced to use older binutils than that then the
- following trick can be applied to create the resulting binary:
-
-
- ld -m elf_i386 --format binary --oformat elf32-i386 -r \
- -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
- ld -m elf_i386 -r -o built-in.o initramfs_data.o
-
- initramfs_data.scr looks like this:
-SECTIONS
-{
- .init.ramfs : { *(.data) }
-}
-
- The above example is for i386 - the parameters vary from architectures.
- Eventually look up LDFLAGS_BLOB in an older version of the
- arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
-
- Using .incbin has the advantage over ld that the correct flags are set
- in the ELF header, as required by certain architectures.
-*/
-
-.section .init.ramfs,"a"
-.incbin "usr/initramfs_data.cpio.gz"
--- a/usr/initramfs_data.lzma.S
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- initramfs_data includes the compressed binary that is the
- filesystem used for early user space.
- Note: Older versions of "as" (prior to binutils 2.11.90.0.23
- released on 2001-07-14) dit not support .incbin.
- If you are forced to use older binutils than that then the
- following trick can be applied to create the resulting binary:
-
-
- ld -m elf_i386 --format binary --oformat elf32-i386 -r \
- -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
- ld -m elf_i386 -r -o built-in.o initramfs_data.o
-
- initramfs_data.scr looks like this:
-SECTIONS
-{
- .init.ramfs : { *(.data) }
-}
-
- The above example is for i386 - the parameters vary from architectures.
- Eventually look up LDFLAGS_BLOB in an older version of the
- arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
-
- Using .incbin has the advantage over ld that the correct flags are set
- in the ELF header, as required by certain architectures.
-*/
-
-.section .init.ramfs,"a"
-.incbin "usr/initramfs_data.cpio.lzma"
--- a/usr/initramfs_data.lzo.S
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- initramfs_data includes the compressed binary that is the
- filesystem used for early user space.
- Note: Older versions of "as" (prior to binutils 2.11.90.0.23
- released on 2001-07-14) dit not support .incbin.
- If you are forced to use older binutils than that then the
- following trick can be applied to create the resulting binary:
-
-
- ld -m elf_i386 --format binary --oformat elf32-i386 -r \
- -T initramfs_data.scr initramfs_data.cpio.gz -o initramfs_data.o
- ld -m elf_i386 -r -o built-in.o initramfs_data.o
-
- initramfs_data.scr looks like this:
-SECTIONS
-{
- .init.ramfs : { *(.data) }
-}
-
- The above example is for i386 - the parameters vary from architectures.
- Eventually look up LDFLAGS_BLOB in an older version of the
- arch/$(ARCH)/Makefile to see the flags used before .incbin was introduced.
-
- Using .incbin has the advantage over ld that the correct flags are set
- in the ELF header, as required by certain architectures.
-*/
-
-.section .init.ramfs,"a"
-.incbin "usr/initramfs_data.cpio.lzo"

--