| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The UEFI HTTP boot mechanism is extraordinarily badly designed, even
by the standards of the UEFI specification in general. It has the
symptoms of a feature that has been designed entirely in terms of user
stories, without any consideration at all being given to the
underlying technical architecture. It does work, provided that you
are doing precisely and only what was envisioned by the product owner.
If you want to try anything outside the bounds of the product owner's
extremely limited imagination, then you are almost certainly about to
enter a world of pain.
As one very minor example of this: the cached DHCP packet is not
available when using HTTP boot. The UEFI HTTP boot code does perform
DHCP, but it pointlessly and unhelpfully throws away the DHCP packet
and trashes the network interface configuration before handing over to
the downloaded executable.
Work around this imbecility by parsing and applying the few network
configuration settings that are persisted into the loaded image's
device path. This is limited to very basic information such as the IP
address, gateway address, and DNS server address, but it does at least
provide enough for a functional routing table.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
| |
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When using a service binding protocol, CreateChild() will create a new
protocol instance (and optionally a new handle). The caller will then
typically open this new protocol instance with BY_DRIVER attributes,
since the service binding mechanism has no equivalent of the driver
binding protocol's Stop() method, and there is therefore no other way
for the caller to be informed if the protocol instance is about to
become invalid (e.g. because the service driver wants to remove the
child).
The caller cannot ask CreateChild() to install the new protocol
instance on the original handle (i.e. the service binding handle),
since the whole point of the service binding protocol is to allow for
the existence of multiple children, and UEFI does not permit multiple
instances of the same protocol to be installed on a handle.
Our current drivers all open the original handle (as passed to our
driver binding's Start() method) with BY_DRIVER attributes, and so the
same handle will be passed to our Stop() method. This changes when
our driver must use a separate handle, as described above.
Add an optional "child handle" field to struct efi_device (on the
assumption that we will not have any drivers that need to create
multiple children), and generalise efidev_find() to match on either
the original handle or the child handle.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
| |
The EFI service binding abstraction is used to add and remove child
handles for multiple different protocols. Provide a common interface
for doing so.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
| |
When booted via HTTP, our loaded image's device path will include the
URI from which we were downloaded. Set this as the current working
URI, so that an embedded script may perform subsequent downloads
relative to the iPXE binary, or construct explicit relative paths via
the ${cwduri} setting.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
| |
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Provide an implementation of the iPXE multiprocessor API for EFI,
based on using EFI_MP_SERVICES to start up a wrapper function on all
application processors.
Note that the processor numbers used by EFI_MP_SERVICES are opaque
integers that bear no relation to the underlying CPU identity
(e.g. the APIC ID), and so we must rely on our own (architecture-
specific) implementation to determine the relevant CPU identifiers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The return status from efi_block_local() indicates whether or not the
handle is eligible to be assigned a local virtual drive number. There
will always be several enumerated EFI_BLOCK_IO_PROTOCOL handles that
are not eligible for a local virtual drive number (e.g. the handles
corresponding to partitions, rather than to complete disks), and this
is not an interesting error to report.
Do not report errors from efi_block_local() as the overall error
status for a SAN boot, since doing so would be likely to mask a much
more relevant error from having previously attempted to scan for a
matching filesystem within an eligible block device handle.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
| |
Add a "--label" option that can be used to specify a filesystem label,
to be matched against the FAT volume label.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add an "--extra" option that can be used to specify an extra
(non-boot) filename that must exist within the booted filesystem.
Note that only files within the FAT-formatted bootable partition will
be visible to this filter. Files within the operating system's root
disk (e.g. "/etc/redhat-release") are not generally accessible to the
firmware and so cannot be used as the existence check filter filename.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
| |
Add a "--uuid" option which may be used to specify a boot device UUID,
to be matched against the GPT partition GUID.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
| |
EFI provides no API for determining the partition GUID (if any) for a
specified device handle. The partition GUID appears to be exposed
only as part of the device path.
Add efi_path_guid() to extract the partition GUID (if any) from a
device path.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The drive specification alone does not necessarily contain enough
information to perform a SAN boot (or local disk boot) under UEFI. If
the next-stage bootloader is installed in the EFI system partition
under a non-standard name (e.g. "\EFI\debian\grubx64.efi") then this
explicit boot filename must also be specified.
Generalise this concept to use a "SAN boot configuration parameters"
structure (currently containing only the optional explicit boot
filename), to allow for easy expansion to provide other parameters
such as the partition UUID or volume label.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Extend the EFI SAN boot code to allow for booting from a local disk,
as is already possible with the BIOS SAN boot code.
There is unfortunately no direct UEFI equivalent of the BIOS drive
number. The UEFI shell does provide numbered mappings fs0:, blk0:,
etc, but these numberings exist only while the UEFI shell is running
and are not necessarily stable between shell invocations or across
reboots.
A substantial amount of existing third-party documentation for iPXE
will suggest using "sanboot --drive 0x80" to boot from a local disk
(when no SAN drives are present), since this suggestion has been
present in the official documentation for the "sanboot" command for
almost thirteen years. We therefore aim to ensure that this
instruction will also work for UEFI, i.e. that in a situation where
there are local disks but no SAN disks, then the first local disk will
be treated as being drive 0x80.
We therefore assign local disks the virtual drive numbers 0x80, 0x81,
etc, matching the numbering typically used in a BIOS environment.
Where a SAN disk is already occupying one of these drive numbers, the
local disks' virtual drive numbers will be incremented as necessary.
This provides a rough approximation of the equivalent functionality
under BIOS, where existing local disks' drive numbers are remapped to
make way for SAN disks.
We do not make any attempt to sort the list of local disks: the order
used for allocating virtual drive numbers will be whatever order is
returned by LocateHandle(). This will typically match the creation
order of the EFI handles, which will typically match the hardware
enumeration order of the devices, which will typically match user
expectations as to which local disk is first, second, etc.
We explicitly do not attempt to match the numbering used by the UEFI
shell (which initially sorts in increasing order of device path, but
does not renumber when new devices are added or removed). We can
never guarantee matching this partly transient UEFI shell numbering,
so it is best not to set any expectation that it will be matched.
(Using local drive numbers starting at 0x80 helps to avoid setting up
this impossible expectation, since the UEFI shell uses local drive
numbers starting at zero.)
Since floppy disks are essentially non-existent in any plausible UEFI
system, overload "--drive 0" to mean "boot from any drive containing
the specified (or default) boot filename".
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
SAN devices created by iPXE are visible to the firmware, and may be
accessed using the firmware's standard block I/O device interface
(e.g. INT 13 for BIOS, or EFI_BLOCK_IO_PROTOCOL for UEFI). The iPXE
code to perform a SAN boot acts as a client of this standard block I/O
device interface, even when the underlying block I/O is being
performed by iPXE itself.
We rely on this separation to allow the "sanboot" command to be used
to boot from a local disk: since the code to perform a SAN boot does
not need direct access to an underlying iPXE SAN device, it may be
used to boot from any device providing the firmware's standard block
I/O device interface.
Clean up the EFI SAN boot code to require only a drive number and an
EFI_BLOCK_IO_PROTOCOL handle, in preparation for adding support for
booting from a local disk under UEFI.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The "sanboot" command allows a custom boot filename to be specified
via the "--filename" option. We currently rely on LoadImage() to
perform both the existence check and to load the image ready for
execution. This may give a false negative result if Secure Boot is
enabled and the boot file is not correctly signed.
Carry out the existence check using EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
separately from loading the image via LoadImage().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
| |
We currently use the SAN device pointer as the debug message stream
identifier. This pointer is not always available: for example, when
booting from a local disk there is no underlying SAN device.
Switch to using the drive number as the debug message colour stream
identifier, so that all block device debug messages may be colourised
consistently.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We currently call ConvertDevicePathToText() with DisplayOnly=TRUE when
constructing a device path to appear within a debug message. For
ATAPI device paths, this will unfortunately omit some key information:
the textual representation will not indicate which ATA bus or drive is
represented. This can lead to misleading debug messages that appear
to refer to identical devices.
Fix by setting DisplayOnly=FALSE to select the long form of device
path textual representations.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The UEFI shim installs wrappers around several boot services functions
before invoking its next stage bootloader, in an attempt to enforce
its desired behaviour upon the aforementioned bootloader. For
example, shim checks that the bootloader has either invoked
StartImage() or has called into the "shim lock protocol" before
allowing an ExitBootServices() call to proceed.
When invoking a shim, iPXE will also install boot services function
wrappers in order to work around assorted bugs in the UEFI shim code
that would otherwise prevent it from being used to boot a kernel. For
details on these workarounds, see commits 28184b7 ("[efi] Add support
for executing images via a shim") and 5b43181 ("[efi] Support versions
of shim that perform SBAT verification").
Using boot services function wrappers in this way is not intrinsically
problematic, provided that wrappers are installed before starting the
wrapped program, and uninstalled only after the wrapped program exits.
This strict ordering requirement ensures that all layers of wrappers
are called in the expected order, and that no calls are issued through
a no-longer-valid function pointer.
Unfortunately, the UEFI shim does not respect this strict ordering
requirement, and will instead uninstall (and reinstall) its wrappers
midway through the execution of the wrapped program. This leaves the
wrapped program with an inconsistent view of the boot services table,
leading to incorrect behaviour.
This results in a boot failure when a first shim is used to boot iPXE,
which then uses a second shim to boot a Linux kernel:
- First shim installs StartImage() and ExitBootServices() wrappers
- First shim invokes iPXE via its own PE loader
- iPXE installs ExitBootServices() wrapper
- iPXE invokes second shim via StartImage()
At this point, the first shim's StartImage() wrapper will illegally
uninstall its ExitBootServices() wrapper, without first checking that
nothing else has modified the ExitBootServices function pointer. This
effectively bypasses iPXE's own ExitBootServices() wrapper, which
causes a boot failure since the code within that wrapper does not get
called.
A proper fix would be for shim to install its wrappers before starting
the image and uninstall its wrappers only after the started image has
exited. Instead of repeatedly uninstalling and reinstalling its
wrappers while the wrapped program is running, shim should simply use
a flag to keep track of whether or not it needs to modify the
behaviour of the wrapped calls.
Experience shows that there is unfortunately no point in trying to get
a fix for this upstreamed into shim. We therefore work around the
shim bug by removing our ExitBootServices() wrapper and moving the
relevant code into our GetMemoryMap() wrapper.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
| |
Support scanning for the 64-bit SMBIOS3 entry point in addition to the
32-bit SMBIOS2 entry point.
Prefer use of the 32-bit entry point if present, since this is
guaranteed to be within accessible memory.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The function efi_pecoff_debug_name() (called by efi_handle_name()) is
used to extract a filename from the debug data directory entry located
within a PE/COFF image. The name is copied into a temporary static
buffer to allow for modifications, but the code currently erroneously
modifies the original name within the loaded PE/COFF image.
Fix by performing the modification on the copy in the temporary
buffer, as originally intended.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Allow network upper-layer drivers (such as LLDP, which attaches to
each network device in order to provide a corresponding LLDP settings
block) to specify a size for private data, which will be allocated as
part of the network device structure (as with the existing private
data allocated for the underlying device driver).
This will allow network upper-layer drivers to be simplified by
omitting memory allocation and freeing code. If the upper-layer
driver requires a reference counter (e.g. for interface
initialisation), then it may use the network device's existing
reference counter, since this is now the reference counter for the
containing block of memory.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
While not guaranteed by the UEFI specification, the enumeration of
handles, protocols, and openers will generally return results in order
of creation. Processing these objects in reverse order (as is already
done when calling DisconnectController() on the list of all handles)
will generally therefore perform the forcible uninstallation
operations in reverse order of object creation, which minimises the
number of implicit operations performed (e.g. when disconnecting a
controller that itself still has existent child controllers).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
| |
The UEFI specification states that the AgentHandle may be either the
driving binding protocol handle or the image handle.
Check for both handles when searching for stale handles to be forcibly
closed on behalf of a vetoed driver.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
| |
In most cases, the driver handle will be the image handle itself.
However, this is not required by the UEFI specification, and some
images will install multiple driver binding handles.
Use the image handle (extracted from the driver binding protocol
instance) when attempting to unload the driver's image.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
| |
Pass the driver binding handle, the driver binding protocol instance,
the image handle, and the loaded image protocol instance to all veto
methods.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
| |
Simplify the process of adding new entries to the veto list by
including the manufacturer name within the standard debug output.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
EFI variables do not map neatly to the iPXE settings mechanism, since
the EFI variable identifier includes a namespace GUID that cannot
cleanly be supplied as part of a setting name. Creating a new EFI
variable requires the variable's attributes to be specified, which
does not fit within iPXE's settings concept.
However, EFI variable names are generally unique even without the
namespace GUID, and EFI does provide a mechanism to iterate over all
existent variables. We can therefore provide read-only access to EFI
variables by comparing only the names and ignoring the namespace
GUIDs.
Provide an "efi" settings block that implements this mechanism using a
syntax such as:
echo Platform language is ${efi/PlatformLang:string}
show efi/SecureBoot:int8
Settings are returned as raw binary values by default since an EFI
variable may contain boolean flags, integer values, ASCII strings,
UCS-2 strings, EFI device paths, X.509 certificates, or any other
arbitrary blob of data.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The EDK2 UefiPxeBcDxe driver includes some remarkably convoluted and
unsafe logic in its driver binding protocol Start() and Stop() methods
in order to support a pair of nominally independent driver binding
protocols (one for IPv4, one for IPv6) sharing a single dynamically
allocated data structure. This PXEBC_PRIVATE_DATA structure is
installed as a dummy protocol on the NIC handle in order to allow both
IPv4 and IPv6 driver binding protocols to locate it as needed.
The error handling code path in the UefiPxeBcDxe driver's Start()
method may attempt to uninstall the dummy protocol but fail to do so.
This failure is ignored and the containing memory is subsequently
freed anyway. On the next invocation of the driver binding protocol,
it will find and use this already freed block of memory. At some
point another memory allocation will occur, the PXEBC_PRIVATE_DATA
structure will be corrupted, and some undefined behaviour will occur.
The UEFI firmware used in VMware ESX 8 includes some proprietary
changes which attempt to install copies of the EFI_LOAD_FILE_PROTOCOL
and EFI_PXE_BASE_CODE_PROTOCOL instances from the IPv4 child handle
onto the NIC handle (along with a VMware-specific protocol with GUID
5190120d-453b-4d48-958d-f0bab3bc2161 and a NULL instance pointer).
This will inevitably fail with iPXE, since the NIC handle already
includes an EFI_LOAD_FILE_PROTOCOL instance.
These VMware proprietary changes end up triggering the unsafe error
handling code path described above. The typical symptom is that an
attempt to exit from iPXE back to the UEFI firmware will crash the VM
with a General Protection fault from within the UefiPxeBcDxe driver:
this happens when the UefiPxeBcDxe driver's Stop() method attempts to
call through a function pointer in the (freed) PXEBC_PRIVATE_DATA
structure, but the function pointer has by then been overwritten by
UCS-2 character data from an unrelated memory allocation.
Work around this failure by adding the VMware UefiPxeBcDxe driver to
the driver veto list.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
| |
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
| |
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
| |
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
| |
The old IPv4-only IScsiDxe driver in MdeModulePkg/Universal/Network
was replaced by a dual-stack IScsiDxe driver in NetworkPkg.
Add the module GUID for this driver.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
| |
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
| |
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
| |
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
| |
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The UEFI shim implements a fairly nicely designed revocation mechanism
designed around the concept of security generations. Unfortunately
nobody in the shim community has thus far added the relevant metadata
to the Linux kernel, with the result that current versions of shim are
incapable of booting current versions of the Linux kernel.
Experience shows that there is unfortunately no point in trying to get
a fix for this upstreamed into shim. We therefore default to working
around this undesirable behaviour by patching data read from the
"SbatLevel" variable used to hold SBAT configuration.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
| |
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add support for using a shim as a helper to execute an EFI image.
When a shim has been specified via shim(), the shim image will be
passed to LoadImage() instead of the selected EFI image and the
command line will be prepended with the name of the selected EFI
image. The selected EFI image will be accessible to the shim via the
virtual filesystem as a hidden file.
Reduce the Secure Boot attack surface by removing, where possible, the
spurious requirement for a third party second stage loader binary such
as GRUB to be used solely in order to call the "shim lock protocol"
entry point.
Do not install the EFI PXE APIs when using a shim, since if shim finds
EFI_PXE_BASE_CODE_PROTOCOL on the loaded image's device handle then it
will attempt to download files afresh instead of using the files
already downloaded by iPXE and exposed via the EFI_SIMPLE_FILE_SYSTEM
protocol. (Experience shows that there is no point in trying to get a
fix for this upstreamed into shim.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
| |
The UEFI shim includes a "shim lock protocol" that can be used by a
third party second stage loader such as GRUB to verify a kernel image.
Add definitions for the relevant portions of this protocol interface.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
| |
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Most image flags are independent values: any combination of flags may
be set for any image, and the flags for one image are independent of
the flags for any other image. The "selected" flag does not follow
this pattern: at most one image may be marked as selected at any time.
When invoking a kernel via the UEFI shim, there will be multiple
"special" images: the selected kernel itself, the shim image, and
potentially a shim-signed GRUB binary to be used as a crutch to assist
shim in loading the kernel (since current versions of the UEFI shim
are not capable of directly loading a Linux kernel).
Remove the "selected" image flag and replace it with a general concept
of an image tag with the same semantics: a given tag may be assigned
to at most one image, an image may be found by its tag only while the
image is currently registered, and a tag will survive unregistration
and reregistration of an image (if it has not already been assigned to
a new image). For visual consistency, also replace the current image
pointer with a current image tag.
The image pointer stored within the image tag holds only a weak
reference to the image, since the selection of an image should not
prevent that image from being freed. (The strong reference to the
currently executing image is held locally within the execution scope
of image_exec(), and is logically separate from the current image
pointer.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Versions 15.4 and earlier of the UEFI shim are incapable of correctly
parsing the command line in order to extract the second stage loader
filename, and will always attempt to load "grubx64.efi" or equivalent.
Versions 15.3 and later of the UEFI shim are currently incapable of
loading a Linux kernel directly anyway, since the kernel does not
include SBAT metadata. These versions will require a genuine
shim-signed GRUB binary to be used as a crutch to assist shim in
loading a Linux kernel.
This leaves versions 15.2 and earlier of the UEFI shim (as currently
used in e.g. RHEL7) as being capable of directly loading a Linux
kernel, but incorrectly attempting to load it using the filename
"grubx64.efi" or equivalent. To support the bugs in these older
versions of the UEFI shim, allow the currently selected image to be
opened via any filename of the form "grub*.efi".
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When invoking a kernel via the UEFI shim, the kernel (and potentially
also a helper binary such as GRUB) must be accessible via the virtual
filesystem exposed via EFI_SIMPLE_FILE_SYSTEM_PROTOCOL but must not be
present in the magic initrd constructed from all registered images.
Allow for images to be flagged as hidden, which will cause them to be
excluded from API-level lists of all images such as the virtual
filesystem directory contents, the magic initrd, or the Multiboot
module list. Hidden images remain visible to iPXE commands including
"imgstat", which will show a "[HIDDEN]" flag for such images.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
| |
Show the original filename as used by the consumer when calling our
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL's Open() method.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
| |
Try searching for a matching registered image before checking for
fixed filenames (such as "initrd.magic" for the dynamically generated
magic initrd file). This minimises surprise by ensuring that an
explicitly downloaded image will always be used verbatim.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
As documented in commits 6a004be ("[efi] Support the initrd
autodetection mechanism in newer Linux kernels") and 04e60a2 ("[efi]
Omit EFI_LOAD_FILE2_PROTOCOL for a zero-length initrd"), the choice in
Linux of using a fixed device path requires bootloaders to allow for
the fact that a previous bootloader may have already installed a
handle with the fixed device path.
We currently deal with this situation by reusing the existing handle,
replacing the EFI_LOAD_FILE2_PROTOCOL instance with our own. Simplify
the code by instead uninstalling the EFI_DEVICE_PATH_PROTOCOL instance
from the existing handle (if present), thereby allowing the creation
of a new handle to succeed.
Create the new handle only if we have a non-empty initrd to provide.
This works around bugs in bootloaders such as the systemd EFI stub
that fail to allow for the existence of multiple-bootloader chains.
(The workaround is not comprehensive: if the user has downloaded other
images in iPXE before invoking the systemd Unified Kernel Image (UKI),
then the systemd EFI stub will still crash and burn since it fails to
allow for the fact that a previous bootloader has already installed a
handle with the fixed device path.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We unregister script images during their execution, to prevent a
"boot" command from re-executing the containing script. This also has
the side effect of preventing executing scripts from showing up within
the Linux magic initrd image (or the Multiboot module list).
Additional logic in bzimage.c and efi_file.c prevents a currently
executing kernel from showing up within the magic initrd image.
Similar logic in multiboot.c prevents the Multiboot kernel from
showing up as a Multiboot module.
This still leaves some corner cases that are not covered correctly.
For example: when using a gzip-compressed kernel image, nothing will
currently hide the original compressed image from the magic initrd.
Fix by moving the logic that temporarily unregisters the current image
from script_exec() to image_exec(), so that it applies to all image
types, and simplify the magic initrd and Multiboot module list
construction logic on the basis that no further filtering of the
registered image list is necessary.
This change has the side effect of hiding currently executing EFI
images from the virtual filesystem exposed by iPXE. For example, when
using iPXE to boot wimboot, the wimboot binary itself will no longer
be visible within the virtual filesystem.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
|
|
| |
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|