@@ -29,6 +29,11 @@ separators will be tried) to be present in the same directory as the binary.
(To illustrate the name handling, a binary named `xen-4.2-unstable.efi` would
try `xen-4.2-unstable.cfg`, `xen-4.2.cfg`, `xen-4.cfg`, and `xen.cfg` in
order.) One can override this with a command line option (`-cfg=<filename>`).
+This configuration file and EFI commandline are only used for booting directly
+from EFI firmware, or when using an simple EFI application loader. When booting
+using a bootloader such as GRUB that loads the dom0 kernel and any other
+required modules, the EFI commandline is ignored. In this case all information
+is passed to Xen using the multiboot2 protocol (x86), or using a FDT (arm64).
The configuration file consists of one or more sections headed by a section
name enclosed in square brackets, with individual values specified in each
@@ -697,7 +697,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS status;
unsigned int i, argc;
CHAR16 **argv, *file_name, *cfg_file_name = NULL, *options = NULL;
- UINTN cols, rows, depth, size, map_key, info_size, gop_mode = ~0;
+ UINTN map_key, info_size, gop_mode = ~0;
EFI_HANDLE *handles = NULL;
EFI_SHIM_LOCK_PROTOCOL *shim_lock;
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop = NULL;
@@ -705,6 +705,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
union string section = { NULL }, name;
bool_t base_video = 0;
char *option_str;
+ bool_t use_cfg_file;
efi_ih = ImageHandle;
efi_bs = SystemTable->BootServices;
@@ -717,6 +718,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
StdOut = SystemTable->ConOut;
StdErr = SystemTable->StdErr ?: StdOut;
+ use_cfg_file = efi_arch_use_config_file(SystemTable);
status = efi_bs->HandleProtocol(ImageHandle, &loaded_image_guid,
(void **)&loaded_image);
@@ -725,67 +727,71 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
efi_arch_load_addr_check(loaded_image);
- argc = get_argv(0, NULL, loaded_image->LoadOptions,
- loaded_image->LoadOptionsSize, NULL);
- if ( argc > 0 &&
- efi_bs->AllocatePool(EfiLoaderData,
- (argc + 1) * sizeof(*argv) +
- loaded_image->LoadOptionsSize,
- (void **)&argv) == EFI_SUCCESS )
- get_argv(argc, argv, loaded_image->LoadOptions,
- loaded_image->LoadOptionsSize, &options);
- else
- argc = 0;
- for ( i = 1; i < argc; ++i )
+ if ( use_cfg_file )
{
- CHAR16 *ptr = argv[i];
-
- if ( !ptr )
- break;
- if ( *ptr == L'/' || *ptr == L'-' )
+ argc = get_argv(0, NULL, loaded_image->LoadOptions,
+ loaded_image->LoadOptionsSize, NULL);
+ if ( argc > 0 &&
+ efi_bs->AllocatePool(EfiLoaderData,
+ (argc + 1) * sizeof(*argv) +
+ loaded_image->LoadOptionsSize,
+ (void **)&argv) == EFI_SUCCESS )
+ get_argv(argc, argv, loaded_image->LoadOptions,
+ loaded_image->LoadOptionsSize, &options);
+ else
+ argc = 0;
+ for ( i = 1; i < argc; ++i )
{
- if ( wstrcmp(ptr + 1, L"basevideo") == 0 )
- base_video = 1;
- else if ( wstrncmp(ptr + 1, L"cfg=", 4) == 0 )
- cfg_file_name = ptr + 5;
- else if ( i + 1 < argc && wstrcmp(ptr + 1, L"cfg") == 0 )
- cfg_file_name = argv[++i];
- else if ( wstrcmp(ptr + 1, L"help") == 0 ||
- (ptr[1] == L'?' && !ptr[2]) )
+ CHAR16 *ptr = argv[i];
+
+ if ( !ptr )
+ break;
+ if ( *ptr == L'/' || *ptr == L'-' )
{
- PrintStr(L"Xen EFI Loader options:\r\n");
- PrintStr(L"-basevideo retain current video mode\r\n");
- PrintStr(L"-cfg=<file> specify configuration file\r\n");
- PrintStr(L"-help, -? display this help\r\n");
- blexit(NULL);
+ if ( wstrcmp(ptr + 1, L"basevideo") == 0 )
+ base_video = 1;
+ else if ( wstrncmp(ptr + 1, L"cfg=", 4) == 0 )
+ cfg_file_name = ptr + 5;
+ else if ( i + 1 < argc && wstrcmp(ptr + 1, L"cfg") == 0 )
+ cfg_file_name = argv[++i];
+ else if ( wstrcmp(ptr + 1, L"help") == 0 ||
+ (ptr[1] == L'?' && !ptr[2]) )
+ {
+ PrintStr(L"Xen EFI Loader options:\r\n");
+ PrintStr(L"-basevideo retain current video mode\r\n");
+ PrintStr(L"-cfg=<file> specify configuration file\r\n");
+ PrintStr(L"-help, -? display this help\r\n");
+ blexit(NULL);
+ }
+ else
+ {
+ PrintStr(L"WARNING: Unknown command line option '");
+ PrintStr(ptr);
+ PrintStr(L"' ignored\r\n");
+ }
}
else
- {
- PrintStr(L"WARNING: Unknown command line option '");
- PrintStr(ptr);
- PrintStr(L"' ignored\r\n");
- }
+ section.w = ptr;
}
- else
- section.w = ptr;
- }
- if ( !base_video )
- {
- unsigned int best;
-
- for ( i = 0, size = 0, best = StdOut->Mode->Mode;
- i < StdOut->Mode->MaxMode; ++i )
+ if ( !base_video )
{
- if ( StdOut->QueryMode(StdOut, i, &cols, &rows) == EFI_SUCCESS &&
- cols * rows > size )
+ unsigned int best;
+ UINTN cols, rows, size;
+
+ for ( i = 0, size = 0, best = StdOut->Mode->Mode;
+ i < StdOut->Mode->MaxMode; ++i )
{
- size = cols * rows;
- best = i;
+ if ( StdOut->QueryMode(StdOut, i, &cols, &rows) == EFI_SUCCESS &&
+ cols * rows > size )
+ {
+ size = cols * rows;
+ best = i;
+ }
}
+ if ( best != StdOut->Mode->Mode )
+ StdOut->SetMode(StdOut, best);
}
- if ( best != StdOut->Mode->Mode )
- StdOut->SetMode(StdOut, best);
}
PrintStr(L"Xen " __stringify(XEN_VERSION) "." __stringify(XEN_SUBVERSION)
@@ -793,37 +799,38 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
efi_arch_relocate_image(0);
- if ( StdOut->QueryMode(StdOut, StdOut->Mode->Mode,
- &cols, &rows) == EFI_SUCCESS )
- efi_arch_console_init(cols, rows);
-
- size = 0;
- status = efi_bs->LocateHandle(ByProtocol, &gop_guid, NULL, &size, NULL);
- if ( status == EFI_BUFFER_TOO_SMALL )
- status = efi_bs->AllocatePool(EfiLoaderData, size, (void **)&handles);
- if ( !EFI_ERROR(status) )
- status = efi_bs->LocateHandle(ByProtocol, &gop_guid, NULL, &size,
- handles);
- if ( EFI_ERROR(status) )
- size = 0;
- for ( i = 0; i < size / sizeof(*handles); ++i )
- {
- status = efi_bs->HandleProtocol(handles[i], &gop_guid, (void **)&gop);
- if ( EFI_ERROR(status) )
- continue;
- status = gop->QueryMode(gop, gop->Mode->Mode, &info_size, &mode_info);
- if ( !EFI_ERROR(status) )
- break;
- }
- if ( handles )
- efi_bs->FreePool(handles);
- if ( EFI_ERROR(status) )
- gop = NULL;
-
- cols = rows = depth = 0;
- if ( efi_arch_use_config_file(SystemTable) )
+ if ( use_cfg_file )
{
EFI_FILE_HANDLE dir_handle;
+ UINTN depth, cols, rows, size;
+
+ size = cols = rows = depth = 0;
+
+ if ( StdOut->QueryMode(StdOut, StdOut->Mode->Mode,
+ &cols, &rows) == EFI_SUCCESS )
+ efi_arch_console_init(cols, rows);
+
+ status = efi_bs->LocateHandle(ByProtocol, &gop_guid, NULL, &size, NULL);
+ if ( status == EFI_BUFFER_TOO_SMALL )
+ status = efi_bs->AllocatePool(EfiLoaderData, size, (void **)&handles);
+ if ( !EFI_ERROR(status) )
+ status = efi_bs->LocateHandle(ByProtocol, &gop_guid, NULL, &size,
+ handles);
+ if ( EFI_ERROR(status) )
+ size = 0;
+ for ( i = 0; i < size / sizeof(*handles); ++i )
+ {
+ status = efi_bs->HandleProtocol(handles[i], &gop_guid, (void **)&gop);
+ if ( EFI_ERROR(status) )
+ continue;
+ status = gop->QueryMode(gop, gop->Mode->Mode, &info_size, &mode_info);
+ if ( !EFI_ERROR(status) )
+ break;
+ }
+ if ( handles )
+ efi_bs->FreePool(handles);
+ if ( EFI_ERROR(status) )
+ gop = NULL;
/* Get the file system interface. */
dir_handle = get_parent_handle(loaded_image, &file_name);
@@ -931,45 +938,44 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
dir_handle->Close(dir_handle);
- }
-
- if ( gop && !base_video )
- {
- for ( i = size = 0; i < gop->Mode->MaxMode; ++i )
+ if ( gop && !base_video )
{
- unsigned int bpp = 0;
-
- status = gop->QueryMode(gop, i, &info_size, &mode_info);
- if ( EFI_ERROR(status) )
- continue;
- switch ( mode_info->PixelFormat )
- {
- case PixelBitMask:
- bpp = hweight32(mode_info->PixelInformation.RedMask |
- mode_info->PixelInformation.GreenMask |
- mode_info->PixelInformation.BlueMask);
- break;
- case PixelRedGreenBlueReserved8BitPerColor:
- case PixelBlueGreenRedReserved8BitPerColor:
- bpp = 24;
- break;
- default:
- continue;
- }
- if ( cols == mode_info->HorizontalResolution &&
- rows == mode_info->VerticalResolution &&
- (!depth || bpp == depth) )
+ for ( i = size = 0; i < gop->Mode->MaxMode; ++i )
{
- gop_mode = i;
- break;
- }
- if ( !cols && !rows &&
- mode_info->HorizontalResolution *
- mode_info->VerticalResolution > size )
- {
- size = mode_info->HorizontalResolution *
- mode_info->VerticalResolution;
- gop_mode = i;
+ unsigned int bpp = 0;
+
+ status = gop->QueryMode(gop, i, &info_size, &mode_info);
+ if ( EFI_ERROR(status) )
+ continue;
+ switch ( mode_info->PixelFormat )
+ {
+ case PixelBitMask:
+ bpp = hweight32(mode_info->PixelInformation.RedMask |
+ mode_info->PixelInformation.GreenMask |
+ mode_info->PixelInformation.BlueMask);
+ break;
+ case PixelRedGreenBlueReserved8BitPerColor:
+ case PixelBlueGreenRedReserved8BitPerColor:
+ bpp = 24;
+ break;
+ default:
+ continue;
+ }
+ if ( cols == mode_info->HorizontalResolution &&
+ rows == mode_info->VerticalResolution &&
+ (!depth || bpp == depth) )
+ {
+ gop_mode = i;
+ break;
+ }
+ if ( !cols && !rows &&
+ mode_info->HorizontalResolution *
+ mode_info->VerticalResolution > size )
+ {
+ size = mode_info->HorizontalResolution *
+ mode_info->VerticalResolution;
+ gop_mode = i;
+ }
}
}
}
Update EFI code to completely ignore the EFI comnandline when booted from GRUB. Previusly it was parsed of EFI boot specific options, but these aren't used when booted from GRUB. Don't do EFI console or video configuration when booted by GRUB. The EFI boot code does some console and video initialization to support native EFI boot from the EFI boot manager or EFI shell. This initlization should not be done when booted using GRUB. Update EFI documentation to indicate that it describes EFI native boot, and does not apply at all when Xen is booted using GRUB. Signed-off-by: Roy Franz <roy.franz@linaro.org> --- --- This patch implements what I understand to be the desired behavior when booting an EFI Xen image via GRUB based on the thread last week. The EFI command line is not used, and the Xen commandline comes via the multiboot protocol (and in the ARM case the multiboot FDT bindings). This brings the x86 and arm64 GRUB EFI boot cases into alignment in not using the EFI commandline. The current state of the arm64 code takes the Xen commandline from the FDT, but still looks in the EFI commandline for EFI boot specific options. If unexpected options are passed in the EFI commandline, it will generate "unrecognized option" ouput for all unexpected options. I think this should be considered for 4.5. Changes since v2: * Rephrased documentation update to avoid "multi-boot aware bootloader", as this is a more general concept that implies things not required for this patch. Changes from v1: * Fixed style, and removed blank line changes * Reviewed scope of variables now that more code is in if ( use_cfg_file ) block docs/misc/efi.markdown | 5 ++ xen/common/efi/boot.c | 240 +++++++++++++++++++++++++------------------------ 2 files changed, 128 insertions(+), 117 deletions(-)