mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-19 10:14:23 +08:00
MIPS: Octeon: detect and fix byte swapped initramfs
Octeon machines support running in little endian mode. U-Boot usually runs in big endian-mode. Therefore the initramfs is loaded in big endian mode, and the kernel later tries to access it in little endian mode. This patch fixes that by detecting byte swapped initramfs using either the CPIO header or the header from standard compression methods, and byte swaps it if needed. It first checks that the header doesn't match in the native endianness to avoid false detections. It uses the kernel decompress library so that we don't have to maintain the list of magics if some decompression methods are added to the kernel. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> Acked-by: David Daney <david.daney@cavium.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/13219/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
b472080912
commit
8f4703aa4d
@ -26,6 +26,7 @@
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-contiguous.h>
|
||||
#include <linux/decompress/generic.h>
|
||||
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/bootinfo.h>
|
||||
@ -243,6 +244,35 @@ disable:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* In some conditions (e.g. big endian bootloader with a little endian
|
||||
kernel), the initrd might appear byte swapped. Try to detect this and
|
||||
byte swap it if needed. */
|
||||
static void __init maybe_bswap_initrd(void)
|
||||
{
|
||||
#if defined(CONFIG_CPU_CAVIUM_OCTEON)
|
||||
u64 buf;
|
||||
|
||||
/* Check for CPIO signature */
|
||||
if (!memcmp((void *)initrd_start, "070701", 6))
|
||||
return;
|
||||
|
||||
/* Check for compressed initrd */
|
||||
if (decompress_method((unsigned char *)initrd_start, 8, NULL))
|
||||
return;
|
||||
|
||||
/* Try again with a byte swapped header */
|
||||
buf = swab64p((u64 *)initrd_start);
|
||||
if (!memcmp(&buf, "070701", 6) ||
|
||||
decompress_method((unsigned char *)(&buf), 8, NULL)) {
|
||||
unsigned long i;
|
||||
|
||||
pr_info("Byteswapped initrd detected\n");
|
||||
for (i = initrd_start; i < ALIGN(initrd_end, 8); i += 8)
|
||||
swab64s((u64 *)i);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __init finalize_initrd(void)
|
||||
{
|
||||
unsigned long size = initrd_end - initrd_start;
|
||||
@ -256,6 +286,8 @@ static void __init finalize_initrd(void)
|
||||
goto disable;
|
||||
}
|
||||
|
||||
maybe_bswap_initrd();
|
||||
|
||||
reserve_bootmem(__pa(initrd_start), size, BOOTMEM_DEFAULT);
|
||||
initrd_below_start_ok = 1;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user