aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAtsushi Nemoto <anemo@mba.ocn.ne.jp>2008-08-26 09:34:57 -0400
committerRalf Baechle <ralf@linux-mips.org>2008-09-05 16:24:12 -0400
commit0011036beeffeada15acd1936d67988de21ca65e (patch)
tree8ec5d593f3ae0b12108e8541157fe54832c2c66c
parent3885ec8ca29e5e33e9a5f0ae9dc849d798634ec9 (diff)
[MIPS] Probe initrd header only if explicitly specified
Currently init_initrd() probes initrd header at the last page of kernel image, but it is valid only if addinitrd was used. If addinitrd was not used, the area contains garbage so probing there might misdetect initrd header (magic number is not strictly robust). This patch introduces CONFIG_PROBE_INITRD_HEADER to explicitly enable this probing. Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/Kconfig9
-rw-r--r--arch/mips/kernel/setup.c33
2 files changed, 27 insertions, 15 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4da736e25333..49896a2a1d72 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1886,6 +1886,15 @@ config STACKTRACE_SUPPORT
1886 1886
1887source "init/Kconfig" 1887source "init/Kconfig"
1888 1888
1889config PROBE_INITRD_HEADER
1890 bool "Probe initrd header created by addinitrd"
1891 depends on BLK_DEV_INITRD
1892 help
1893 Probe initrd header at the last page of kernel image.
1894 Say Y here if you are using arch/mips/boot/addinitrd.c to
1895 add initrd or initramfs image to the kernel image.
1896 Otherwise, say N.
1897
1889menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)" 1898menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
1890 1899
1891config HW_HAS_EISA 1900config HW_HAS_EISA
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 2aae76bce293..16f8edfe5cdc 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -160,30 +160,33 @@ early_param("rd_size", rd_size_early);
160static unsigned long __init init_initrd(void) 160static unsigned long __init init_initrd(void)
161{ 161{
162 unsigned long end; 162 unsigned long end;
163 u32 *initrd_header;
164 163
165 /* 164 /*
166 * Board specific code or command line parser should have 165 * Board specific code or command line parser should have
167 * already set up initrd_start and initrd_end. In these cases 166 * already set up initrd_start and initrd_end. In these cases
168 * perfom sanity checks and use them if all looks good. 167 * perfom sanity checks and use them if all looks good.
169 */ 168 */
170 if (initrd_start && initrd_end > initrd_start) 169 if (!initrd_start || initrd_end <= initrd_start) {
171 goto sanitize; 170#ifdef CONFIG_PROBE_INITRD_HEADER
171 u32 *initrd_header;
172 172
173 /* 173 /*
174 * See if initrd has been added to the kernel image by 174 * See if initrd has been added to the kernel image by
175 * arch/mips/boot/addinitrd.c. In that case a header is 175 * arch/mips/boot/addinitrd.c. In that case a header is
176 * prepended to initrd and is made up by 8 bytes. The fisrt 176 * prepended to initrd and is made up by 8 bytes. The first
177 * word is a magic number and the second one is the size of 177 * word is a magic number and the second one is the size of
178 * initrd. Initrd start must be page aligned in any cases. 178 * initrd. Initrd start must be page aligned in any cases.
179 */ 179 */
180 initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8; 180 initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8;
181 if (initrd_header[0] != 0x494E5244) 181 if (initrd_header[0] != 0x494E5244)
182 goto disable;
183 initrd_start = (unsigned long)(initrd_header + 2);
184 initrd_end = initrd_start + initrd_header[1];
185#else
182 goto disable; 186 goto disable;
183 initrd_start = (unsigned long)(initrd_header + 2); 187#endif
184 initrd_end = initrd_start + initrd_header[1]; 188 }
185 189
186sanitize:
187 if (initrd_start & ~PAGE_MASK) { 190 if (initrd_start & ~PAGE_MASK) {
188 pr_err("initrd start must be page aligned\n"); 191 pr_err("initrd start must be page aligned\n");
189 goto disable; 192 goto disable;