1 /* SPDX-License-Identifier: LGPL-2.1+ */
10 typedef VOID(*handover_f
)(VOID
*image
, EFI_SYSTEM_TABLE
*table
, struct boot_params
*params
);
11 static VOID
linux_efi_handover(EFI_HANDLE image
, struct boot_params
*params
) {
15 handover
= (handover_f
)((UINTN
)params
->hdr
.code32_start
+ 512 + params
->hdr
.handover_offset
);
16 handover(image
, ST
, params
);
19 typedef VOID(*handover_f
)(VOID
*image
, EFI_SYSTEM_TABLE
*table
, struct boot_params
*params
) __attribute__((regparm(0)));
20 static VOID
linux_efi_handover(EFI_HANDLE image
, struct boot_params
*params
) {
23 handover
= (handover_f
)((UINTN
)params
->hdr
.code32_start
+ params
->hdr
.handover_offset
);
24 handover(image
, ST
, params
);
28 EFI_STATUS
linux_exec(EFI_HANDLE
*image
,
29 CHAR8
*cmdline
, UINTN cmdline_len
,
31 UINTN initrd_addr
, UINTN initrd_size
) {
32 struct boot_params
*image_params
;
33 struct boot_params
*boot_params
;
35 EFI_PHYSICAL_ADDRESS addr
;
38 image_params
= (struct boot_params
*) linux_addr
;
40 if (image_params
->hdr
.boot_flag
!= 0xAA55 ||
41 image_params
->hdr
.header
!= SETUP_MAGIC
||
42 image_params
->hdr
.version
< 0x20b ||
43 !image_params
->hdr
.relocatable_kernel
)
44 return EFI_LOAD_ERROR
;
46 boot_params
= (struct boot_params
*) 0xFFFFFFFF;
47 err
= uefi_call_wrapper(BS
->AllocatePages
, 4, AllocateMaxAddress
, EfiLoaderData
,
48 EFI_SIZE_TO_PAGES(0x4000), (UINTN
*) &boot_params
);
52 ZeroMem(boot_params
, 0x4000);
53 CopyMem(&boot_params
->hdr
, &image_params
->hdr
, sizeof(struct setup_header
));
54 boot_params
->hdr
.type_of_loader
= 0xff;
55 setup_sectors
= image_params
->hdr
.setup_sects
> 0 ? image_params
->hdr
.setup_sects
: 4;
56 boot_params
->hdr
.code32_start
= (UINT32
)linux_addr
+ (setup_sectors
+ 1) * 512;
60 err
= uefi_call_wrapper(BS
->AllocatePages
, 4, AllocateMaxAddress
, EfiLoaderData
,
61 EFI_SIZE_TO_PAGES(cmdline_len
+ 1), &addr
);
64 CopyMem((VOID
*)(UINTN
)addr
, cmdline
, cmdline_len
);
65 ((CHAR8
*)(UINTN
)addr
)[cmdline_len
] = 0;
66 boot_params
->hdr
.cmd_line_ptr
= (UINT32
)addr
;
69 boot_params
->hdr
.ramdisk_image
= (UINT32
)initrd_addr
;
70 boot_params
->hdr
.ramdisk_size
= (UINT32
)initrd_size
;
72 linux_efi_handover(image
, boot_params
);
73 return EFI_LOAD_ERROR
;