[edk2-devel] [PATCH v3 12/14] OvmfPkg/PlatformBootManagerLib: switch to QemuLoadImageLib

Ard Biesheuvel posted 14 patches 5 years, 11 months ago
[edk2-devel] [PATCH v3 12/14] OvmfPkg/PlatformBootManagerLib: switch to QemuLoadImageLib
Posted by Ard Biesheuvel 5 years, 11 months ago
Replace the open coded sequence to load Linux on x86 with a short and
generic sequence invoking QemuLoadImageLib, which can be provided by
a generic version that only supports the LoadImage and StartImage boot
services, and one that incorporates the entire legacy loading sequence
as well.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2566
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
---
 OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf |   2 +-
 OvmfPkg/Library/PlatformBootManagerLib/QemuKernel.c               | 144 ++------------------
 2 files changed, 14 insertions(+), 132 deletions(-)

diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
index c479f113b92b..e470b9a6a3e5 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -49,7 +49,7 @@ [LibraryClasses]
   NvVarsFileLib
   QemuFwCfgLib
   QemuFwCfgS3Lib
-  LoadLinuxLib
+  QemuLoadImageLib
   QemuBootOrderLib
   ReportStatusCodeLib
   UefiLib
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/QemuKernel.c b/OvmfPkg/Library/PlatformBootManagerLib/QemuKernel.c
index ddfef925edd3..c6255921779e 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/QemuKernel.c
+++ b/OvmfPkg/Library/PlatformBootManagerLib/QemuKernel.c
@@ -9,11 +9,8 @@
 
 #include <Library/BaseLib.h>
 #include <Library/DebugLib.h>
-#include <Library/LoadLinuxLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/QemuFwCfgLib.h>
+#include <Library/QemuLoadImageLib.h>
 #include <Library/ReportStatusCodeLib.h>
-#include <Library/UefiBootServicesTableLib.h>
 #include <Library/UefiLib.h>
 
 
