/* Try calling the kernel compat entry point if one exists. */
if (err == EFI_UNSUPPORTED && entry->type == LOADER_LINUX) {
- uint32_t kernel_entry_address;
+ uint32_t compat_address;
- err = pe_kernel_info(loaded_image->ImageBase, &kernel_entry_address, NULL, NULL);
+ err = pe_kernel_info(loaded_image->ImageBase, &compat_address);
if (err != EFI_SUCCESS) {
if (err != EFI_UNSUPPORTED)
return log_error_status_stall(err, L"Error finding kernel compat entry address: %r", err);
- } else {
+ } else if (compat_address > 0) {
EFI_IMAGE_ENTRY_POINT kernel_entry =
- (EFI_IMAGE_ENTRY_POINT) ((uint8_t *) loaded_image->ImageBase + kernel_entry_address);
+ (EFI_IMAGE_ENTRY_POINT) ((uint8_t *) loaded_image->ImageBase + compat_address);
err = kernel_entry(image, ST);
graphics_mode(false);
if (err == EFI_SUCCESS)
return EFI_SUCCESS;
- }
+ } else
+ err = EFI_UNSUPPORTED;
}
return log_error_status_stall(err, L"Failed to execute %s (%s): %r", entry->title_show, entry->loader, err);
const void *linux_buffer, UINTN linux_length,
const void *initrd_buffer, UINTN initrd_length) {
- uint32_t kernel_alignment, kernel_size_of_image, kernel_entry_address = 0;
+ uint32_t compat_address;
EFI_STATUS err;
assert(parent);
assert(linux_buffer && linux_length > 0);
assert(initrd_buffer || initrd_length == 0);
- /* get the necessary fields from the PE header */
- err = pe_kernel_info(linux_buffer, &kernel_entry_address, &kernel_size_of_image, &kernel_alignment);
+ err = pe_kernel_info(linux_buffer, &compat_address);
#if defined(__i386__) || defined(__x86_64__)
if (err == EFI_UNSUPPORTED)
/* Kernel is too old to support LINUX_INITRD_MEDIA_GUID, try the deprecated EFI handover
err = BS->StartImage(kernel_image, NULL, NULL);
/* Try calling the kernel compat entry point if one exists. */
- if (err == EFI_UNSUPPORTED && kernel_entry_address > 0) {
+ if (err == EFI_UNSUPPORTED && compat_address > 0) {
EFI_IMAGE_ENTRY_POINT compat_entry =
- (EFI_IMAGE_ENTRY_POINT) ((uint8_t *) loaded_image->ImageBase + kernel_entry_address);
+ (EFI_IMAGE_ENTRY_POINT) ((uint8_t *) loaded_image->ImageBase + compat_address);
err = compat_entry(kernel_image, ST);
}
return 0;
}
-EFI_STATUS pe_kernel_info(
- const void *base,
- uint32_t *ret_entry_point_address,
- uint32_t *ret_size_of_image,
- uint32_t *ret_section_alignment) {
-
- const DosFileHeader *dos;
- const PeFileHeader *pe;
-
+EFI_STATUS pe_kernel_info(const void *base, uint32_t *ret_compat_address) {
assert(base);
- assert(ret_entry_point_address);
+ assert(ret_compat_address);
- dos = (const DosFileHeader *) base;
+ const DosFileHeader *dos = (const DosFileHeader *) base;
if (!verify_dos(dos))
return EFI_LOAD_ERROR;
- pe = (const PeFileHeader *) ((const uint8_t *) base + dos->ExeHeader);
+ const PeFileHeader *pe = (const PeFileHeader *) ((const uint8_t *) base + dos->ExeHeader);
if (!verify_pe(pe, /* allow_compatibility= */ true))
return EFI_LOAD_ERROR;
if (pe->OptionalHeader.MajorImageVersion < 1)
return EFI_UNSUPPORTED;
- uint32_t entry_address = pe->OptionalHeader.AddressOfEntryPoint;
-
- /* Look for a compat entry point. */
- if (pe->FileHeader.Machine != TARGET_MACHINE_TYPE) {
- entry_address = get_compatibility_entry_address(dos, pe);
- if (entry_address == 0)
- /* Image type not supported and no compat entry found. */
- return EFI_UNSUPPORTED;
+ if (pe->FileHeader.Machine == TARGET_MACHINE_TYPE) {
+ *ret_compat_address = 0;
+ return EFI_SUCCESS;
}
- *ret_entry_point_address = entry_address;
- if (ret_size_of_image)
- *ret_size_of_image = pe->OptionalHeader.SizeOfImage;
- if (ret_section_alignment)
- *ret_section_alignment = pe->OptionalHeader.SectionAlignment;
+ uint32_t compat_address = get_compatibility_entry_address(dos, pe);
+ if (compat_address == 0)
+ /* Image type not supported and no compat entry found. */
+ return EFI_UNSUPPORTED;
+
+ *ret_compat_address = compat_address;
return EFI_SUCCESS;
}
UINTN *offsets,
UINTN *sizes);
-EFI_STATUS pe_kernel_info(
- const void *base,
- uint32_t *ret_entry_point_address,
- uint32_t *ret_size_of_image,
- uint32_t *ret_section_alignment);
+EFI_STATUS pe_kernel_info(const void *base, uint32_t *ret_compat_address);