[syslinux] UEFI support for chain.c32 in 6.04 syslinux

H. Peter Anvin hpa at zytor.com
Wed May 23 13:28:57 PDT 2018


On 05/21/18 09:17, Jeffrey Hutzelman via Syslinux wrote:
> On Fri, 2016-12-23 at 08:43 -0500, Gene Cumm via Syslinux wrote:
>> On Thu, Dec 15, 2016 at 2:59 PM, Robin Mathews (robimath) via
>> Syslinux
>> <syslinux at zytor.com> wrote:
>>>
>>> Hi Folks ,
>>>
>>> Can you please let me know if there is any fix for chain
>>> loading  UEFI boot loader using chain.c32  in 6.04 release ?
>>> I am booting my system with syslinux.efi and want to chain load to
>>> windows or sex specific boot loader in the second stage  .
>> chain.c32 has a lot of BIOS-isms and probably isn't worth modifying.
>> I believe none of the chain.c32 options apply to a (U)EFI
>> environment.
>>
>> There is a patch I'm reviewing for a new module to chainload (U)EFI
>> but it needs a lot of style cleanup. The chainloading of (U)EFI
>> binaries should be a lot closer to how linux.c32 works though might
>> in
>> the future contain (U)EFI-specific options.  See
>> EFI_BOOT_SERVICES.LoadImage().
> 
> Did anything ever come of this? I'm about to be under some pressure to
> upgrade our aging PXE boot menu system to support UEFI, and as you
> might imagine, we currently rely quite heavily on chainloading (there
> are currently at least 38 invocations of pxechain.cbt, and yes, I'm
> still using that :-)).
> 

>From what I can tell, I think chainloading UEFI or, for that matter,
running any arbitrary UEFI application or installing a UEFI driver
should simply be a matter of:

1  Use loadfile() to load the file into memory.
2. Use EFI_BOOT_SERVICES.LoadImage() to install it into UEFI.
3. free() the loaded image; UEFI has copied it to an new buffer.
4. [Optional] set the LoadOptions of the image.
    -> The UEFI shell simply set this to the unparsed
       command line. Some images may want a binary blob which
       would have to be loaded from a file.
5. [Optional] install a EFI_SHELL_PARAMETERS_PROTOCOL (argc/argv and
   filehandles) on the application image.
6. [Optional] support installing a ramdisk (see below);
   this would provide functionality equivalent to memdisk.
7. Call EFI_BOOT_SERVICES.StartImage()
8. If the program exits:
   If ExitData is set, print ExitData to the screen (probably prefixed
   with the filename) and then free the ExitData buffer using
   FreePool().

The nicest thing about this is that the same code can handle UEFI
drivers, UEFI applications, and UEFI bootloaders.

To install a protocol, use EFI_BOOT_SERVICES.InstallProtocolInterface().

A RAM disk can be installed on newer UEFI firmware simply by calling
EFI_RAM_DISK_PROTOCOL.Register(). Unfortunately this is a *very* new
protocol (UEFI 2.6; November 2016.) If this isn't supported, it is is
possible to add a EFI_BLOCK_IO_PROTOCOL driver to supply this
functionality; it might even be able to add EFI_RAM_DISK_PROTOCOL support.

There is a fancier way to do this, which does has some pretty awesome
advantages, but requires a lot more work: have Syslinux install a UEFI
device driver (specifically, a Media Access driver) providing an
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL (much preferred) or
EFI_LOAD_FILE_PROTOCOL (much simpler) for its own filesystem driver.
That way UEFI software could access whatever filesystem Syslinux sees
(and inherently support multi-device once implemented in Syslinux, etc.)

Multi-device support for UEFI could also be handled by instead of
installing a device driver for "Syslinux" adding a
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL drivers for each device that
Syslinux-recognized filesystems but doesn't have such a filesystem
protocol installed yet.

	-hpa


More information about the Syslinux mailing list