From 6ae64e428f74e7bacab898ef9665dda719ea6fde Mon Sep 17 00:00:00 2001
From: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Date: Fri, 17 Sep 2010 15:24:09 -0700
Subject: 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 <brueckner@linux.vnet.ibm.com>
Cc: WANG Cong <xiyou.wangcong@gmail.com>
Acked-by: Michal Marek <mmarek@suse.cz>
Acked-by: "H. Peter Anvin" <hpa@zytor.com>
Cc: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Michal Marek <mmarek@suse.cz>
---
 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(-)
 delete mode 100644 usr/initramfs_data.bz2.S
 delete mode 100644 usr/initramfs_data.gz.S
 delete mode 100644 usr/initramfs_data.lzma.S
 delete mode 100644 usr/initramfs_data.lzo.S

(limited to 'usr')

diff --git a/usr/Makefile b/usr/Makefile
index 6b4b6da0b67d..6faa444b7087 100644
--- a/usr/Makefile
+++ b/usr/Makefile
@@ -18,13 +18,15 @@ suffix_$(CONFIG_INITRAMFS_COMPRESSION_LZMA)   = .lzma
 # 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
diff --git a/usr/initramfs_data.S b/usr/initramfs_data.S
index 7c6973d8d829..49a545fea120 100644
--- 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)
diff --git a/usr/initramfs_data.bz2.S b/usr/initramfs_data.bz2.S
deleted file mode 100644
index bc54d090365c..000000000000
--- 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"
diff --git a/usr/initramfs_data.gz.S b/usr/initramfs_data.gz.S
deleted file mode 100644
index 890c8dd1d6bd..000000000000
--- 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"
diff --git a/usr/initramfs_data.lzma.S b/usr/initramfs_data.lzma.S
deleted file mode 100644
index e11469e48562..000000000000
--- 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"
diff --git a/usr/initramfs_data.lzo.S b/usr/initramfs_data.lzo.S
deleted file mode 100644
index 59211905da84..000000000000
--- 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"
-- 
cgit v1.2.3


From ffe8018c3424892c9590048fc36caa6c3e0c8a76 Mon Sep 17 00:00:00 2001
From: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Date: Fri, 17 Sep 2010 15:24:11 -0700
Subject: 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 <holzheu@linux.vnet.ibm.com>
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Reviewed-by: WANG Cong <xiyou.wangcong@gmail.com>
Acked-by: Michal Marek <mmarek@suse.cz>
Acked-by: "H. Peter Anvin" <hpa@zytor.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Michal Marek <mmarek@suse.cz>
---
 include/asm-generic/vmlinux.lds.h |  3 ++-
 init/initramfs.c                  |  9 ++++-----
 usr/initramfs_data.S              | 16 +++++++++++-----
 3 files changed, 17 insertions(+), 11 deletions(-)

(limited to 'usr')

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 030a954ed292..0c6387d6a6ae 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -633,7 +633,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
diff --git a/init/initramfs.c b/init/initramfs.c
index 4b9c20205092..371c3da64ad3 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -483,7 +483,8 @@ static int __init retain_initrd_param(char *str)
 }
 __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);
diff --git a/usr/initramfs_data.S b/usr/initramfs_data.S
index 49a545fea120..b9efed5e35cc 100644
--- 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
-- 
cgit v1.2.3


From 96f935934591b72f5b05fd6923bc8cdcae92f2e5 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: Sun, 31 Oct 2010 10:56:23 +0100
Subject: initramfs: Fix initramfs size for 32-bit arches

Commit ffe8018c3424 ("initramfs: fix initramfs size calculation") broke
32-bit big-endian arches like (on ARAnyM):

    VFS: Cannot open root device "hda1" or unknown-block(3,1)
    Please append a correct "root=" boot option; here are the available partitions:
    fe80         1059408 nfhd8  (driver?)
      fe81          921600 nfhd8p1 00000000-0000-0000-0000-000000000nfhd8p1
      fe82          137807 nfhd8p2 00000000-0000-0000-0000-000000000nfhd8p2
    0200            3280 fd0  (driver?)
    0201            3280 fd1  (driver?)
    0300         1059408 hda  driver: ide-gd
      0301          921600 hda1 00000000-0000-0000-0000-000000000hda1
      0302          137807 hda2 00000000-0000-0000-0000-000000000hda2
    Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(3,1)

As pointed out by Kerstin Jonsson <kerstin.jonsson@ericsson.com>, this
is due to CONFIG_32BIT not being defined, so the initramfs size field is
done as a 64-bit quad.  On little-endian (like x86) this doesn matter,
but on a big-endian machine the 32-bit reads will see the (zero) high
bits.

Only mips, s390, and score set CONFIG_32BIT for 32-bit builds, so fix it for
all other 32-bit arches by inverting the logic and testing for CONFIG_64BIT,
which should be defined on all 64-bit arches.

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
[ I think we should just make it "u64" on all architectures and get
  rid of the whole #ifdef CONFIG_xxBIT   - Linus ]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 usr/initramfs_data.S | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'usr')

diff --git a/usr/initramfs_data.S b/usr/initramfs_data.S
index b9efed5e35cc..792a750d9441 100644
--- a/usr/initramfs_data.S
+++ b/usr/initramfs_data.S
@@ -30,8 +30,8 @@ __irf_end:
 .section .init.ramfs.info,"a"
 .globl __initramfs_size
 __initramfs_size:
-#ifdef CONFIG_32BIT
-	.long __irf_end - __irf_start
-#else
+#ifdef CONFIG_64BIT
 	.quad __irf_end - __irf_start
+#else
+	.long __irf_end - __irf_start
 #endif
-- 
cgit v1.2.3