efi/chainload: Support passing of command lines. Addresses #244
This commit is contained in:
parent
a085af55ec
commit
ac1c5d1b95
|
@ -97,7 +97,7 @@ Editor control options.
|
||||||
*Locally assignable (non protocol specific)* keys are:
|
*Locally assignable (non protocol specific)* keys are:
|
||||||
* `COMMENT` - An optional comment string that will be displayed by the bootloader on the menu when an entry is selected.
|
* `COMMENT` - An optional comment string that will be displayed by the bootloader on the menu when an entry is selected.
|
||||||
* `PROTOCOL` - The boot protocol that will be used to boot the kernel. Valid protocols are: `linux`, `limine`, `chainload`, `chainload_next`, `multiboot` (or `multiboot1`), and `multiboot2`.
|
* `PROTOCOL` - The boot protocol that will be used to boot the kernel. Valid protocols are: `linux`, `limine`, `chainload`, `chainload_next`, `multiboot` (or `multiboot1`), and `multiboot2`.
|
||||||
* `CMDLINE` - The command line string to be passed to the kernel. Can be omitted.
|
* `CMDLINE` - The command line string to be passed to the kernel/executable. Can be omitted.
|
||||||
* `KERNEL_CMDLINE` - Alias of `CMDLINE`.
|
* `KERNEL_CMDLINE` - Alias of `CMDLINE`.
|
||||||
|
|
||||||
*Locally assignable (protocol specific)* keys are:
|
*Locally assignable (protocol specific)* keys are:
|
||||||
|
|
|
@ -975,9 +975,9 @@ noreturn void boot(char *config) {
|
||||||
print("Multiboot 2 is not available on aarch64.\n\n");
|
print("Multiboot 2 is not available on aarch64.\n\n");
|
||||||
#endif
|
#endif
|
||||||
} else if (!strcmp(proto, "chainload_next")) {
|
} else if (!strcmp(proto, "chainload_next")) {
|
||||||
chainload_next(config);
|
chainload_next(config, cmdline);
|
||||||
} else if (!strcmp(proto, "chainload")) {
|
} else if (!strcmp(proto, "chainload")) {
|
||||||
chainload(config);
|
chainload(config, cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
panic(true, "Unsupported protocol specified for kernel.");
|
panic(true, "Unsupported protocol specified for kernel.");
|
||||||
|
|
|
@ -72,7 +72,9 @@ noreturn static void spinup(uint8_t drive) {
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
noreturn void chainload(char *config) {
|
noreturn void chainload(char *config, char *cmdline) {
|
||||||
|
(void)cmdline;
|
||||||
|
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
|
|
||||||
int part; {
|
int part; {
|
||||||
|
@ -188,7 +190,7 @@ void bios_chainload_volume(struct volume *p) {
|
||||||
|
|
||||||
#elif defined (UEFI)
|
#elif defined (UEFI)
|
||||||
|
|
||||||
noreturn void chainload(char *config) {
|
noreturn void chainload(char *config, char *cmdline) {
|
||||||
char *image_path = config_get_value(config, 0, "IMAGE_PATH");
|
char *image_path = config_get_value(config, 0, "IMAGE_PATH");
|
||||||
if (image_path == NULL)
|
if (image_path == NULL)
|
||||||
panic(true, "chainload: IMAGE_PATH not specified");
|
panic(true, "chainload: IMAGE_PATH not specified");
|
||||||
|
@ -197,10 +199,10 @@ noreturn void chainload(char *config) {
|
||||||
if ((image = uri_open(image_path)) == NULL)
|
if ((image = uri_open(image_path)) == NULL)
|
||||||
panic(true, "chainload: Failed to open image with path `%s`. Is the path correct?", image_path);
|
panic(true, "chainload: Failed to open image with path `%s`. Is the path correct?", image_path);
|
||||||
|
|
||||||
efi_chainload_file(config, image);
|
efi_chainload_file(config, cmdline, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
noreturn void efi_chainload_file(char *config, struct file_handle *image) {
|
noreturn void efi_chainload_file(char *config, char *cmdline, struct file_handle *image) {
|
||||||
EFI_STATUS status;
|
EFI_STATUS status;
|
||||||
|
|
||||||
EFI_HANDLE efi_part_handle = image->efi_part_handle;
|
EFI_HANDLE efi_part_handle = image->efi_part_handle;
|
||||||
|
@ -228,6 +230,16 @@ noreturn void efi_chainload_file(char *config, struct file_handle *image) {
|
||||||
size_t fb_count;
|
size_t fb_count;
|
||||||
fb_init(&fbinfo, &fb_count, req_width, req_height, req_bpp);
|
fb_init(&fbinfo, &fb_count, req_width, req_height, req_bpp);
|
||||||
|
|
||||||
|
size_t cmdline_len = strlen(cmdline);
|
||||||
|
CHAR16 *new_cmdline;
|
||||||
|
status = gBS->AllocatePool(EfiLoaderData, cmdline_len * sizeof(CHAR16), (void **)&new_cmdline);
|
||||||
|
if (status) {
|
||||||
|
panic(true, "chainload: Allocation failure");
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < cmdline_len + 1; i++) {
|
||||||
|
new_cmdline[i] = cmdline[i];
|
||||||
|
}
|
||||||
|
|
||||||
pmm_release_uefi_mem();
|
pmm_release_uefi_mem();
|
||||||
|
|
||||||
MEMMAP_DEVICE_PATH memdev_path[2];
|
MEMMAP_DEVICE_PATH memdev_path[2];
|
||||||
|
@ -270,6 +282,9 @@ noreturn void efi_chainload_file(char *config, struct file_handle *image) {
|
||||||
new_handle_loaded_image->DeviceHandle = efi_part_handle;
|
new_handle_loaded_image->DeviceHandle = efi_part_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new_handle_loaded_image->LoadOptionsSize = cmdline_len;
|
||||||
|
new_handle_loaded_image->LoadOptions = new_cmdline;
|
||||||
|
|
||||||
UINTN exit_data_size = 0;
|
UINTN exit_data_size = 0;
|
||||||
CHAR16 *exit_data = NULL;
|
CHAR16 *exit_data = NULL;
|
||||||
EFI_STATUS exit_status = gBS->StartImage(new_handle, &exit_data_size, &exit_data);
|
EFI_STATUS exit_status = gBS->StartImage(new_handle, &exit_data_size, &exit_data);
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
#include <stdnoreturn.h>
|
#include <stdnoreturn.h>
|
||||||
|
|
||||||
noreturn void chainload(char *config);
|
noreturn void chainload(char *config, char *cmdline);
|
||||||
|
|
||||||
#if defined (UEFI)
|
#if defined (UEFI)
|
||||||
#include <fs/file.h>
|
#include <fs/file.h>
|
||||||
noreturn void efi_chainload_file(char *config, struct file_handle *image);
|
noreturn void efi_chainload_file(char *config, char *cmdline, struct file_handle *image);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (BIOS)
|
#if defined (BIOS)
|
||||||
|
|
|
@ -8,14 +8,15 @@
|
||||||
#include <lib/part.h>
|
#include <lib/part.h>
|
||||||
|
|
||||||
#if defined (BIOS)
|
#if defined (BIOS)
|
||||||
static void try(char *config, struct volume *v) {
|
static void try(char *config, char *cmdline, struct volume *v) {
|
||||||
(void)config;
|
(void)config;
|
||||||
|
(void)cmdline;
|
||||||
bios_chainload_volume(v);
|
bios_chainload_volume(v);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (UEFI)
|
#if defined (UEFI)
|
||||||
static void try(char *config, struct volume *v) {
|
static void try(char *config, char *cmdline, struct volume *v) {
|
||||||
for (int i = 0; i <= v->max_partition + 1; i++) {
|
for (int i = 0; i <= v->max_partition + 1; i++) {
|
||||||
struct file_handle *image;
|
struct file_handle *image;
|
||||||
struct volume *p = volume_get_by_coord(v->is_optical, v->index, i);
|
struct volume *p = volume_get_by_coord(v->is_optical, v->index, i);
|
||||||
|
@ -28,12 +29,12 @@ static void try(char *config, struct volume *v) {
|
||||||
}
|
}
|
||||||
case_insensitive_fopen = old_cif;
|
case_insensitive_fopen = old_cif;
|
||||||
|
|
||||||
efi_chainload_file(config, image);
|
efi_chainload_file(config, cmdline, image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
noreturn void chainload_next(char *config) {
|
noreturn void chainload_next(char *config, char *cmdline) {
|
||||||
bool wrap = false;
|
bool wrap = false;
|
||||||
for (int i = boot_volume->is_optical ? 0 : (wrap = true, boot_volume->index + 1);
|
for (int i = boot_volume->is_optical ? 0 : (wrap = true, boot_volume->index + 1);
|
||||||
boot_volume->is_optical ? true : i != boot_volume->index; i++) {
|
boot_volume->is_optical ? true : i != boot_volume->index; i++) {
|
||||||
|
@ -47,7 +48,7 @@ noreturn void chainload_next(char *config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try(config, v);
|
try(config, cmdline, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
wrap = false;
|
wrap = false;
|
||||||
|
@ -63,7 +64,7 @@ noreturn void chainload_next(char *config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try(config, v);
|
try(config, cmdline, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
panic(true, "chainload_next: No other bootable device");
|
panic(true, "chainload_next: No other bootable device");
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
#include <stdnoreturn.h>
|
#include <stdnoreturn.h>
|
||||||
|
|
||||||
noreturn void chainload_next(char *config);
|
noreturn void chainload_next(char *config, char *cmdline);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue