From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) by mx.groups.io with SMTP id smtpd.web12.4073.1583244083923910549 for ; Tue, 03 Mar 2020 06:01:24 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@linaro.org header.s=google header.b=GMvFQGks; spf=pass (domain: linaro.org, ip: 209.85.128.67, mailfrom: ard.biesheuvel@linaro.org) Received: by mail-wm1-f67.google.com with SMTP id i9so1914139wml.4 for ; Tue, 03 Mar 2020 06:01:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=Vbp68XJG3OobgNsdPZYZrJWlSJFwQYOnlV0qt3WHRfQ=; b=GMvFQGksYI1YgwnhbvbDPlxa4+q6wcMBQPzmw8o43xJDSQI1P38wPHng0oOmBr/w0h 0oJ4YYTRiKWbqYi+0hvMkEpKUOWirEciLG6Vg1yBNybtAZ6TuOsJ1Vb6iAyggZuijkMx JuirVv+gL+AyxHDi4x6yWvyI1VkBmVWv0kYvo8RBjQoUiw2+rT1YcZ2sBuUwmmQyEIIB CKV1i+5mZk7wBBjB4PodUeG7/7PHhYPcx77Mg6qSctWkeSsjzih8yjJelh1yw8vQgz5j 57lctXdGvkDpLkLJqg4zHmADYvF/4GFf9KhNqVSvQpCx32izEIpiDXhsygd4pzwif0G1 7JIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=Vbp68XJG3OobgNsdPZYZrJWlSJFwQYOnlV0qt3WHRfQ=; b=XYXUoXU1m6JQ1iRLGgovBlhBzqtKTzMSmDAudj8trgZSuxevBzzDpSg1h/dWMqvs9a jc7ytiV2XrpYXKCiUQIjSlbTO8qjOiXAsc5qz9Z/cWXxnUgrZnoJ9lurEcmEWHe8eZh6 pwKUjSE5TxdWMDDtv/h9vS9xPsxm+mcd7X+9d2uCpUJc1w3a3FvnnKBpizh7ZU3kHFXX Z5QCgOZFdncQNzn5yqIDglK3QPp8NTpTf+SvXmV2OOTYcCBM+lffpkPbcFMWP8KWTneo MFVVsqo8zbmKPVZFE8cpriyX5bGtGFGtHfVHRNVQ2hZ7XCeJHJJgl0myEXUrna1zbz0x g19g== X-Gm-Message-State: ANhLgQ18d5wqLBn7bYRi2Yrpvy83fmoliDZIFMoVLe6VOC7XN83mV4OV oJQQwUffvlrDuskCIFlcRwfVwVh5fAL9mg== X-Google-Smtp-Source: ADFU+vvBnU4s8El55vzocD1FTMNH9z+ak9Qz/ALIz4TKJotIADGI7JHzxRVpueDKNEeffiA/bDdpKw== X-Received: by 2002:a7b:cb90:: with SMTP id m16mr1147145wmi.105.1583244081942; Tue, 03 Mar 2020 06:01:21 -0800 (PST) Return-Path: Received: from e123331-lin.home ([2a01:cb1d:112:6f00:816e:ff0d:fb69:f613]) by smtp.gmail.com with ESMTPSA id i10sm27575122wrn.53.2020.03.03.06.01.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Mar 2020 06:01:21 -0800 (PST) From: "Ard Biesheuvel" To: devel@edk2.groups.io Cc: Ard Biesheuvel , lersek@redhat.com, leif@nuviainc.com, Liming Gao Subject: [PATCH v4 0/7] OvmfPkg: implement initrd shell command and mixed mode loader Date: Tue, 3 Mar 2020 15:01:10 +0100 Message-Id: <20200303140117.7288-1-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.17.1 This series is part of my effort to define a generic EFI boot protocol for Linux, i.e,. one that is the same across all different architectures that are able to boot Linux from EFI, and naturally reused the firmware's infrastructure for authenticated boot and measured boot. Path #1 ... #4 implement the 'initrd' dynamic shell command, which takes a file and exposes it via the LoadFile2 protocol installed on a vendor media device path with guid LINUX_EFI_INITRD_MEDIA_GUID. This is a Linux specific, but arch-agnostic way for the OS loader to load an initial ramdisk, while leaving the firmware (or bootloader) in charge of where the file contents are served from. This supersedes the currently existing solutions on Linux, which are either limited to loading from the same volume that the OS loader was loaded from, or load the initrd into memory first, and use architecture specific data structures to pass on the information regarding base and size. Patch #5 is an update to the integration of the PE/COFF emulator protocol, to align it more closely with how LoadImage() and StartImage() behave today: LoadImage() is not restricted to images that can execute natively on the platform, but also permits loading of cross-type supported images. This means that any judgement on whether an image can be *started* needs to be deferred until StartImage(), which is why the invocation of the RegisterImage() callback needs to be deferred as well. Patch #6 implements the PE/COFF emulator protocol so it can start X64 images that have been loaded on IA32 firmware. This is needed for Linux's so-called 'mixed mode', which is an elaborate scheme of on-the-fly translation of data structures and thunking into 32-bit compat mode, allowing X64 Linux kernels to be used on X64 capable hardware that shipped with IA32 firmware. This needs support from the loader, and is currently implemented in GRUB (and OVMF's command line kernel loader) using the EFI handover protocol, which relies far too much on knowledge of kernel internal data structures, and circumvents LoadImage and StartImage entirely. (Note: mixed mode support is mainly targeted at cheap Atom tablets that shipped with a [cheaper] 32-bit version of Windows, and so this particular patch is unlikely to help that use case, but it is useful for validation.) Patch #7 is new in v4, and modified the initrd Shell command so it aborts immediately if the Linux initrd media GUID device path already has the LoadFile2 protocol installed in the protocol database. With these changes in place, we can boot x86 mixed-mode Linux straight from the UEFI Shell Shell>initrd fs0:\initrd.img Shell>fs0:\bzImage root=/dev/vda2 Another benefit of this approach is that we can exit cleanly from the loader (and back to the shell) using the Exit() boot service if any errors occur, whereas the EFI handover protocol enters a deadloop upon any error that occurs during execution of the EFI stub. Changes since v3: - pick up some acks - update patch #6 to sanity check the contents of the .compat section so we don't overrun the end of the section looking for a compatible entrypoint - add patch #7 Changes since v2: - incorporate Laszlo's feedback, and add R-b's - I have incorporated all the feedback given, except for the structure of the shell command implementation: it is not my preferred style, but it is correct, and idiomatic for the shell commands I could find in the tree. Changes from v1: - Use a dynamic UEFI shell command, which is the recommended way of implementing new shell commands that are not covered by the UEFI shell specification. It also makes the command more easily usable on existing platforms, since the driver can be loaded as an ordinary driver. - split initrd patch into 4, as requested by Laszlo - add patch to tweak the LoadImage/StartImage behavior wrt the PE/COFF emulator protocol - return EFI_UNSUPPORTED from PeCoffEmu::RegisterImage() if the image does not have the required .compat section [0] https://edk2.groups.io/g/devel/topic/rfc_patch_1_1_ovmfpkg_add/71177416 [1] https://edk2.groups.io/g/devel/topic/patch_1_1_ovmfpkg_ia32_add/71272266 v2: https://edk2.groups.io/g/devel/topic/patch_v2_0_6_ovmfpkg/71530294 v3: https://edk2.groups.io/g/devel/message/54932 Cc: lersek@redhat.com Cc: leif@nuviainc.com Cc: Liming Gao Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2564 Ard Biesheuvel (7): OvmfPkg: add definition of LINUX_EFI_INITRD_MEDIA_GUID OvmfPkg: add 'initrd' shell command to expose Linux initrd via device path ArmVirtPkg: add the 'initrd' dynamic shell command OvmfPkg: add the 'initrd' dynamic shell command MdeModulePkg/DxeCore: defer PE/COFF emulator registration to StartImage OvmfPkg IA32: add support for loading X64 images OvmfPkg/LinuxInitrdDynamicShellCommand: bail if initrd already exists ArmVirtPkg/ArmVirt.dsc.inc | 4 + ArmVirtPkg/ArmVirtQemuFvMain.fdf.inc | 1 + ArmVirtPkg/ArmVirtXen.fdf | 1 + MdeModulePkg/Core/Dxe/Image/Image.c | 24 +- .../CompatImageLoaderDxe.c | 143 ++++++ .../CompatImageLoaderDxe.inf | 37 ++ OvmfPkg/Include/Guid/LinuxEfiInitrdMedia.h | 17 + .../LinuxInitrdDynamicShellCommand.c | 460 ++++++++++++++++++ .../LinuxInitrdDynamicShellCommand.inf | 53 ++ .../LinuxInitrdDynamicShellCommand.uni | 52 ++ OvmfPkg/OvmfPkg.dec | 1 + OvmfPkg/OvmfPkgIa32.dsc | 9 + OvmfPkg/OvmfPkgIa32.fdf | 5 + OvmfPkg/OvmfPkgIa32X64.dsc | 4 + OvmfPkg/OvmfPkgIa32X64.fdf | 1 + OvmfPkg/OvmfPkgX64.dsc | 4 + OvmfPkg/OvmfPkgX64.fdf | 1 + OvmfPkg/OvmfXen.dsc | 4 + OvmfPkg/OvmfXen.fdf | 1 + 19 files changed, 811 insertions(+), 11 deletions(-) create mode 100644 OvmfPkg/CompatImageLoaderDxe/CompatImageLoaderDxe.c create mode 100644 OvmfPkg/CompatImageLoaderDxe/CompatImageLoaderDxe.inf create mode 100644 OvmfPkg/Include/Guid/LinuxEfiInitrdMedia.h create mode 100644 OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.c create mode 100644 OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf create mode 100644 OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.uni -- 2.17.1