1 // SPDX-License-Identifier: GPL-2.0
6 #include <linux/unaligned.h>
10 static unsigned char zboot_heap
[SZ_256K
] __aligned(64);
11 static unsigned long free_mem_ptr
, free_mem_end_ptr
;
14 #if defined(CONFIG_KERNEL_GZIP)
15 #include "../../../../lib/decompress_inflate.c"
16 #elif defined(CONFIG_KERNEL_LZ4)
17 #include "../../../../lib/decompress_unlz4.c"
18 #elif defined(CONFIG_KERNEL_LZMA)
19 #include "../../../../lib/decompress_unlzma.c"
20 #elif defined(CONFIG_KERNEL_LZO)
21 #include "../../../../lib/decompress_unlzo.c"
22 #elif defined(CONFIG_KERNEL_XZ)
26 #define memmove memmove
27 #include "../../../../lib/decompress_unxz.c"
28 #elif defined(CONFIG_KERNEL_ZSTD)
29 #include "../../../../lib/decompress_unzstd.c"
32 extern char efi_zboot_header
[];
33 extern char _gzdata_start
[], _gzdata_end
[];
35 static void error(char *x
)
37 efi_err("EFI decompressor: %s\n", x
);
40 static unsigned long alloc_preferred_address(unsigned long alloc_size
)
42 #ifdef EFI_KIMG_PREFERRED_ADDRESS
43 efi_physical_addr_t efi_addr
= EFI_KIMG_PREFERRED_ADDRESS
;
45 if (efi_bs_call(allocate_pages
, EFI_ALLOCATE_ADDRESS
, EFI_LOADER_DATA
,
46 alloc_size
/ EFI_PAGE_SIZE
, &efi_addr
) == EFI_SUCCESS
)
52 void __weak
efi_cache_sync_image(unsigned long image_base
,
53 unsigned long alloc_size
)
55 // Provided by the arch to perform the cache maintenance necessary for
56 // executable code loaded into memory to be safe for execution.
59 struct screen_info
*alloc_screen_info(void)
61 return __alloc_screen_info();
64 asmlinkage efi_status_t __efiapi
65 efi_zboot_entry(efi_handle_t handle
, efi_system_table_t
*systab
)
67 unsigned long compressed_size
= _gzdata_end
- _gzdata_start
;
68 unsigned long image_base
, alloc_size
;
69 efi_loaded_image_t
*image
;
74 WRITE_ONCE(efi_system_table
, systab
);
76 free_mem_ptr
= (unsigned long)&zboot_heap
;
77 free_mem_end_ptr
= free_mem_ptr
+ sizeof(zboot_heap
);
79 status
= efi_bs_call(handle_protocol
, handle
,
80 &LOADED_IMAGE_PROTOCOL_GUID
, (void **)&image
);
81 if (status
!= EFI_SUCCESS
) {
82 error("Failed to locate parent's loaded image protocol");
86 status
= efi_handle_cmdline(image
, &cmdline_ptr
);
87 if (status
!= EFI_SUCCESS
)
90 efi_info("Decompressing Linux Kernel...\n");
92 // SizeOfImage from the compressee's PE/COFF header
93 alloc_size
= round_up(get_unaligned_le32(_gzdata_end
- 4),
96 // If the architecture has a preferred address for the image,
98 image_base
= alloc_preferred_address(alloc_size
);
99 if (image_base
== ULONG_MAX
) {
100 unsigned long min_kimg_align
= efi_get_kimg_min_align();
103 if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE
)) {
104 // Setting the random seed to 0x0 is the same as
105 // allocating as low as possible
107 } else if (efi_nokaslr
) {
108 efi_info("KASLR disabled on kernel command line\n");
110 status
= efi_get_random_bytes(sizeof(seed
), (u8
*)&seed
);
111 if (status
== EFI_NOT_FOUND
) {
112 efi_info("EFI_RNG_PROTOCOL unavailable\n");
114 } else if (status
!= EFI_SUCCESS
) {
115 efi_err("efi_get_random_bytes() failed (0x%lx)\n",
121 status
= efi_random_alloc(alloc_size
, min_kimg_align
, &image_base
,
122 seed
, EFI_LOADER_CODE
, 0, EFI_ALLOC_LIMIT
);
123 if (status
!= EFI_SUCCESS
) {
124 efi_err("Failed to allocate memory\n");
129 // Decompress the payload into the newly allocated buffer.
130 ret
= __decompress(_gzdata_start
, compressed_size
, NULL
, NULL
,
131 (void *)image_base
, alloc_size
, NULL
, error
);
133 error("Decompression failed");
134 status
= EFI_DEVICE_ERROR
;
138 efi_cache_sync_image(image_base
, alloc_size
);
140 status
= efi_stub_common(handle
, image
, image_base
, cmdline_ptr
);
143 efi_free(alloc_size
, image_base
);
145 efi_bs_call(free_pool
, cmdline_ptr
);