@@ -23,120 +20,11 @@ TryRunningQemuKernel (
   )
 {
   EFI_STATUS                Status;
-  UINTN                     KernelSize;
-  UINTN                     KernelInitialSize;
-  VOID                      *KernelBuf;
-  UINTN                     SetupSize;
-  VOID                      *SetupBuf;
-  UINTN                     CommandLineSize;
-  CHAR8                     *CommandLine;
-  UINTN                     InitrdSize;
-  VOID*                     InitrdData;
+  EFI_HANDLE                KernelImageHandle;
 
-  SetupBuf = NULL;
-  SetupSize = 0;
-  KernelBuf = NULL;
-  KernelInitialSize = 0;
-  CommandLine = NULL;
-  CommandLineSize = 0;
-  InitrdData = NULL;
-  InitrdSize = 0;
-
-  if (!QemuFwCfgIsAvailable ()) {
-    return EFI_NOT_FOUND;
-  }
-
-  QemuFwCfgSelectItem (QemuFwCfgItemKernelSize);
-  KernelSize = (UINTN) QemuFwCfgRead64 ();
-
-  QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupSize);
-  SetupSize = (UINTN) QemuFwCfgRead64 ();
-
-  if (KernelSize == 0 || SetupSize == 0) {
-    DEBUG ((EFI_D_INFO, "qemu -kernel was not used.\n"));
-    return EFI_NOT_FOUND;
-  }
-
-  SetupBuf = LoadLinuxAllocateKernelSetupPages (EFI_SIZE_TO_PAGES (SetupSize));
-  if (SetupBuf == NULL) {
-    DEBUG ((EFI_D_ERROR, "Unable to allocate memory for kernel setup!\n"));
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  DEBUG ((EFI_D_INFO, "Setup size: 0x%x\n", (UINT32) SetupSize));
-  DEBUG ((EFI_D_INFO, "Reading kernel setup image ..."));
-  QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupData);
-  QemuFwCfgReadBytes (SetupSize, SetupBuf);
-  DEBUG ((EFI_D_INFO, " [done]\n"));
-
-  Status = LoadLinuxCheckKernelSetup (SetupBuf, SetupSize);
-  if (EFI_ERROR (Status)) {
-    goto FreeAndReturn;
-  }
-
-  Status = LoadLinuxInitializeKernelSetup (SetupBuf);
-  if (EFI_ERROR (Status)) {
-    goto FreeAndReturn;
-  }
-
-  KernelInitialSize = LoadLinuxGetKernelSize (SetupBuf, KernelSize);
-  if (KernelInitialSize == 0) {
-    Status = EFI_UNSUPPORTED;
-    goto FreeAndReturn;
-  }
-
-  KernelBuf = LoadLinuxAllocateKernelPages (
-                SetupBuf,
-                EFI_SIZE_TO_PAGES (KernelInitialSize));
-  if (KernelBuf == NULL) {
-    DEBUG ((EFI_D_ERROR, "Unable to allocate memory for kernel!\n"));
-    Status = EFI_OUT_OF_RESOURCES;
-    goto FreeAndReturn;
-  }
-
-  DEBUG ((EFI_D_INFO, "Kernel size: 0x%x\n", (UINT32) KernelSize));
-  DEBUG ((EFI_D_INFO, "Reading kernel image ..."));
-  QemuFwCfgSelectItem (QemuFwCfgItemKernelData);
-  QemuFwCfgReadBytes (KernelSize, KernelBuf);
-  DEBUG ((EFI_D_INFO, " [done]\n"));
-
-  QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);
-  CommandLineSize = (UINTN) QemuFwCfgRead64 ();
-
-  if (CommandLineSize > 0) {
-    CommandLine = LoadLinuxAllocateCommandLinePages (
-                    EFI_SIZE_TO_PAGES (CommandLineSize));
-    QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData);
-    QemuFwCfgReadBytes (CommandLineSize, CommandLine);
-  } else {
-    CommandLine = NULL;
-  }
-
-  Status = LoadLinuxSetCommandLine (SetupBuf, CommandLine);
-  if (EFI_ERROR (Status)) {
-    goto FreeAndReturn;
-  }
-
-  QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);
-  InitrdSize = (UINTN) QemuFwCfgRead64 ();
-
-  if (InitrdSize > 0) {
-    InitrdData = LoadLinuxAllocateInitrdPages (
-                   SetupBuf,
-                   EFI_SIZE_TO_PAGES (InitrdSize)
-                   );
-    DEBUG ((EFI_D_INFO, "Initrd size: 0x%x\n", (UINT32) InitrdSize));
-    DEBUG ((EFI_D_INFO, "Reading initrd image ..."));
-    QemuFwCfgSelectItem (QemuFwCfgItemInitrdData);
-    QemuFwCfgReadBytes (InitrdSize, InitrdData);
-    DEBUG ((EFI_D_INFO, " [done]\n"));
-  } else {
-    InitrdData = NULL;
-  }
-
-  Status = LoadLinuxSetInitrd (SetupBuf, InitrdData, InitrdSize);
+  Status = QemuLoadKernelImage (&KernelImageHandle);
   if (EFI_ERROR (Status)) {
-    goto FreeAndReturn;
+    return Status;
   }
 
   //
@@ -147,22 +35,16 @@ TryRunningQemuKernel (
   REPORT_STATUS_CODE (EFI_PROGRESS_CODE,
     (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT));
 
-  Status = LoadLinux (KernelBuf, SetupBuf);
+  //
+  // Start the image.
+  //
+  Status = QemuStartKernelImage (&KernelImageHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: QemuStartKernelImage(): %r\n", __FUNCTION__,
+      Status));
+  }
 
-FreeAndReturn:
-  if (SetupBuf != NULL) {
-    FreePages (SetupBuf, EFI_SIZE_TO_PAGES (SetupSize));
-  }
-  if (KernelBuf != NULL) {
-    FreePages (KernelBuf, EFI_SIZE_TO_PAGES (KernelInitialSize));
-  }
-  if (CommandLine != NULL) {
-    FreePages (CommandLine, EFI_SIZE_TO_PAGES (CommandLineSize));
-  }
-  if (InitrdData != NULL) {
-    FreePages (InitrdData, EFI_SIZE_TO_PAGES (InitrdSize));
-  }
+  QemuUnloadKernelImage (KernelImageHandle);
 
   return Status;
 }
