summaryrefslogtreecommitdiff
path: root/arch/mips/boot/compressed/decompress.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/boot/compressed/decompress.c')
-rw-r--r--arch/mips/boot/compressed/decompress.c91
1 files changed, 55 insertions, 36 deletions
diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c
index 2c9573098c0d..90021c6a8cab 100644
--- a/arch/mips/boot/compressed/decompress.c
+++ b/arch/mips/boot/compressed/decompress.c
@@ -1,20 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright 2001 MontaVista Software Inc.
* Author: Matt Porter <mporter@mvista.com>
*
* Copyright (C) 2009 Lemote, Inc.
* Author: Wu Zhangjin <wuzhangjin@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
*/
+#define DISABLE_BRANCH_PROFILING
+
+#define __NO_FORTIFY
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/libfdt.h>
#include <asm/addrspace.h>
+#include <linux/unaligned.h>
+#include <asm-generic/vmlinux.lds.h>
+
+#include "decompress.h"
/*
* These two variables specify the free mem region
@@ -23,13 +28,6 @@
unsigned long free_mem_ptr;
unsigned long free_mem_end_ptr;
-/* The linker tells us where the image is. */
-extern unsigned char __image_begin, __image_end;
-
-/* debug interfaces */
-extern void puts(const char *s);
-extern void puthex(unsigned long long val);
-
void error(char *x)
{
puts("\n\n");
@@ -44,32 +42,17 @@ void error(char *x)
#define STATIC static
#ifdef CONFIG_KERNEL_GZIP
-void *memcpy(void *dest, const void *src, size_t n)
-{
- int i;
- const char *s = src;
- char *d = dest;
-
- for (i = 0; i < n; i++)
- d[i] = s[i];
- return dest;
-}
#include "../../../../lib/decompress_inflate.c"
#endif
#ifdef CONFIG_KERNEL_BZIP2
-void *memset(void *s, int c, size_t n)
-{
- int i;
- char *ss = s;
-
- for (i = 0; i < n; i++)
- ss[i] = c;
- return s;
-}
#include "../../../../lib/decompress_bunzip2.c"
#endif
+#ifdef CONFIG_KERNEL_LZ4
+#include "../../../../lib/decompress_unlz4.c"
+#endif
+
#ifdef CONFIG_KERNEL_LZMA
#include "../../../../lib/decompress_unlzma.c"
#endif
@@ -78,13 +61,28 @@ void *memset(void *s, int c, size_t n)
#include "../../../../lib/decompress_unlzo.c"
#endif
+#ifdef CONFIG_KERNEL_XZ
+#include "../../../../lib/decompress_unxz.c"
+#endif
+
+#ifdef CONFIG_KERNEL_ZSTD
+#include "../../../../lib/decompress_unzstd.c"
+#endif
+
+const unsigned long __stack_chk_guard = 0x000a0dff;
+
+void __stack_chk_fail(void)
+{
+ error("stack-protector: Kernel stack is corrupted\n");
+}
+
void decompress_kernel(unsigned long boot_heap_start)
{
unsigned long zimage_start, zimage_size;
- zimage_start = (unsigned long)(&__image_begin);
- zimage_size = (unsigned long)(&__image_end) -
- (unsigned long)(&__image_begin);
+ zimage_start = (unsigned long)(__image_begin);
+ zimage_size = (unsigned long)(__image_end) -
+ (unsigned long)(__image_begin);
puts("zimage at: ");
puthex(zimage_start);
@@ -102,8 +100,29 @@ void decompress_kernel(unsigned long boot_heap_start)
puts("\n");
/* Decompress the kernel with according algorithm */
- decompress((char *)zimage_start, zimage_size, 0, 0,
- (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, error);
+ __decompress((char *)zimage_start, zimage_size, 0, 0,
+ (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, 0, error);
+
+ if (IS_ENABLED(CONFIG_MIPS_RAW_APPENDED_DTB) &&
+ fdt_magic((void *)&__appended_dtb) == FDT_MAGIC) {
+ unsigned int image_size, dtb_size;
+
+ dtb_size = fdt_totalsize((void *)&__appended_dtb);
+
+ /* last four bytes is always image size in little endian */
+ image_size = get_unaligned_le32((void *)__image_end - 4);
+
+ /* The device tree's address must be properly aligned */
+ image_size = ALIGN(image_size, STRUCT_ALIGNMENT);
+
+ puts("Copy device tree to address ");
+ puthex(VMLINUX_LOAD_ADDRESS_ULL + image_size);
+ puts("\n");
+
+ /* copy dtb to where the booted kernel will expect it */
+ memcpy((void *)VMLINUX_LOAD_ADDRESS_ULL + image_size,
+ __appended_dtb, dtb_size);
+ }
/* FIXME: should we flush cache here? */
puts("Now, booting the kernel...\n");