18f75582aSVasily Gorbik // SPDX-License-Identifier: GPL-2.0 28f75582aSVasily Gorbik #include <linux/string.h> 315426ca4SVasily Gorbik #include <asm/setup.h> 48f75582aSVasily Gorbik #include "compressed/decompressor.h" 58f75582aSVasily Gorbik #include "boot.h" 68f75582aSVasily Gorbik 715426ca4SVasily Gorbik #ifdef CONFIG_KERNEL_UNCOMPRESSED 815426ca4SVasily Gorbik unsigned long mem_safe_offset(void) 915426ca4SVasily Gorbik { 1015426ca4SVasily Gorbik return vmlinux.default_lma + vmlinux.image_size + vmlinux.bss_size; 1115426ca4SVasily Gorbik } 1215426ca4SVasily Gorbik #endif 1315426ca4SVasily Gorbik 1415426ca4SVasily Gorbik static void rescue_initrd(void) 1515426ca4SVasily Gorbik { 1615426ca4SVasily Gorbik unsigned long min_initrd_addr; 1715426ca4SVasily Gorbik 1815426ca4SVasily Gorbik if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD)) 1915426ca4SVasily Gorbik return; 2015426ca4SVasily Gorbik if (!INITRD_START || !INITRD_SIZE) 2115426ca4SVasily Gorbik return; 2215426ca4SVasily Gorbik min_initrd_addr = mem_safe_offset(); 2315426ca4SVasily Gorbik if (min_initrd_addr <= INITRD_START) 2415426ca4SVasily Gorbik return; 2515426ca4SVasily Gorbik memmove((void *)min_initrd_addr, (void *)INITRD_START, INITRD_SIZE); 2615426ca4SVasily Gorbik INITRD_START = min_initrd_addr; 2715426ca4SVasily Gorbik } 2815426ca4SVasily Gorbik 298f75582aSVasily Gorbik void startup_kernel(void) 308f75582aSVasily Gorbik { 31369f91c3SVasily Gorbik void *img; 328f75582aSVasily Gorbik 3315426ca4SVasily Gorbik rescue_initrd(); 348f75582aSVasily Gorbik if (!IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) { 35369f91c3SVasily Gorbik img = decompress_kernel(); 36369f91c3SVasily Gorbik memmove((void *)vmlinux.default_lma, img, vmlinux.image_size); 378f75582aSVasily Gorbik } 38369f91c3SVasily Gorbik vmlinux.entry(); 398f75582aSVasily Gorbik } 40