-
-- 
2.17.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#55535): https://edk2.groups.io/g/devel/message/55535
Mute This Topic: https://groups.io/mt/71749527/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-

Re: [edk2-devel] [PATCH v3 12/14] OvmfPkg/PlatformBootManagerLib: switch to QemuLoadImageLib
Posted by Laszlo Ersek 5 years, 11 months ago
Hi Ard,

On 03/05/20 14:46, Ard Biesheuvel wrote:
> Replace the open coded sequence to load Linux on x86 with a short and
> generic sequence invoking QemuLoadImageLib, which can be provided by
> a generic version that only supports the LoadImage and StartImage boot
> services, and one that incorporates the entire legacy loading sequence
> as well.
> 
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2566
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> ---
>  OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf |   2 +-
>  OvmfPkg/Library/PlatformBootManagerLib/QemuKernel.c               | 144 ++------------------
>  2 files changed, 14 insertions(+), 132 deletions(-)
> 
> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> index c479f113b92b..e470b9a6a3e5 100644
> --- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> +++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> @@ -49,7 +49,7 @@ [LibraryClasses]
>    NvVarsFileLib
>    QemuFwCfgLib
>    QemuFwCfgS3Lib
> -  LoadLinuxLib
> +  QemuLoadImageLib
>    QemuBootOrderLib
>    ReportStatusCodeLib
>    UefiLib

This hunk (in commit 859b55443a42) seems to break the OvmfXen platform build:

Active Platform          = OvmfPkg/OvmfXen.dsc

build.py...
OvmfPkg/OvmfXen.dsc(...): error 4000: Instance of library class [QemuLoadImageLib] is not found
        in [OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf] [X64]
        consumed by module [MdeModulePkg/Universal/BdsDxe/BdsDxe.inf]

Can you please send a patch?

I think resolving the lib class to the generic instance suffices. gBS->LoadImage() will return EFI_NOT_FOUND from QemuLoadKernelImage(), because OvmfPkg/QemuKernelLoaderFsDxe is not included in the Xen platform.

An alternative fix that's larger in source code, but lighter in binary code, would be to add a Null instance of QemuLoadImageLib, and use that in the Xen platform.

For the future, please include OvmfXen.dsc in your build / CI scripts.

Thanks!
Laszlo


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#55551): https://edk2.groups.io/g/devel/message/55551
Mute This Topic: https://groups.io/mt/71749527/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-

Re: [edk2-devel] [PATCH v3 12/14] OvmfPkg/PlatformBootManagerLib: switch to QemuLoadImageLib
Posted by Ard Biesheuvel 5 years, 11 months ago
On Thu, 5 Mar 2020 at 22:15, Laszlo Ersek <lersek@redhat.com> wrote:
>
> Hi Ard,
>
> On 03/05/20 14:46, Ard Biesheuvel wrote:
> > Replace the open coded sequence to load Linux on x86 with a short and
> > generic sequence invoking QemuLoadImageLib, which can be provided by
> > a generic version that only supports the LoadImage and StartImage boot
> > services, and one that incorporates the entire legacy loading sequence
> > as well.
> >
> > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2566
> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> > ---
> >  OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf |   2 +-
> >  OvmfPkg/Library/PlatformBootManagerLib/QemuKernel.c               | 144 ++------------------
> >  2 files changed, 14 insertions(+), 132 deletions(-)
> >
> > diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> > index c479f113b92b..e470b9a6a3e5 100644
> > --- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> > +++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> > @@ -49,7 +49,7 @@ [LibraryClasses]
> >    NvVarsFileLib
> >    QemuFwCfgLib
> >    QemuFwCfgS3Lib
> > -  LoadLinuxLib
> > +  QemuLoadImageLib
> >    QemuBootOrderLib
> >    ReportStatusCodeLib
> >    UefiLib
>
> This hunk (in commit 859b55443a42) seems to break the OvmfXen platform build:
>
> Active Platform          = OvmfPkg/OvmfXen.dsc
>
> build.py...
> OvmfPkg/OvmfXen.dsc(...): error 4000: Instance of library class [QemuLoadImageLib] is not found
>         in [OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf] [X64]
>         consumed by module [MdeModulePkg/Universal/BdsDxe/BdsDxe.inf]
>
> Can you please send a patch?
>
> I think resolving the lib class to the generic instance suffices. gBS->LoadImage() will return EFI_NOT_FOUND from QemuLoadKernelImage(), because OvmfPkg/QemuKernelLoaderFsDxe is not included in the Xen platform.
>
> An alternative fix that's larger in source code, but lighter in binary code, would be to add a Null instance of QemuLoadImageLib, and use that in the Xen platform.
>
> For the future, please include OvmfXen.dsc in your build / CI scripts.
>

