comments in-line

On 11/12/12 21:55, Laszlo Ersek wrote:
> On 10/29/12 01:01, Jordan Justen wrote:

>> +
>> +
>> +STATIC
>>  EFI_STATUS
>> -TryRunningQemuKernel (
>> -  VOID
>> +TryRunningPeCoffImage (
>> +  IN VOID                   *SetupBuf,
>> +  IN UINTN                  SetupSize,
>> +  IN UINTN                  KernelSize
>> +  )
>> +{
>> +  EFI_STATUS                Status;
>> +  UINTN                     PeImageSize;
>> +  VOID                      *PeImageData;
>> +  EFI_HANDLE                ImageHandle;
>> +  EFI_HANDLE                DevicePathHandle;
>> +  MEMMAP_IMAGE_DEVICE_PATH  DevicePath;
>> +
>> +  PeImageData = NULL;
>> +  PeImageSize = 0;
>> +  Status = EFI_SUCCESS;
>> +
>> +  //
>> +  // The first part of the PE/COFF image was loaded from the 'kernel setup'
>> +  // area. QEMU will put the remaining portion in the 'kernel data' area.
>> +  //
>> +  // We combine these two items into a single buffer to retrieve the 
>> original
>> +  // PE/COFF image.
>> +  //
>> +  PeImageSize = SetupSize + KernelSize;

Let's assume the sum won't ever overflow.

>> +  PeImageData = AllocatePages (EFI_SIZE_TO_PAGES (PeImageSize));
>> +  if (PeImageData == NULL) {
>> +    Status = EFI_OUT_OF_RESOURCES;
>> +    goto FreeAndReturn;
>> +  }
>> +  CopyMem (PeImageData, SetupBuf, SetupSize);
>> +
>> +  DEBUG ((EFI_D_INFO, "Remaining PE/COFF image size: 0x%x\n", (UINT32) 
>> KernelSize));
>> +  DEBUG ((EFI_D_INFO, "Reading PE/COFF image ..."));
>> +  QemuFwCfgSelectItem (QemuFwCfgItemKernelData);
>> +  QemuFwCfgReadBytes (KernelSize, ((UINT8*) PeImageData) + SetupSize);
>> +  DEBUG ((EFI_D_INFO, " [done]\n"));
>> +
>> +  //
>> +  // Create a device path for the image
>> +  //
>> +  CopyMem ((VOID*) &DevicePath,
>> +           (VOID*) &mMemmapImageDevicePathTemplate,
>> +           sizeof (DevicePath));

Ah this makes me ask another question regarding
MEMMAP_IMAGE_DEVICE_PATH: shouldn't it be packed? AFAIK a device path is
traversed node-by-node using "EFI_DEVICE_PATH_PROTOCOL.Length" at the
beginning of each ("derived") node. Without packing, a compiler is
theoretically allowed to insert padding between the two fields of
MEMMAP_IMAGE_DEVICE_PATH, throwing off the traversal.


>> +  DevicePath.MemMapDevPath.StartingAddress = (UINTN) PeImageData;
>> +  DevicePath.MemMapDevPath.EndingAddress =
>> +    DevicePath.MemMapDevPath.StartingAddress + PeImageSize;

Is "EndingAddress" exclusive?

- "DuetPkg/FvbRuntimeService/FWBlockService.c" suggests it is inclusive
(ie. base + size - 1).
- OTOH, "ArmPkg/Library/BdsLib/BdsFilePath.c" suggests it is exclusive
(ie. size = ending - starting)
- The field name itself suggests inclusive.

>> +  DevicePathHandle = NULL;
>> +  Status = gBS->InstallProtocolInterface (
>> +                  &DevicePathHandle,
>> +                  &gEfiDevicePathProtocolGuid,
>> +                  EFI_NATIVE_INTERFACE,
>> +                  (VOID*) &DevicePath
>> +                  );

Status check missing.

BTW why do we need to install the protocol interace on DevicePath for
the rest of the world?

>> +
>> +  //
>> +  // Load and start the PE/COFF image
>> +  //
>> +  ImageHandle = NULL;
>> +  Status = gBS->LoadImage (
>> +                  FALSE,
>> +                  gImageHandle,
>> +                  (VOID*) &DevicePath,
>> +                  PeImageData,
>> +                  PeImageSize,
>> +                  &ImageHandle
>> +                  );

Do we need both DevicePath and PeImageData/PeImageSize here? (Just
trying to learn, the spec of LoadImage() is hard to interpret.)

>> +  DEBUG ((EFI_D_INFO, "Loading PE/COFF image -> %r\n", Status));
>> +
>> +  if (!EFI_ERROR (Status)) {
>> +    DEBUG ((EFI_D_INFO, "Starting PE/COFF image ...\n"));
>> +    Status = gBS->StartImage (ImageHandle, NULL, NULL);
>> +    DEBUG ((EFI_D_INFO, "PE/COFF image exited -> %r\n", Status));
>> +  }

Again, I do not understand UnloadImage() spec: what happens if the image
- has been loaded,
- has been started,
- does not have an Unload entry point?

UnloadImage() returns EFI_UNSUPPORTED. That's OK, but what happens to
the image when StartImage() returns? Is it automatically unloaded, or
leaked forever?

>> +
>> +  //
>> +  // Uninstall the device path for the image
>> +  //
>> +  Status = gBS->UninstallProtocolInterface (
>> +                  DevicePathHandle,
>> +                  &gEfiDevicePathProtocolGuid,
>> +                  (VOID*) &DevicePath
>> +                  );

This overwrites the status returned by the image. May not matter in
practice, but I think the intent is to propagate it.

>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +FreeAndReturn:
>> +  if (PeImageData != NULL) {
>> +    FreePages (PeImageData, EFI_SIZE_TO_PAGES (PeImageSize));
>> +  }
>> +
>> +  return Status;
>> +}
>> +
>> +

>> +EFI_STATUS
>> +TryRunningQemuKernel (
>> +  VOID
>> +  )
>> +{
>> +  EFI_STATUS                Status;
>> +  UINTN                     SetupSize;
>> +  VOID                      *SetupBuf;
>> +  UINTN                     KernelSize;
>> +
>> +  SetupBuf = NULL;
>> +  SetupSize = 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"));
>> +
>> +  if (LooksLikeAPeCoffImage (SetupBuf, SetupSize)) {
>> +    Status = TryRunningPeCoffImage (SetupBuf, SetupSize, KernelSize);
>> +  } else {
>> +    Status = TryRunningKernelImage (SetupBuf, SetupSize, KernelSize);
>> +  }
>> +
>> +  if (SetupBuf != NULL) {
>> +    FreePages (SetupBuf, EFI_SIZE_TO_PAGES (SetupSize));
>> +  }

Sorry for not noticing this earlier: SetupBuf is never NULL here.

>> +
>> +  return Status;
>> +}

No more comments.

Thanks,
Laszlo

------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to