Since you asked here is a little more info:

The file's EFI_FILE_PROTOCOL is insufficient information to find it as it just 
contains the path in file system for the file.  That's the equivalent to saying 
"I want to open file directory/foo.txt".  you need to give more context for 
success.

To load into memory, it needs a EFI_DEVICE_PATH_PROTOCOL, this is a path to the 
device the file resides on, followed by the path in the file system for the 
file.  In the UEFI Shell there is a "drive name" that is something like "fs0" 
which the shell decodes to get the first portion of the 
EFI_DEVICE_PATH_PROTOCOL for your file.  You can look in ShellProtocol.c for 2 
functions involved: EfiShellGetDevicePathFromFilePath, and 
EfiShellGetFilePathFromDevicePath (one for each direction of conversion).

-Jaben

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of
> Andrew Fish
> Sent: Friday, February 05, 2016 6:56 AM
> To: Michael Zimmermann <sigmaepsilo...@gmail.com>
> Cc: edk2-devel@lists.01.org <edk2-de...@ml01.01.org>; Laszlo Ersek
> <ler...@redhat.com>
> Subject: Re: [edk2] manually booting efi file
> 
> 
> > On Feb 5, 2016, at 6:44 AM, Michael Zimmermann
> <sigmaepsilo...@gmail.com> wrote:
> >
> > Lazlo,
> >
> > using 'FileDevicePath' works perfectly, thx :)
> > sth. else I stumbled on is this typedef:
> > typedef EFI_DEVICE_PATH_PROTOCOL  EFI_DEVICE_PATH;
> >
> > I tried to find a way to convert from EFI_DEVICE_PATH_PROTOCOL to
> > EFI_DEVICE_PATH until I saw that it's just an alias :P
> >
> 
> Also EFI boots from removable media via spec defined file names.
> So if you search for BOOTX64.EFI you find:
>  #define EFI_REMOVABLE_MEDIA_FILE_NAME_X64
> L"\\EFI\\BOOT\\BOOTX64.EFI"
> That leads you to:
> #define EFI_REMOVABLE_MEDIA_FILE_NAME
> EFI_REMOVABLE_MEDIA_FILE_NAME_X64
> And that will point you to the BDS code that loads files from removable media:
> 
> ~/work/src/edk2(master)>git grep EFI_REMOVABLE_MEDIA_FILE_NAME -- *.c
> IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c:2081:
> FullDevicePath = FileDevicePath (Handle,
> EFI_REMOVABLE_MEDIA_FILE_NAME);
> IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c:2376:
> FilePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME);
> IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c:3336:
> EFI_REMOVABLE_MEDIA_FILE_NAME,
> IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c:3720:
> EFI_REMOVABLE_MEDIA_FILE_NAME,
> MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c:1398:  by appending
> EFI_REMOVABLE_MEDIA_FILE_NAME.
> MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c:1434:
> TempDevicePath = FileDevicePath (Handle,
> EFI_REMOVABLE_MEDIA_FILE_NAME);
> MdeModulePkg/Library/UefiBootManagerLib/BmBoot.c:1496:
> TempDevicePath = FileDevicePath (SimpleFileSystemHandles[Index],
> EFI_REMOVABLE_MEDIA_FILE_NAME);
> MdeModulePkg/Universal/BdsDxe/BdsEntry.c:724:  FilePath = FileDevicePath
> (NULL, EFI_REMOVABLE_MEDIA_FILE_NAME);
> Vlv2TbltDevicePkg/Library/PlatformBdsLib/BdsPlatform.c:1308:
> EFI_REMOVABLE_MEDIA_FILE_NAME,
> Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsL
> ib/BdsBoot.c:2083:        FullDevicePath = FileDevicePath (Handle,
> EFI_REMOVABLE_MEDIA_FILE_NAME);
> Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsL
> ib/BdsBoot.c:2387:        FilePath = FileDevicePath (Handle,
> EFI_REMOVABLE_MEDIA_FILE_NAME);
> Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsL
> ib/BdsBoot.c:3351:                   EFI_REMOVABLE_MEDIA_FILE_NAME,
> Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsL
> ib/BdsBoot.c:3837:                 EFI_REMOVABLE_MEDIA_FILE_NAME,
> 
> Thanks,
> 
> Andrew Fish
> 
> 
> > Thanks for everyone's help :)
> >
> > Michael
> >
> > On Fri, Feb 5, 2016 at 3:01 PM, Laszlo Ersek <ler...@redhat.com> wrote:
> >
> >> On 02/05/16 14:26, Michael Zimmermann wrote:
> >>> The problem is that there is no GUID for 'EFI_FILE_PROTOCOL' there's
> >>> only 'EFI_SIMPLE_FILE_SYSTEM_PROTOCOL' which I already have.
> >>
> >> Ah, sorry, I completely forgot about this. I've only ever worked with
> >> EFI_SIMPLE_FILE_SYSTEM_PROTOCOL and EFI_FILE_PROTOCOL once, in git
> >> commit 23d04b58e27b.
> >>
> >>> I don't even understand the concept of a devicepath attached to a file
> >>> since a file is not a device.
> >>
> >> Okay, so I'm fuzzy on this, but the LoadImage() specification explains
> >> it more or less. The idea is (/me hand-waving) that all but the last
> >> device path nodes are used to locate the simple file system protocol
> >> instance, and the last device path node, which is supposed to be of type
> >> MEDIA_DEVICE_PATH, subtype MEDIA_FILEPATH_DP, carries the pathname
> of
> >> the file within the simple file system.
> >>
> >> The root directory of the file system would be opened with
> >> EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume(), which returns an
> >> EFI_FILE_PROTOCOL, standing for the root directory.
> >>
> >> This is in turn used with EFI_FILE_PROTOCOL.Open(), passing in the
> >> pathname from MEDIA_FILEPATH_DP, to get the EFI_FILE_PROTOCOL that
> >> ultimately stands for the file.
> >>
> >> So, what you need in this case is the following:
> >> - the handle of the simple file system protocol that the file exists on
> >> - the absolute pathname of the file within that file system.
> >>
> >> If you don't already have access to the first, I don't know how you can
> >> get it, starting from EFI_FILE_PROTOCOL.
> >>
> >> The name of the file itself can be retrieved with
> >> EFI_FILE_PROTOCOL.GetInfo(), passing in the EFI_FILE_INFO_ID GUID as
> >> InformationType. However, I think this will only return the direct
> >> filename, not the absolute pathname within the filesystem. So ultimately
> >> I can't tell you how to get this piece of info either.
> >>
> >> Assuming you have them both though, you can use the FileDevicePath()
> >> library function, from the DevicePathLib class
> >> (MdePkg/Include/Library/DevicePathLib.h), to create a device path that
> >> you can pass to LoadImage().
> >>
> >> See also EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL.
> >>
> >> ... Hm, I think I just found an omission in the spec (2.6).
> >>
> >> Namely, in my first reply, I actually wanted to propose to load the
> >> entire contents of the file into memory (using
> >> EFI_FILE_PROTOCOL.Read()), and then pass the contents to LoadImage(),
> >> using the SourceBuffer and SourceSize parameters. Also setting the
> >> DevicePath parameter to NULL.
> >>
> >> Ultimately I didn't recommend this, because the spec doesn't mark the
> >> DevicePath parameter of LoadImage() OPTIONAL. The LoadImage()
> >> description *never* mentions that DevicePath can be NULL. This is the
> >> omission.
> >>
> >> Because, if you look at EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL, it
> says:
> >>
> >>    [...] It is legal to call LoadImage() for a buffer in memory with a
> >>    NULL DevicePath parameter. In this case, the Loaded Image Device
> >>    Path Protocol is installed with a NULL interface pointer.
> >>
> >>> How do the Shell or other boot manager load such files?
> >>
> >> I don't think they ever start out with a bare EFI_FILE_PROTOCOL. But,
> >> using the above method (load contents, pass buffer to LoadImage(), with
> >> DevicePath=NULL), it should be possible.
> >>
> >> Sorry, I made a huge detour here. My only excuse is that the only time I
> >> worked with this was long ago, and that the LoadImage() specification
> >> seems incomplete.
> >>
> >> Thanks
> >> Laszlo
> >>
> >>> On Fri, Feb 5, 2016 at 1:17 PM, Laszlo Ersek <ler...@redhat.com
> >>> <mailto:ler...@redhat.com>> wrote:
> >>>
> >>>    On 02/05/16 12:44, Michael Zimmermann wrote:
> >>>> Hi,
> >>>>
> >>>> how can I boot a EFI application if I have it's
> >> 'EFI_FILE_PROTOCOL'?
> >>>> 'BdsStartEfiApplication' does only accept a 'EFI_DEVICE_PATH'.
> >>>
> >>>    You could do the following:
> >>>    - call LocateHandle() to find all handles that have EFI_FILE_PROTOCOL
> >>>      installed
> >>>    - on each handle returned, call OpenProtocol() with GET_PROTOCOL
> and
> >>>      the EFI_FILE_PROTOCOL GUID, and see if the returned protocol
> >>>      interface address matches the one that you already have
> >>>    - if so, call OpenProtocol() with GET_PROTOCOL and the
> >>>      EFI_DEVICE_PATH_PROTOCOL GUID on the same handle.
> >>>
> >>>    Laszlo
> >>>
> >>>>
> >>>> Michael
> >>>> _______________________________________________
> >>>> edk2-devel mailing list
> >>>> edk2-devel@lists.01.org <mailto:edk2-devel@lists.01.org>
> >>>> https://lists.01.org/mailman/listinfo/edk2-devel
> >>>>
> >>>
> >>>
> >>
> >>
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to