Apologies - I will fix it right away. It never occurred to me that
'TryRunningQemuKernel ()' is live code on OvmfXen.

Being able to drop LoadLinuxLib from the Xen build is a win in itself,
so I will leave the Null library class for another day, if you don't
mind.

-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#55552): https://edk2.groups.io/g/devel/message/55552
Mute This Topic: https://groups.io/mt/71749527/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-

Re: [edk2-devel] [PATCH v3 12/14] OvmfPkg/PlatformBootManagerLib: switch to QemuLoadImageLib
Posted by Laszlo Ersek 5 years, 11 months ago
On 03/05/20 22:20, Ard Biesheuvel wrote:
> On Thu, 5 Mar 2020 at 22:15, Laszlo Ersek <lersek@redhat.com> wrote:
>>
>> Hi Ard,
>>
>> On 03/05/20 14:46, Ard Biesheuvel wrote:
>>> Replace the open coded sequence to load Linux on x86 with a short and
>>> generic sequence invoking QemuLoadImageLib, which can be provided by
>>> a generic version that only supports the LoadImage and StartImage boot
>>> services, and one that incorporates the entire legacy loading sequence
>>> as well.
>>>
>>> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=2566
>>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
>>> ---
>>>  OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf |   2 +-
>>>  OvmfPkg/Library/PlatformBootManagerLib/QemuKernel.c               | 144 ++------------------
>>>  2 files changed, 14 insertions(+), 132 deletions(-)
>>>
>>> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
>>> index c479f113b92b..e470b9a6a3e5 100644
>>> --- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
>>> +++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
>>> @@ -49,7 +49,7 @@ [LibraryClasses]
>>>    NvVarsFileLib
>>>    QemuFwCfgLib
>>>    QemuFwCfgS3Lib
>>> -  LoadLinuxLib
>>> +  QemuLoadImageLib
>>>    QemuBootOrderLib
>>>    ReportStatusCodeLib
>>>    UefiLib
>>
>> This hunk (in commit 859b55443a42) seems to break the OvmfXen platform build:
>>
>> Active Platform          = OvmfPkg/OvmfXen.dsc
>>
>> build.py...
>> OvmfPkg/OvmfXen.dsc(...): error 4000: Instance of library class [QemuLoadImageLib] is not found
>>         in [OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf] [X64]
>>         consumed by module [MdeModulePkg/Universal/BdsDxe/BdsDxe.inf]
>>
>> Can you please send a patch?
>>
>> I think resolving the lib class to the generic instance suffices. gBS->LoadImage() will return EFI_NOT_FOUND from QemuLoadKernelImage(), because OvmfPkg/QemuKernelLoaderFsDxe is not included in the Xen platform.
>>
>> An alternative fix that's larger in source code, but lighter in binary code, would be to add a Null instance of QemuLoadImageLib, and use that in the Xen platform.
>>
>> For the future, please include OvmfXen.dsc in your build / CI scripts.
>>
> 
> Apologies - I will fix it right away. It never occurred to me that
> 'TryRunningQemuKernel ()' is live code on OvmfXen.

Right. Such surprises are going to disappear after
<https://bugzilla.tianocore.org/show_bug.cgi?id=2122> is fixed,
hopefully around August 2020.

> Being able to drop LoadLinuxLib from the Xen build is a win in itself,

Good point, I didn't realize!

> so I will leave the Null library class for another day, if you don't
> mind.
> 

Sure, that's absolutely fine.

Thanks!
Laszlo


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#55560): https://edk2.groups.io/g/devel/message/55560
Mute This Topic: https://groups.io/mt/71749527/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-