On 3/18/12 11:45 AM, Shea Levy wrote: > Hello, > > Inlined is a patch to have the kernel read its parameters from a > config file when booted via the EFI boot stub without any parameters > passed. This patch roughly follows the plan I discussed when proposing > this idea, except now the file is found relative to the location of > the bzImage and there is no additional check to see if > image->parent_handle is NULL (despite the spec saying it will be NULL > when the image was loaded by the firmware itself, it was never NULL on > any of the systems I tested). > > Cheers, > Shea Levy > > --- > > From 2c12b0f49831d2d96b6bdcef931794178312c288 Mon Sep 17 00:00:00 2001 > From: Shea Levy > Date: Sun, 18 Mar 2012 16:17:04 +0100 > Subject: [PATCH 1/1] x86, efi: EFI boot stub config file support > > When booting via the EFI boot stub, search for a file named > 'linux.conf' in > the same directory as the bzImage and read the kernel command line > from it > when no load options are passed. > > The file search should only be triggered when the bzImage is loaded > from the > firmware's boot process. When loaded via an EFI shell, the load > options always > contain at least one character, even if no parameters were passed at the > prompt. > > Signed-off-by: Shea Levy > --- > arch/x86/boot/compressed/eboot.c | 146 > ++++++++++++++++++++++++++++++++++++-- > arch/x86/boot/compressed/eboot.h | 2 + > 2 files changed, 143 insertions(+), 5 deletions(-) > > diff --git a/arch/x86/boot/compressed/eboot.c > b/arch/x86/boot/compressed/eboot.c > index fec216f..672ecfe 100644 > --- a/arch/x86/boot/compressed/eboot.c > +++ b/arch/x86/boot/compressed/eboot.c > @@ -486,14 +486,14 @@ struct initrd { > * kernel image. > */ > static efi_status_t handle_ramdisks(efi_loaded_image_t *image, > - struct setup_header *hdr) > + struct setup_header *hdr, > + efi_file_handle_t *fh) > { > struct initrd *initrds; > unsigned long initrd_addr; > efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID; > u64 initrd_total; > efi_file_io_interface_t *io; > - efi_file_handle_t *fh; > efi_status_t status; > int nr_initrds; > char *str; > @@ -568,7 +568,7 @@ static efi_status_t > handle_ramdisks(efi_loaded_image_t *image, > *p = '\0'; > > /* Only open the volume once. */ > - if (!i) { > + if (!fh) { > efi_boot_services_t *boottime; > > boottime = sys_table->boottime; > @@ -712,6 +712,7 @@ static efi_status_t make_boot_params(struct > boot_params *boot_params, > u16 *s2; > u8 *s1; > int i; > + efi_file_handle_t *fh = NULL; > > hdr->type_of_loader = 0x21; > > @@ -743,14 +744,149 @@ static efi_status_t make_boot_params(struct > boot_params *boot_params, > > *s1 = '\0'; > } > - } > + } else { > + efi_char16_t config_file_name[ > + sizeof CONFIG_FILE_NAME * sizeof(efi_char16_t)]; > + u16 *file_path = (u16 *)image->file_path; > + efi_char16_t config_path[256], *config_path_position; > + efi_boot_services_t *boottime; > + efi_file_info_t *info; > + unsigned long info_sz = 0; > + u64 file_sz; > + efi_guid_t info_guid = EFI_FILE_INFO_ID; > + efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID; > + efi_file_io_interface_t *io; > + efi_file_handle_t *h; > + > + boottime = sys_table->boottime; > + > + config_path_position = config_path; > + > + for (i = 0; i < sizeof CONFIG_FILE_NAME; i++) > + config_file_name[i] = CONFIG_FILE_NAME[i]; > + > + while (*file_path == 0x404) { > + u16 node_size = *(file_path + 1)/sizeof *file_path; > + > + if (config_path_position - config_path) { > + if (*(file_path + 2) == '\\' && > + *(file_path - 2) == '\\') { > + config_path_position--; > + } else if (*(file_path + 2) != '\\' && > + *(file_path - 2) != '\\') { > + *config_path_position++ = '\\'; > + } > + } > + > + if ((config_path_position - config_path) + node_size - 3 > + + sizeof config_file_name > + / sizeof *config_file_name > + > sizeof config_path > + / sizeof *config_path) > + goto end; > + > + memcpy((void *)config_path_position, file_path + 2, > + (node_size - 3) * sizeof *config_path); > > + config_path_position += node_size - 3; > + file_path += node_size; > + } > + > + while (*config_path_position != '\\' && config_path_position != > + config_path) > + config_path_position--; > + > + *config_path_position = '\\'; > + > + memcpy((void *)(config_path_position + 1), > + config_file_name, > + sizeof config_file_name); > + > + status = efi_call_phys3(boottime->handle_protocol, > + image->device_handle, &fs_proto, &io); > + > + if (status != EFI_SUCCESS) > + goto end; > + > + status = efi_call_phys2(io->open_volume, io, &fh); > + > + if (status != EFI_SUCCESS) { > + fh = NULL; > + goto end; > + } > + > + status = efi_call_phys5(fh->open, > + fh, > + &h, > + config_path, > + EFI_FILE_MODE_READ, (u64)0); > + > + if (status != EFI_SUCCESS) > + goto end; > + > + status = efi_call_phys4(h->get_info, h, &info_guid, > + &info_sz, NULL); > + > + if (status != EFI_BUFFER_TOO_SMALL) > + goto close_config_file; > + > + while (status == EFI_BUFFER_TOO_SMALL) { > + status = efi_call_phys3(boottime->allocate_pool, > + EFI_LOADER_DATA, info_sz, &info); > + > + if (status != EFI_SUCCESS) > + goto close_config_file; > + > + status = efi_call_phys4(h->get_info, h, &info_guid, > + &info_sz, info); > + > + if (status == EFI_BUFFER_TOO_SMALL) > + efi_call_phys1(boottime->free_pool, info); > + } > + > + if (status != EFI_SUCCESS) > + goto free_config_file_info; > + > + file_sz = info->file_size; > + > + if (file_sz > hdr->cmdline_size) > + file_sz = hdr->cmdline_size; > + > + options_size = file_sz + 1; > + > + status = low_alloc(options_size, 1, &cmdline); > + > + if (status != EFI_SUCCESS) > + goto free_config_file_info; > + > + status = efi_call_phys3(h->read, h, &file_sz, cmdline); > + > + if (status != EFI_SUCCESS) > + goto free_config_file_cmdline; > + > + *((u8 *)cmdline + file_sz) = 0; > + > + goto free_config_file_info; > +free_config_file_cmdline: > + low_free(options_size, cmdline); > + cmdline = 0; > + options_size = 0; > +free_config_file_info: > + efi_call_phys1(boottime->free_pool, info); > +close_config_file: > + efi_call_phys1(h->close, h); > + } > +end: > hdr->cmd_line_ptr = cmdline; > > hdr->ramdisk_image = 0; > hdr->ramdisk_size = 0; > > - status = handle_ramdisks(image, hdr); > + status = handle_ramdisks(image, hdr, fh); > + > + if (fh) > + efi_call_phys1(fh->close, fh); > + > if (status != EFI_SUCCESS) > goto free_cmdline; > > diff --git a/arch/x86/boot/compressed/eboot.h > b/arch/x86/boot/compressed/eboot.h > index 3925166..186b4c6 100644 > --- a/arch/x86/boot/compressed/eboot.h > +++ b/arch/x86/boot/compressed/eboot.h > @@ -20,6 +20,8 @@ > #define PIXEL_BLT_ONLY 3 > #define PIXEL_FORMAT_MAX 4 > > +#define CONFIG_FILE_NAME "linux.conf" > + > struct efi_pixel_bitmask { > u32 red_mask; > u32 green_mask; Hmm, my mail client seems to have mangled the patch. I've attached it here.