diff options
| -rw-r--r-- | arch/mips/Kconfig | 9 | ||||
| -rw-r--r-- | arch/mips/kernel/setup.c | 33 |
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 | ||
| 1887 | source "init/Kconfig" | 1887 | source "init/Kconfig" |
| 1888 | 1888 | ||
| 1889 | config 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 | |||
| 1889 | menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)" | 1898 | menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)" |
| 1890 | 1899 | ||
| 1891 | config HW_HAS_EISA | 1900 | config 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); | |||
| 160 | static unsigned long __init init_initrd(void) | 160 | static 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 | ||
| 186 | sanitize: | ||
| 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; |
