^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2001 MontaVista Software Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author: Matt Porter <mporter@mvista.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2009 Lemote, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Wu Zhangjin <wuzhangjin@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define DISABLE_BRANCH_PROFILING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/libfdt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/addrspace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * These two variables specify the free mem region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * that can be used for temporary malloc area
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) unsigned long free_mem_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) unsigned long free_mem_end_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* The linker tells us where the image is. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) extern unsigned char __image_begin, __image_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* debug interfaces */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #ifdef CONFIG_DEBUG_ZBOOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) extern void puts(const char *s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) extern void puthex(unsigned long long val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define puts(s) do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define puthex(val) do {} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) extern char __appended_dtb[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) void error(char *x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) puts("\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) puts(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) puts("\n\n -- System halted");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) while (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ; /* Halt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* activate the code for pre-boot environment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define STATIC static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #ifdef CONFIG_KERNEL_GZIP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include "../../../../lib/decompress_inflate.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #ifdef CONFIG_KERNEL_BZIP2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include "../../../../lib/decompress_bunzip2.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #ifdef CONFIG_KERNEL_LZ4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include "../../../../lib/decompress_unlz4.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #ifdef CONFIG_KERNEL_LZMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #include "../../../../lib/decompress_unlzma.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #ifdef CONFIG_KERNEL_LZO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #include "../../../../lib/decompress_unlzo.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #ifdef CONFIG_KERNEL_XZ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #include "../../../../lib/decompress_unxz.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #ifdef CONFIG_KERNEL_ZSTD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #include "../../../../lib/decompress_unzstd.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) const unsigned long __stack_chk_guard = 0x000a0dff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) void __stack_chk_fail(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) error("stack-protector: Kernel stack is corrupted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) void decompress_kernel(unsigned long boot_heap_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) unsigned long zimage_start, zimage_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) zimage_start = (unsigned long)(&__image_begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) zimage_size = (unsigned long)(&__image_end) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) (unsigned long)(&__image_begin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) puts("zimage at: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) puthex(zimage_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) puts(" ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) puthex(zimage_size + zimage_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) puts("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* This area are prepared for mallocing when decompressing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) free_mem_ptr = boot_heap_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) free_mem_end_ptr = boot_heap_start + BOOT_HEAP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* Display standard Linux/MIPS boot prompt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) puts("Uncompressing Linux at load address ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) puthex(VMLINUX_LOAD_ADDRESS_ULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) puts("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* Decompress the kernel with according algorithm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) __decompress((char *)zimage_start, zimage_size, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) (void *)VMLINUX_LOAD_ADDRESS_ULL, 0, 0, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (IS_ENABLED(CONFIG_MIPS_RAW_APPENDED_DTB) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) fdt_magic((void *)&__appended_dtb) == FDT_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) unsigned int image_size, dtb_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) dtb_size = fdt_totalsize((void *)&__appended_dtb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* last four bytes is always image size in little endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) image_size = get_unaligned_le32((void *)&__image_end - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* copy dtb to where the booted kernel will expect it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) memcpy((void *)VMLINUX_LOAD_ADDRESS_ULL + image_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) __appended_dtb, dtb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* FIXME: should we flush cache here? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) puts("Now, booting the kernel...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }