Use the standard "pushl $function ; pushw %cs ; call prot_call"
sequence everywhere that prot_call() is used.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On a 64-bit CPU, any modification of a register by 32-bit or 16-bit
code will destroy the invisible upper 32 bits of the corresponding
64-bit register. For example: a 32-bit "pushl %eax" followed by a
"popl %eax" will zero the upper half of %rax. This differs from the
treatment of upper halves of 32-bit registers by 16-bit code: a
"pushw %ax" followed by a "popw %ax" will leave the upper 16 bits of
%eax unmodified.
Inline assembly generated using REAL_CODE() or PHYS_CODE() will
therefore have to preserve the upper halves of all registers, to avoid
clobbering registers that gcc expects to be preserved.
Output operands from REAL_CODE() and PHYS_CODE() assembly may
therefore contain undefined values in the upper 32 bits.
Fix by using explicit variable widths (e.g. uint32_t) for
non-discarded output operands, to ensure that undefined values in the
upper 32 bits of 64-bit registers are ignored.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Move most arch/i386 files to arch/x86, and adjust the contents of the
Makefiles and the include/bits/*.h headers to reflect the new
locations.
This patch makes no substantive code changes, as can be seen using a
rename-aware diff (e.g. "git show -M5").
This patch does not make the pcbios platform functional for x86_64; it
merely allows it to compile without errors.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit c64747d ("[librm] Speed up real-to-protected mode transition
under KVM") rounded down the .text16 segment address calculated in
alloc_basemem() to a multiple of 64 bytes in order to speed up mode
transitions under KVM.
This creates a potential discrepancy between alloc_basemem() and
free_basemem(), meaning that free_basemem() may free less memory than
was allocated by alloc_basemem().
Fix by padding the calculated sizes of both .text16 and .data16 to a
multiple of 64 bytes at build time.
Debugged-by: Yossef Efraim <yossefe@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Guard against various corner cases (such as zero-length buffers, zero
alignments, and integer overflow when rounding up allocation lengths
and alignments) and ensure that the struct io_buffer is correctly
aligned even when the caller requests a non-zero alignment for the I/O
buffer itself.
Add self-tests to verify that the resulting alignments and lengths are
correct for a range of allocations.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit f3fbb5f ("[malloc] Avoid integer overflow for excessively large
memory allocations") fixed signed integer overflow issues caused by
the use of ssize_t, but did not guard against unsigned integer
overflow.
Add explicit checks for unsigned integer overflow where needed. As a
side bonus, erroneous calls to malloc_dma() with an (illegal) size of
zero will now fail cleanly.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
ath_rx_init() demonstrates some serious confusion over how to use
pointers, resulting in (uint32_t*)NULL being used as a temporary
variable. This does not end well.
The broken code in question is performing manual alignment of I/O
buffers, which can now be achieved more simply using alloc_iob_raw().
Fix by removing ath_rxbuf_alloc() entirely.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The various early-exit paths in parse_uri() accidentally bypass the
URI field decoding. The result is that opaque or relative URIs do not
undergo URI field decoding, resulting in double-encoding when the URIs
are subsequently used. For example:
#!ipxe
set mac ${macstring}
imgfetch /boot/by-mac/${mac:uristring}
would result in an HTTP GET such as
GET /boot/by-mac/00%253A0c%253A29%253Ac5%253A39%253Aa1 HTTP/1.1
rather than the expected
GET /boot/by-mac/00%3A0c%3A29%3Ac5%3A39%3Aa1 HTTP/1.1
Fix by ensuring that URI decoding is always applied regardless of the
URI format.
Reported-by: Andrew Widdersheim <awiddersheim@inetu.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
TFTP URIs are intrinsically problematic, since:
- TFTP servers may use either normal slashes or backslashes as a
directory separator,
- TFTP servers allow filenames to be specified using relative paths
(with no initial directory separator),
- TFTP filenames present in a DHCP filename field may use special
characters such as "?" or "#" that prevent parsing as a generic URI.
As of commit 7667536 ("[uri] Refactor URI parsing and formatting"), we
have directly constructed TFTP URIs from DHCP next-server and filename
pairs, avoiding the generic URI parser. This eliminated the problems
related to special characters, but indirectly made it impossible to
parse a "tftp://..." URI string into a TFTP URI with a non-absolute
path.
Re-introduce the convention of requiring an extra slash in a
"tftp://..." URI string in order to specify a TFTP URI with an initial
slash in the filename. For example:
tftp://192.168.0.1/boot/pxelinux.0 => RRQ "boot/pxelinux.0"
tftp://192.168.0.1//boot/pxelinux.0 => RRQ "/boot/pxelinux.0"
This is ugly, but there seems to be no other sensible way to provide
the ability to specify all possible TFTP filenames.
A side-effect of this change is that format_uri() will no longer add a
spurious initial "/" when formatting a relative URI string. This
improves the console output when fetching an image specified via a
relative URI.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The OCSP responder URI included within an X.509 certificate may or may
not include a trailing slash. We currently rely on the fact that
format_uri() incorrectly inserts an initial slash, which we include
unconditionally within the OCSP request URI.
Switch to using uri_encode() directly, and insert a slash only if the
X.509 certificate's OCSP responder URI does not already include a
trailing slash.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 53d2d9e ("[uri] Generalise tftp_uri() to pxe_uri()") introduced
a regression in which an NFS root path would no longer be treated as
an unsupported root path, causing a boot with an NFS root path to fail
with a "Could not open SAN device" error.
Reported-by: David Evans <dave.evans55@googlemail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some protocols (such as ARP) may modify the received packet and re-use
the same I/O buffer for transmission of a reply. The SMSC95XX
transmit header is larger than the receive header: the re-used I/O
buffer therefore does not have sufficient headroom for the transmit
header, and the ARP reply will therefore fail to be transmitted. This
is essentially the same problem as in commit 2e72d10 ("[ncm] Reserve
headroom in received packets").
Fix by reserving sufficient space at the start of each received packet
to allow for the difference between the lengths of the transmit and
receive headers.
This problem is not caught by the current driver development test
suite (documented at http://ipxe.org/dev/driver), since even the large
file transfer tests tend to completely sufficiently quickly that there
is no need for the server to ever send an ARP request. The failure
shows up only when using a very slow protocol such as RFC7440-enhanced
TFTP (as used by Windows Deployment Services).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The LED pins are configured by default as GPIO inputs. While it is
conceivable that a board might actually use these pins as GPIOs, no
such board is known to exist.
The Linux smsc95xx driver configures these pins unconditionally as LED
outputs. Assume that it is safe to do likewise.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Expose the network interface name (e.g. "net0") as a setting. This
allows a script to obtain the name of the most recently opened network
interface via ${netX/ifname}.
Signed-off-by: Andrew Widdersheim <amwiddersheim@gmail.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add a named CONFIG=cloud configuration, which enables console types
useful for obtaining output from virtual machines in public clouds
such as AWS EC2.
An image suitable for use in AWS EC2 can be built using
make bin/ipxe.usb CONFIG=cloud EMBED=config/cloud/aws.ipxe
The embedded script will direct iPXE to download and execute the EC2
"user-data" file, which is always available to an EC2 VM via the URI
http://169.254.169.254/latest/user-data (regardless of the VPC
networking settings). The boot can therefore be controlled by
modifying the per-instance user data, without having to modify the
boot disk image.
Console output can be obtained via syslog (with a syslog server
configured in the user-data script), via the AWS "System Log" (after
the instance has been stopped), or as a last resort from the log
partition on the boot disk.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The three nominally-disambiguated ENOTSUP errors accidentally all used
the same error disambiguator, rendering them identical. Fix by
changing all three values. We avoid reusing the 0x01 disambiguator
value, since that remains ambiguous in older binaries.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some BIOS console redirection capabilities do not work well with the
colourised debug messages used by iPXE. We already allow the range of
colours to be controlled via the DBGCOL=... build parameter. Extend
this syntax to allow DBGCOL=0 to be used to mean "disable colours".
Requested-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide a debug function check_bios_interrupts() to look for changes
to the interrupt vector table. This can be useful when investigating
the behaviour (including crashes) of external PXE NBPs.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
For historical reasons, iPXE sets the current working URI to the root
of the TFTP server whenever the TFTP server address is changed. This
was originally implemented in the hope of allowing a DHCP-provided
TFTP filename to be treated simply as a relative URI. This usage
turns out to be impractical since DHCP-provided TFTP filenames may
include characters which would have special significance to the URI
parser, and so the DHCP next-server+filename combination is now
handled by the dedicated pxe_uri() function instead.
The practice of setting the current working URI to the root of the
TFTP server is potentially helpful for interactive uses of iPXE,
allowing a user to type e.g.
iPXE> dhcp
Configuring (net0 52:54:00:12:34:56)... ok
iPXE> chain pxelinux.0
and have the URI "pxelinux.0" interpreted as being relative to the
root of the TFTP server provided via DHCP.
The current implementation of tftp_apply_settings() has an unintended
flaw. When the "dhcp" command is used to renew a DHCP lease (or to
pick up potentially modified DHCP options), the old settings block
will be unregistered before the new settings block is registered.
This causes tftp_apply_settings() to believe that the TFTP server has
been changed twice (to 0.0.0.0 and back again), and so the current
working URI will always be set to the root of the TFTP server, even if
the DHCP response provides exactly the same TFTP server as previously.
Fix by doing nothing in tftp_apply_settings() whenever there is no
TFTP server address.
Debugged-by: Andrew Widdersheim <awiddersheim@inetu.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Update the image's recorded URI when a download redirection occurs.
This ensures that URIs relative to a redirected download are resolved
correctly.
In particular, this allows for the use of relative URIs in scripts
that are themselves downloaded via a redirection, such as the HTTP 301
redirection used to fix up URIs pointing to directories but omitting
the trailing slash (e.g. "http://boot.ipxe.org/demo", which will be
redirected to "http://boot.ipxe.org/demo/").
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Resolve redirection URIs as being relative to the original HTTP
request URI, rather than treating them as being implicitly relative to
the current working URI.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 5de45cd ("[romprefix] Report a pessimistic runtime size
estimate") set the PCI3.0 "runtime size" field equal to the worst-case
runtime size, on the basis that there is no guarantee that PMM
allocation will succeed and hence no guarantee that we will be able to
shrink the ROM image.
On a PCI3.0 system where PMM allocation would succeed, this can cause
the BIOS to unnecessarily refuse to initialise the iPXE ROM due to a
perceived shortage of option ROM space.
Fix by reporting the best-case runtime size via the PCI header, and
checking that we have sufficient runtime space (if applicable). This
allows iPXE ROMs to initialise on PCI3.0 systems that might otherwise
fail due to a shortage of option ROM space.
This may cause iPXE ROMs to fail to initialise on PCI3.0 systems where
PMM is broken. (Pre-PCI3.0 systems are unaffected since there must
already have been sufficient option ROM space available for the
initialisation entry point to be called.)
On balance, it seems preferable to avoid breaking "good" systems
(PCI3.0 with working PMM) at the cost of potentially breaking "bad"
systems (PCI3.0 with broken PMM).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The GuestRPC mechanism (used for VMWARE_SETTINGS and CONSOLE_VMWARE)
does not use any real-mode code and so can be exposed in both 64-bit
and 32-bit builds.
Reported-by: Matthew Helton <mwhelton@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow the use of the iPXE DRBG implementation in BSD-licensed
projects.
Requested-by: Sean Davis <dive@hq.endersgame.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow the use of the iPXE DRBG implementation in BSD-licensed
projects.
Requested-by: Sean Davis <dive@hq.endersgame.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The SMSC95xx devices tend to be used in embedded systems with a
variety of ad-hoc mechanisms for storing the MAC address.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When USB network card drivers are used, the BIOS' legacy USB
capability is necessarily disabled since there is no way to share the
host controller between the BIOS and iPXE.
Commit 3726722 ("[usb] Add basic support for USB keyboards") added
support allowing a USB keyboard to be used within iPXE. However,
external code such as a PXE NBP has no way to utilise this support,
and so a USB keyboard cannot be used to control a PXE NBP loaded from
a USB network card.
Add support for injecting keypresses from any iPXE console into the
BIOS keyboard buffer. This allows external code such as a PXE NBP to
function with a USB keyboard even after the BIOS' legacy USB
capability has been disabled.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The build system allows for additional drivers (or other objects) to
be specified using build targets such as
make bin/intel--realtek.usb
make bin/8086100e--8086100f.mrom
This currently fails if the base target is the "bin/ipxe.*" all-drivers
target, e.g.
make bin/ipxe--acm.usb
Fix the build target parsing logic to allow additional drivers (or
other objects) to be included on top of the base all-drivers target.
This can be used to include USB network card drivers, which are not
yet included by default in the all-drivers build.
Reported-by: Andrew Sloma <asloma@lenovo.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some xHCI controllers (such as qemu's emulated xHCI controller) do not
correctly handle zero-length packets that are part of a TRB chain.
The zero-length TRB ends up being squashed and does not result in a
zero-length packet as seen by the device.
Work around this problem by marking the zero-length packet as
belonging to a separate transfer descriptor.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some hubs (e.g. the Avocent Corp. Virtual Hub on a Lenovo x3550
Integrated Management Module) have been observed to require more than
the standard 200ms for ports to stabilise, with the result that
devices appear to disconnect and immediately reconnect during the
initial bus enumeration.
Work around this problem by allowing specific hubs an extra 500ms of
settling time.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Record the speed of a USB device based on the port's speed at the time
that the device was enabled. This allows us to remember the device's
speed even after the device has been disconnected (and so the port's
current speed has changed).
In particular, this allows us to correctly identify the transaction
translator for a low-speed or full-speed device after the device has
been disconnected.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The usb_message() and usb_stream() functions currently check for
port->speed==USB_SPEED_NONE to determine whether or not a device has
been unplugged. This test will give a false negative result if a new
device has been plugged in before the hotplug mechanism has finished
handling the removal of the old device.
Fix by checking instead the port->disconnected flag, which is now
cleared only after completing the removal of the old device.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide BIT_QWORD_PTR() to allow for easy extraction of non-endian
fields (e.g. Infiniband GUIDs) without unnecessary byte swapping.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Tested using QEMU and usbredir to expose the LAN9512 chip present on a
Raspberry Pi.
There is a known issue with the LAN9512: an extra two bytes are
appended to every transmitted packet. These two bytes comprise:
{ 0x00, 0x08 } if packet length == 0 (mod 8)
{ CRC[0], 0x00 } if packet length == 7 (mod 8)
{ CRC[0], CRC[1] } otherwise
The extra bytes are appended whether the Ethernet CRC is generated
manually or added automatically by the hardware. The issue occurs
with the Linux kernel driver as well as the iPXE driver. It appears
to be an undocumented hardware errata.
TCP/IP traffic is not affected, since the IP header length field
causes the extraneous bytes to be discarded by the receiver. However,
protocols that rely on the length of the Ethernet frame (such as FCoE
or iPXE's "lotest" protocol) will be unusable on this hardware.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On some models (notably ICH), the PHY reset mechanism appears to be
broken. In particular, the PHY_CTRL register will be correctly loaded
from NVM but the values will not be propagated to the "OEM bits" PHY
register. This typically has the effect of dropping the link speed to
10Mbps.
Since the original version of this driver in commit 945e428 ("[intel]
Replace driver for Intel Gigabit NICs"), we have always worked around
this problem by skipping the PHY reset if the link is already up.
Enhance this workaround by explicitly checking for known-broken PCI
IDs.
Reported-by: Robin Smidsrød <robin@smidsrod.no>
Tested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE does not call shutdown() before invoking a COMBOOT executable,
since the executable is allowed to make API calls back into iPXE. If
a background picture is used, then the console will not be restored to
text mode before invoking the COMBOOT executable. This can cause
undefined behaviour.
Fix by adding an explicit call to console_reset() immediately before
invoking a COMBOOT or COM32 executable, analogous to the call made to
console_reset() immediately before invokving a PXE NBP.
Debugged-by: Andrew Widdersheim <awiddersheim@inetu.net>
Tested-by: Andrew Widdersheim <awiddersheim@inetu.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
For switches which remain permanently in the non-forwarding state (or
which erroneously report a non-forwarding state), ensure that iPXE
will eventually give up waiting for the link to become unblocked.
Originally-fixed-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
If we detect (via STP) that a switch port is in a non-forwarding
state, then the link is marked as being temporarily blocked and DHCP
discovery will be deferred until the link becomes unblocked.
The timer used to decide when to give up waiting for ProxyDHCPOFFERs
is currently based on the time that DHCP discovery was started, and
makes no allowances for any time spent waiting for the link to become
unblocked. Consequently, if STP is used then the timeout for
ProxyDHCPOFFERs becomes essentially zero.
Fix by resetting the recorded start time whenever DHCP discovery is
deferred due to a blocked link.
Debugged-by: Sebastian Roth <sebastian.roth@zoho.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The name "vesafb" is intrinsically specific to a BIOS environment.
Generalise the build configuration option CONSOLE_VESAFB to
CONSOLE_FRAMEBUFFER, in preparation for adding EFI framebuffer
support.
Existing configurations using CONSOLE_VESAFB will continue to work.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Avoid accidentally dereferencing a NULL cipher context pointer for
plaintext blocks (which are usually messages with a block length of
zero, indicating a missing block).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
UEFI UNDI is a hideously ugly lump of poorly specified garbage bolted
on as an appendix of the UEFI specification. My personal favourite
line from the UNDI 'specification' is section E.2.2, which states
"Basically, the rule is: Do it right, or don't do it at all". The
author appears to believe that such exhortations are a viable
substitute for documenting what it is that the wretched reader is
supposed to, in fact, do.
(Second favourite is the section listing the pros and cons of various
driver types. This fails to identify a single con for the mythical
"Hardware UNDI", a design so insanely intrinsically slow that it
appears to have been the inspiration for the EFI_USB_IO_PROTOCOL.)
UNDI is functionally isomorphic to the substantially less preposterous
EFI_SIMPLE_NETWORK_PROTOCOL. Provide an UNDI interface (as a thin
wrapper around the existing SNP interface) to allow for use by
third-party software that has made poor life choices.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Calling EDK2's OpenProtocol() with attributes BY_DRIVER|EXCLUSIVE will
call DisconnectController() in a loop to attempt to dislodge any
existing openers with attributes BY_DRIVER. The loop will continue
indefinitely until either no such openers remain, or until
DisconnectController() returns an error.
If our driver binding protocol's Stop() method is ever called to
disconnect a device that we are not in fact driving, then return
EFI_DEVICE_ERROR rather than EFI_SUCCESS, in order to break this
potentially infinite loop.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The Microsoft PE/COFF specification defines the MajorLinkerVersion and
MinorLinkerVersion fields as "The linker major version number" and
"The linker minor version number" respectively, and has nothing more
to say on the matter. These fields have no significance: they do not
affect the interpretation of the remainder of the file, but merely
provide diagnostic information for interested humans to read.
Apparently, versions 2.4 and earlier of the Microsoft linker produced
binaries so incorrigibly cursed that even to attempt to parse such a
binary would risk summoning a plague of enraged spiders. To protect
users from unwanted arachnids, ImageHlp.dll's MapAndLoad() function
will helpfully fail to map and/or load a 32-bit binary unless the
linker version field indicates version 2.5 or later. (64-bit binaries
are exempt from such helpfulness.)
Work around the broken Microsoft ImageHlp.dll library by providing a
linker version number that will satisfy the arbitrary whims of the
MapAndLoad() function.
This mirrors wimboot commit 670c7e2 ("[efi] Work around broken 32-bit
PE executable parsing in ImageHlp.dll").
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use INT 1a,564e to notify the BIOS of each network device that we
detect. This provides an opportunity for the BIOS to implement
platform policy such as changing the MAC address by issuing a call to
PXENV_UNDI_SET_STATION_ADDRESS.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Invoke INT 1a,564e whenever a PXE stack is activated, passing the
address of the PXENV+ structure in %es:%bx. This is designed to allow
a BIOS to be notified when a PXE stack has been installed, providing
an opportunity for start-of-day commands such as setting the MAC
address according to a policy chosen by the BIOS.
PXE defines INT 1a,5650 as a means of locating the PXENV+ structure:
this call returns %ax=0x564e and the address of the PXENV+ structure
in %es:%bx. We choose INT 1a,564e as a fairly natural notification
call, using the parameters as would be returned by INT 1a,5650.
The full calling convention (documented as per section 3.1 of the PXE
specification) is:
INT 1a,564e - PXE installation notification
Enter:
%ax = 0x564e
%es = 16-bit segment address of the PXENV+ structure
%bx = 16-bit offset of the PXENV+ structure
Exit:
%edx may be trashed (as is the case for INT 1a,5650)
All other register contents must be preserved
CF is cleared
IF is preserved
All other flags are undefined
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Avoid dragging in unnecessary iPXE header files such as <ipxe/uuid.h>
and <ipxe/tables.h> when building host utilities, and ensure that
FILE_LICENCE() (present in the imported EDK2 headers) expands to a
no-op.
Reported-by: Michael Tautschnig <mt@debian.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 7d36a1b ("[build] Explicitly link efilink against -liberty")
introduced a dependency on libiberty to cope with old versions of
libbfd. This commit dates from 2008 and seems to apply only to what
are now extremely old versions of libbfd (prior to binutils 2.12).
There are systems (such as current Debian) which do not include
libiberty within the binutils packages. On such systems, our build
dependency on libiberty represents a pointless hurdle.
Remove the explicit dependency on libiberty, hoping that there are no
modern systems where this will cause a problem.
Suggested-by: Ben Hildred <42656e@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow the UEFI platform firmware to provide drivers for unrecognised
devices, by exposing our own implementation of EFI_USB_IO_PROTOCOL.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Make the class ID a property of the USB driver (rather than a property
of the USB device ID), and allow USB drivers to specify a wildcard ID
for any of the three component IDs (class, subclass, or protocol).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Generate a score for each possible USB device configuration based on
the available driver support, and select the configuration with the
highest score. This will allow us to prefer ECM over RNDIS (for
devices which support both) and will allow us to meaningfully select a
configuration even when we have drivers available for all functions
(e.g. when exposing unused functions via EFI_USB_IO_PROTOCOL).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The decision on whether or not a zero-length packet needs to be
transmitted is independent of the host controller and belongs in the
USB core.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
TCP/IP checksum fields are one's complement values and therefore have
two possible representations of zero: positive zero (0x0000) and
negative zero (0xffff).
In RFC768, UDP over IPv4 exploits this redundancy to repurpose the
positive representation of zero (0x0000) to mean "no checksum
calculated"; checksums are optional for UDP over IPv4.
In RFC2460, checksums are made mandatory for UDP over IPv4. The
wording of the RFC is such that the UDP header is mandated to use only
the negative representation of zero (0xffff), rather than simply
requiring the checksum to be correct but allowing for either
representation of zero to be used.
In RFC1071, an example algorithm is given for calculating the TCP/IP
checksum. This algorithm happens to produce only the positive
representation of zero (0x0000); this is an artifact of the way that
unsigned arithmetic is used to calculate a signed one's complement
sum (and its final negation).
A common misconception has developed (exemplified in RFC1624) that
this artifact is part of the specification. Many people have assumed
that the checksum field should never contain the negative
representation of zero (0xffff).
A sensible receiver will calculate the checksum over the whole packet
and verify that the result is zero (in whichever representation of
zero happens to be generated by the receiver's algorithm). Such a
receiver will not care which representation of zero happens to be used
in the checksum field.
However, there are receivers in existence which will verify the
received checksum the hard way: by calculating the checksum over the
remainder of the packet and comparing the result against the checksum
field. If the representation of zero used by the receiver's algorithm
does not match the representation of zero used by the transmitter (and
so placed in the checksum field), and if the receiver does not
explicitly allow for both representations to compare as equal, then
the receiver may reject packets with a valid checksum.
For UDP, the combined RFCs effectively mandate that we should generate
only the negative representation of zero in the checksum field.
For IP, TCP and ICMP, the RFCs do not mandate which representation of
zero should be used, but the misconceptions which have grown up around
RFC1071 and RFC1624 suggest that it would be least surprising to
generate only the positive representation of zero in the checksum
field.
Fix by ensuring that all of our checksum algorithms generate only the
positive representation of zero, and explicitly inverting this in the
case of transmitted UDP packets.
Reported-by: Wissam Shoukair <wissams@mellanox.com>
Tested-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow iPXE to coexist with other USB device drivers, by attaching to
the EFI_USB_IO_PROTOCOL instances provided by the UEFI platform
firmware.
The EFI_USB_IO_PROTOCOL is an unsurprisingly badly designed
abstraction of a USB device. The poor design choices intrinsic in the
UEFI specification prevent efficient operation as a network device,
with the result that devices operated using the EFI_USB_IO_PROTOCOL
operate approximately two orders of magnitude slower than devices
operated using our native EHCI or xHCI host controller drivers.
Since the performance is so abysmally slow, and since the underlying
problems are due to fundamental architectural mistakes in the UEFI
specification, support for the EFI_USB_IO_PROTOCOL host controller
driver is left as disabled by default. Users are advised to use the
native iPXE host controller drivers instead.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Many UEFI NBPs expect to find an EFI_PXE_BASE_CODE_PROTOCOL installed
in addition to the EFI_SIMPLE_NETWORK_PROTOCOL. Most NBPs use the
EFI_PXE_BASE_CODE_PROTOCOL only to retrieve the cached DHCP packets.
This implementation has been tested with grub.efi, shim.efi,
syslinux.efi, and wdsmgfw.efi. Some methods (such as Discover() and
Arp()) are not used by any known NBP and so have not (yet) been
implemented.
Usage notes for the tested bootstraps are:
- grub.efi uses EFI_PXE_BASE_CODE_PROTOCOL only to retrieve the
cached DHCP packet, and uses no other methods.
- shim.efi uses EFI_PXE_BASE_CODE_PROTOCOL to retrieve the cached
DHCP packet and to retrieve the next NBP via the Mtftp() method.
If shim.efi was downloaded via HTTP (or other non-TFTP protocol)
then shim.efi will blindly call Mtftp() with an HTTP URI as the
filename: this allows the next NBP (e.g. grubx64.efi) to also be
transparently retrieved by HTTP.
shim.efi can also use the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL to
retrieve files previously loaded by "imgfetch" or similar commands
in iPXE. The current implementation of shim.efi will use the
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL only if it does not find an
EFI_PXE_BASE_CODE_PROTOCOL; this patch therefore prevents this
usage of our EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. This logic could be
trivially reversed in shim.efi if needed.
- syslinux.efi uses EFI_PXE_BASE_CODE_PROTOCOL only to retrieve the
cached DHCP packet. Versions 6.03 and earlier have a bug which
may cause syslinux.efi to attach to the wrong NIC if there are
multiple NICs in the system (or if the UEFI firmware supports
IPv6).
- wdsmgfw.efi (ab)uses EFI_PXE_BASE_CODE_PROTOCOL to retrieve the
cached DHCP packets, and to send and retrieve UDP packets via the
UdpWrite() and UdpRead() methods. (This was presumably done in
order to minimise the amount of benefit obtainable by switching to
UEFI, by replicating all of the design mistakes present in the
original PXE specification.)
The EFI_DOWNGRADE_UX configuration option remains available for now,
until this implementation has received more widespread testing.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Merge the functionality of parse_next_server_and_filename() and
tftp_uri() into a single pxe_uri(), which takes a server address
(IPv4/IPv6/none) and a filename, and produces a URI using the rule:
- if the filename is a hierarchical absolute URI (i.e. includes a
scheme such as "http://" or "tftp://") then use that URI and ignore
the server address,
- otherwise, if the server address is recognised (according to
sa_family) then construct a TFTP URI based on the server address,
port, and filename
- otherwise fail.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We currently do not populate the ciaddr field in the constructed PXE
Boot Server ACK packet. This causes a WDS server to respond with a
broadcast packet, which is then ignored by wdsmgfw.efi since it does
not match the specified IP address filter.
Fix by populating ciaddr within the constructed PXE Boot Server ACK
packet.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Our SNP ReceiveFilters() method is a no-op, since we always (if
possible) use promiscuous mode for all network cards. The method
currently returns EFI_NOT_READY if the SNP interfaces are claimed for
use by iPXE, as with all other SNP methods.
The WDS bootstrap wdsmgfw.efi attempts to use both the PXE Base Code
protocol and the Simple Network Protocol simultaneously. This is
fundamentally broken, since use of the PXE Base Code protocol requires
us to disable the use of SNP (by claiming the interfaces for use by
iPXE), otherwise MnpDxe swallows all of the received packets before
our PXE Base Code's UdpRead() method is able to return them.
The root cause of this problem is that, as with BIOS PXE, the network
booting portions of the UEFI specification are less of a specification
and more of an application note sketchily describing how the original
hacked-together Intel implementation works. No sane design would ever
have included the UdpWrite() and UdpRead() methods.
Work around these fundamental conceptual flaws by unconditionally
returning success from efi_snp_receive_filters().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some distributions (observed with Ubuntu 15.04) place ldlinux.c32 in a
separate directory from isolinux.bin. Search for these files
separately, and allow an alternative location of ldlinux.c32 to be
provided via LDLINUX_C32=... on the make command line.
Reported-by: Adrian Koshka <adriankoshcha@teknik.io>
Tested-by: Adrian Koshka <adriankoshcha@teknik.io>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The debug directory size specified in the data directory should cover
only the EFI_IMAGE_DEBUG_DIRECTORY_ENTRY structure, not the whole of
the .debug section.
Reported-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add definitions of protocols observed to be used by wdsmgfw.efi, and
add a handle name type for ConIn, ConOut, and StdErr.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit edf74df ("[pxe] Always reconstruct packet for
PXENV_GET_CACHED_INFO") fixed the problems caused by returning stale
DHCP packets (e.g. from an earlier boot attempt using a different
network device), but broke interoperability with NBPs such as WDS
which may overwrite our cached (fake) DHCP packets and expect the
modified packets to be returned by a subsequent call to
PXENV_GET_CACHED_INFO.
Fix by constructing the fake DHCP packets immediately before
transferring control to a PXE NBP. Calls to PXENV_GET_CACHED_INFO
will now never modify the cached packets.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add debug wrappers for more boot services functions, and print
symbolic values rather than raw numbers where possible.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The raw EFI_HANDLE value is almost never useful to know, and simply
adds noise to the already verbose debug messages. Improve the
legibility of debug messages by using only the name generated by
efi_handle_name().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We attempt to mimic the behaviour of Intel's PXE ROM by skipping the
separate ProxyDHCPREQUEST if the ProxyDHCPOFFER already contains a
boot filename or a PXE boot menu.
Experimentation reveals that Intel's PXE ROM will also check for a
non-empty next-server address alongside the boot filename. Update our
test to match this behaviour.
Reported-by: Wissam Shoukair <wissams@mellanox.com>
Tested-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 09b057c ("[settings] Remove "uristring" setting type") removed
support for URI-encoded settings via the "uristring" setting type, on
the basis that such encoding was no longer necessary to avoid problems
with the command line parser.
Other valid use cases for the "uristring" setting type do exist: for
example, a password containing a '/' character expanded via
chain http://username:${password:uristring}@server.name/boot.php
Restore the existence of the "uristring" setting, avoiding the
potentially large stack allocations that were used in the old code
prior to commit 09b057c ("[settings] Remove "uristring" setting
type").
Requested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When booting without an embedded script, display the imgstat()
information immediately before executing the downloaded image. This
allows potentially useful diagnostic information (such as the detected
image type) to be observed by the user without needing to enter the
iPXE shell and manually download the image.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The current usage pattern of image_probe() is a legacy from the time
before commit 34b6ecb ("[image] Simplify image management") when
loading an image to its executable location in memory was a separate
action from actually executing the image.
Call image_probe() as soon as an image is registered. This allows
"imgstat" to display image type information for all images and allows
image-consuming code to assume that image->type is already set
correctly.
Ignore failures if image_probe() does not recognise the image, since
we do expect to handle unrecognised images (initrds, modules, etc).
Unrecognised images will be left with a NULL image->type, which
image-consuming code can easily check.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow the return status from an embedded image to propagate out to the
eventual return status from main(). When running under Linux, this
allows the pass/fail result of unit tests to be observable without
having to visually inspect the console output.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
A relatively common user mistake is to attempt to boot an EFI
executable (such as grub.efi) using a BIOS version of iPXE.
Unfortunately there are no signature checks that we can use to
unambiguously identify a PXE NBP, since a PXE NBP is just raw machine
code. We therefore have to accept anything sufficiently small to fit
into base memory as a valid PXE NBP.
We can detect that a file might be an EFI executable by checking for
the initial "MZ" signature bytes. This does not necessarily preclude
the file from also being a PXE NBP (since it would be possible to
create a hybrid binary which acts as both an EFI executable and a PXE
NBP, similar to the way in which wimboot and the Linux kernel are
hybrid binaries which act as both an EFI executable and a bzImage).
If the initial "MZ" signature bytes are present, then attempt to warn
the user by setting the image type to "PXE-NBP (may be EFI?)". We
can't (sensibly) prevent the user from accidentally running an EFI
executable as a PXE NBP, but we can at least make it easier for the
user to identify their mistake.
Inspired-by: Robin Smidsrød <robin@smidsrod.no>
Inspired-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some ProxyDHCP servers and PXE boot servers do not specify a DHCP
server identifier via option 54. We currently work around this in a
variety of ad-hoc ways:
- if a ProxyDHCPACK has no server identifier then we treat it as
having the correct server identifier,
- if a boot server ACK has no server identifier then we use the
packet's source IP address as the server identifier.
Introduce the concept of a DHCP server pseudo-identifier, defined as
being:
- the server identifier (option 54), or
- if there is no server identifier, then the next-server address
(siaddr),
- if there is no server identifier or next-server address, then the
DHCP packet's source IP address.
Use the pseudo-identifier in place of the server identifier when
handling ProxyDHCP and PXE boot server responses.
Originally-fixed-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The Infiniband link status change callback ipoib_link_state_changed()
may be called while the IPoIB device is closed, in which case there
will not be an IPoIB queue pair to be joined to the IPv4 broadcast
group. This leads to NULL pointer dereferences in ib_mcast_attach()
and ib_mcast_detach().
Fix by not attempting to join (or leave) the broadcast group unless we
actually have an IPoIB queue pair.
Signed-off-by: Wissam Shoukair <wissams@mellanox.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Rewrite the HTTP core to allow for the addition of arbitrary content
encoding mechanisms, such as PeerDist and gzip.
The core now exposes http_open() which can be used to create requests
with an explicitly selected HTTP method, an optional requested content
range, and an optional request body. A simple wrapper provides the
preexisting behaviour of creating either a GET request or an
application/x-www-form-urlencoded POST request (if the URI includes
parameters).
The HTTP SAN interface is now implemented using the generic block
device translator. Individual blocks are requested using http_open()
to create a range request.
Server connections are now managed via a connection pool; this allows
for multiple requests to the same server (e.g. for SAN blocks) to be
completely unaware of each other. Repeated HTTPS connections to the
same server can reuse a pooled connection, avoiding the per-connection
overhead of establishing a TLS session (which can take several seconds
if using a client certificate).
Support for HTTP SAN booting and for the Basic and Digest
authentication schemes is now optional and can be controlled via the
SANBOOT_PROTO_HTTP, HTTP_AUTH_BASIC, and HTTP_AUTH_DIGEST build
configuration options in config/general.h.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
UEFI platforms may provide a watchdog timer, which will reboot the
machine if an operating system takes more than five minutes to load.
This can cause long-lived iPXE downloads (or interactive shell
sessions) to unexpectedly reboot.
Fix by resetting the watchdog timer every ten seconds while the iPXE
main processing loop continues to run.
Reported-by: Bradley B Williams <bradleybwilliams@swbell.net>
Reported-by: John Clark <john.r.clark.3@gmail.com>
Reported-by: wdriever@gmail.com
Reported-by: Charlie Beima <cbeima@indiana.edu>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add support for SHA-224, SHA-384, and SHA-512 as digest algorithms in
X.509 certificates, and allow the choice of public-key, cipher, and
digest algorithms to be configured at build time via config/crypto.h.
Originally-implemented-by: Tufan Karadere <tufank@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The current implementation handles big-endian 24-bit integers (which
occur in several TLS record types) by treating them as big-endian
32-bit integers which are shifted by 8 bits. This can result in
"Invalid read" errors when running under valgrind, if the 24-bit field
happens to be exactly at the end of an I/O buffer.
Fix by ensuring that we touch only the three bytes which comprise the
24-bit integer.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Check for existence of the UART in uart_select(), not just in
uart_init(). This allows uart_select() to refuse to set a non-working
address in uart->base, which in turns means that the serial console
code will not attempt to use a non-existent UART.
Reported-by: Torgeir Wulfsberg <Torgeir.Wulfsberg@kongsberg.com>
Reported-by: Ján ONDREJ (SAL) <ondrejj@salstar.sk>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When the ability for iPXE to handle multiple serial ports was added,
the choice was made that the singular serial port referred to by
COMBOOT calls should mean the port used for the serial console. This
unintentionally caused IMAGE_COMBOOT to also enable CONSOLE_SERIAL.
Fix by providing a weak-symbol version of the serial console which
will be used if serial console support was not explicitly enabled.
Reported-by: Torgeir Wulfsberg <Torgeir.Wulfsberg@kongsberg.com>
Reported-by: Ján ONDREJ (SAL) <ondrejj@salstar.sk>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We do not set up any kind of virtual addressing before invoking an
ELFBoot image. Reject if the image's program headers indicate that
virtual addresses are not equal to physical addresses.
This avoids problems when loading some RHEL5 kernels, which seem to
include ELFBoot headers using virtual addressing. With this change,
these kernels are no longer detected as ELFBoot, and so may be
(correctly) detected as bzImage instead.
Reported-by: Torgeir.Wulfsberg@kongsberg.com
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow line buffer to accumulate multiple lines, with buffered_line()
returning each freshly-completed line as it is encountered. This
allows buffered lines to be subsequently processed as a group.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
VLAN and 802.11 devices use a network device operations structure that
wraps an underlying structure. For example, the vlan_operations
structure wraps the network device operations structure of the
underlying trunk device. This can cause false positives from the
current implementation of netdev_irq_supported(), which will always
report that VLAN devices support interrupts since it has no visibility
into the support provided by the underlying trunk device.
Fix by allowing network devices to explicitly flag that interrupts are
not supported, despite the presence of an irq() method.
Originally-fixed-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iscsi_tx_done() is missing "break" statements at the end of each case.
(Fortunately, this happens not to cause a bug in practice, since
iscsi_login_request_done() is effectively a no-op when completing a
data-out PDU.)
Reported-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Extend the IPv6 concept of "scope ID" (indicating the network device
index) to IPv4 socket addresses, so that IPv4 multicast transmissions
may specify the transmitting network device.
The scope ID is not (currently) exposed via the string representation
of the socket address, since IPv4 does not use the IPv6 concept of
link-local addresses (which could legitimately be specified in a URI).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Redefine various IPv4 address constants and testing macros to avoid
unnecessary byte swapping at runtime, and slightly rename the macros
to prevent code from accidentally using the old definitions.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Avoid using zero as a network device index, so that a zero
sin6_scope_id can be used to mean "unspecified" (rather than
unintentionally meaning "net0").
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When an IPv6 socket address string specifies a link-local or multicast
address but does not specify the requisite network device name
(e.g. "fe80::69ff:fe50:5845" rather than "fe80::69ff:fe50:5845%net0"),
assume the use of "netX".
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Remove AXTLS headers now that no AXTLS code remains, with many thanks
to the AXTLS project for use of their cryptography code over the past
several years.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Replace the AES implementation from AXTLS with a dedicated iPXE
implementation which is slightly smaller and around 1000% faster.
This implementation has been verified using the existing self-tests
based on the NIST AES test vectors.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Generalise the existing support for performing CBC-mode block cipher
tests, and update the code to use okx() for neater reporting of test
results.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
xfer_buffer() uses intf_get_dest_op() to obtain the destination
interface for xfer_deliver(), in order to check that this is the same
interface which provides xfer_buffer(). The return value from
intf_get_dest_op() (which contains the actual method implementing
xfer_deliver()) is not used.
On some gcc versions, this triggers a "value computed is not used"
warning, since the explicit type cast included within the
intf_get_dest_op() macro is treated as a "value computed".
Fix by explicitly casting the result of intf_get_dest_op() to void.
Reported-by: Matthew Helton <mwhelton@gmail.com>
Reported-by: James A. Peltier <jpeltier@sfu.ca>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Reduce the cost of implementing object methods which convey no
information beyond the fact that the method has been called.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide profile_custom() as a trivial wrapper around profile_update()
to allow for the use of the profiling infrastructure by code using
timers other than the default profile_timestamp() provider.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide an inject_corruption() function that can be used to randomly
corrupt data bytes with configurable probabilities.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide a generic inject_fault() function that can be used to inject
random faults with configurable probabilities.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add a named configuration for qemu, based on the config.ipxe.general.h
file taken from the current qemu repository and enabling the option to
work around the missing EFI_PXE_BASE_CODE_PROTOCOL.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE does not currently provide EFI_PXE_BASE_CODE_PROTOCOL: this
causes failures when chainloading bootloaders such as shim.efi which
assume that this protocol will be present.
Provide the ability to work around these problems via the build
configuration option EFI_DOWNGRADE_UX. If this option is enabled,
then we will not install our usual EFI_LOAD_FILE_PROTOCOL
implementation, thereby allowing the platform firmware to install its
own EFI_PXE_BASE_CODE_PROTOCOL implementation on top of our
EFI_SIMPLE_NETWORK_PROTOCOL handle.
A somewhat major side-effect of this workaround is that almost all
iPXE features will be disabled.
This configuration option will be removed in future when support for
EFI_PXE_BASE_CODE_PROTOCOL is added.
Requested-by: Laszlo Ersek <lersek@redhat.com>
Requested-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Fix the TxBuf value filled in by GetStatus() to report the transmit
buffer address as required by the (now clarified) specification.
Simplify "interrupt" handling in GetStatus() to report only that one
or more packets have been transmitted or received; there is no need to
report one GetStatus() "interrupt" per packet.
Simplify receive handling to dequeue received packets immediately from
the network device into an internal list (thereby avoiding the hacks
previously used to determine when to report new packet arrivals).
Originally-fixed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Expose the high bit of the VGA text attribute byte via the ANSI SGR
parameters 5 ("blink on") and 25 ("blink off").
Note that some video cards (and virtual machines) may display a high
intensity background colour instead of blinking text.
Signed-off-by: Christian Nilsson <nikize@gmail.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Multicast MAC addresses will never have REMAC cache entries, and the
corresponding multicast IPoIB MAC address cannot be obtained simply by
issuing an ARP request.
For the trivial volume of multicast packets that we expect to send in
any realistic scenario, the simplest solution is to send them as
broadcasts instead.
Reported-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We currently do not wait for a received FIN before exiting to boot a
loaded OS. In the common case of booting from an HTTP server, this
means that the TCP connection is left consuming resources on the
server side: the server will retransmit the FIN several times before
giving up.
Fix by initiating a graceful close of all TCP connections and waiting
(for up to one second) for all connections to finish closing
gracefully (i.e. for the outgoing FIN to have been sent and ACKed, and
for the incoming FIN to have been received and ACKed at least once).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Older, out-of-tree Xen kernel modules (such as those provided with
SuSE Linux Enterprise Server 11) do not clear the leftover "event
pending" bit when opening an event channel. Consequently, no event is
ever delivered to indicate that there is information in the XenStore
ring buffer, and the system hangs shortly after loading the
xen-platform-pci kernel module.
Work around this problem by always waiting for the XenStore event
channel to be signalled, and clearing the event before processing the
received data.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The only way to map an eIPoIB MAC address (REMAC) to an IPoIB MAC
address is to intercept an incoming ARP request or reply.
If we do not have an REMAC cache entry for a particular destination
MAC address, then we cannot transmit the packet. This can arise in at
least two situations:
- An external program (e.g. a PXE NBP using the UNDI API) may attempt
to transmit to a destination MAC address that has been obtained by
some method other than ARP.
- Memory pressure may have caused REMAC cache entries to be
discarded. This is fairly likely on a busy network, since REMAC
cache entries are created for all received (broadcast) ARP
requests. (We can't sensibly avoid creating these cache entries,
since they are required in order to send an ARP reply, and when we
are being used via the UNDI API we may have no knowledge of which
IP addresses are "ours".)
Attempt to ameliorate the situation by generating a semi-spurious ARP
request whenever we find a missing REMAC cache entry. This will
hopefully trigger an ARP reply, which would then provide us with the
information required to populate the REMAC cache.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As with the neighbour cache, discarding an REMAC cache entry is
potentially very disruptive.
Originally-fixed-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Avoid accidentally returning stale packets (e.g. for a previously
attempted network device) by always constructing a fresh DHCP packet.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
If the link is blocked (e.g. due to a Spanning Tree Protocol port not
yet forwarding packets) then defer DHCP discovery until the link
becomes unblocked.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
A fairly common end-user problem is that the default configuration of
a switch may leave the port in a non-forwarding state for a
substantial length of time (tens of seconds) after link up. This can
cause iPXE to time out and give up attempting to boot.
We cannot force the switch to start forwarding packets sooner, since
any attempt to send a Spanning Tree Protocol bridge PDU may cause the
switch to disable our port (if the switch happens to have the Bridge
PDU Guard feature enabled for the port).
For non-ancient versions of the Spanning Tree Protocol, we can detect
whether or not the port is currently forwarding and use this to inform
the network device core that the link is currently blocked.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When Spanning Tree Protocol (STP) is used, there may be a substantial
delay (tens of seconds) from the time that the link goes up to the
time that the port starts forwarding packets.
Add a generic concept of a "blocked link" (i.e. a link which is up but
which is not expected to communicate successfully), and allow "ifstat"
to indicate when a link is blocked.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
In some Ethernet framing variants the two-byte protocol field is used
as a length, with the Ethernet header being followed by an IEEE 802.2
LLC header. The first two bytes of the LLC header are the DSAP and
SSAP.
If the received Ethernet packet appears to use this framing, then
interpret the two-byte DSAP and SSAP as being the network-layer
protocol. This allows support for receiving Spanning Tree Protocol
frames (which use an LLC header with {DSAP,SSAP}=0x4242) to be added
without requiring a full LLC protocol layer.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The size of the .mrom payload (the second PCI ROM image) is defined in
its PCI header. The code type for the .mrom payload image is
deliberately set to an invalid value (0xff) to ensure that no BIOS
tries to parse anything in the image other than the PCI header.
Since the code type is not set to 0x00 ("Intel x86, PC-AT
compatible"), bytes 0x02-0x17 should not be interpreted by the BIOS as
being in the standard ISA expansion ROM format. In particular, the
byte at offset 0x02 does not represent the length of the ROM image (in
512-byte blocks).
However, some Dell BIOSes seem to erroneously use the byte at offset
0x02 to determine the length of the .mrom payload when walking the
list of PCI ROM images. Since this byte is currently set to zero,
this can lead to the BIOS getting stuck in an infinite loop during
POST. (This problem may not arise if the .mrom payload is the final
image in the ROM, since the BIOS will then have no reason to attempt
to locate the next image.)
One possible workaround would be to put the real payload size in this
byte, but doing so would constrain the .mrom payload size to 128kB
(see commit 8049a52 ("[mromprefix] Allow for .mrom images larger than
128kB") for more details).
Another possible workaround would be to put the real payload size as a
word in bytes 0x02-0x03 (as is done for EFI ROMs). This would not
constrain the .mrom payload size, but a payload size which happened to
be exactly 128kB would result in a zero value in the byte at offset
0x02 and so could still result in infinite loops on BIOSes with this
bug.
We choose to place a fixed value of 0x01 in the byte at offset 0x02.
This should at least prevent the BIOS from getting stuck in an
infinite loop. (The BIOS may walk into the middle of the .mrom
payload, where it will almost certainly not find a valid {0x55,0xaa}
signature or a valid PCIR header, and will therefore hopefully abort
processing.)
Reported-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We currently shrink the TCP window permanently if we are ever forced
(by a low-memory condition) to discard a previously received TCP
packet. This behaviour was intended to reduce the number of
retransmissions in a lossy network, since lost packets might
potentially result in the entire window contents being retransmitted.
Since commit e0fc8fe ("[tcp] Implement support for TCP Selective
Acknowledgements (SACK)") the cost of lost packets has been reduced by
around one order of magnitude, and the reduction in the window size
(which affects the maximum throughput) is now the more significant
cost.
Remove the code which reduces the TCP maximum window size when a
received packet is discarded.
Reported-by: Wissam Shoukair <wissams@mellanox.com>
Tested-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some HP BIOSes (observed with an HP ProLiant m710p Server Cartridge)
have a bug in the implementation of INT 1a,b101: they blithely assume
that real-mode code is able to read from anywhere in the 32-bit memory
space.
This problem affects the call to INT 1a,b101 made from within
pcibios_num_bus() (which uses REAL_CODE() and hence executes in
genuine real mode) but does not affect the call made from within
romprefix.S (since with a PMM BIOS, that call executes in flat real
mode anyway).
Work around the problem by explicitly calling flatten_real_mode()
before invoking INT 1a,b101. This is a rarely-used code path, and so
the extra overhead of emulating instructions in some VM configurations
(see commit 6d4deee ("[librm] Use genuine real mode to accelerate
operation in virtual machines") for more details) is negligible.
Reported-by: Wissam Shoukair <wissams@mellanox.com>
Debugged-by: Wissam Shoukair <wissams@mellanox.com>
Debugged-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some Intel Skylake platforms (observed on a prototype Lenovo ThinkPad)
report the list of available USB3 protocol speed ID values as {1,2,3}
but then report a port's speed using ID value 4.
The value 4 happens to be the default value for SuperSpeed (when no
protocol speed ID value list is explicitly defined), and the hardware
seems to function correctly if we simply ignore its protocol speed ID
table and assume that it uses the default values.
Fix by adding a "broken PSI values" quirk for this controller.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
gcc 4.8.2 fails to report this erroneous comparison unless assertions
are enabled.
Reported-by: Mary-Ann Johnson <MaryAnn.Johnson@displaylink.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit dc19e63 ("[build] Construct all-drivers list based on driver
class") accidentally excluded the USB bus drivers from the list of
files parsed in order to create PCI 3.0 device ID lists.
Fix by returning $(DRIVERS) to its previous definition as a list of
all driver files, and use only $(DRIVERS_ipxe) to contain the
filtered list containing only those drivers which we want to include
in the "all-drivers" build.
Reported-by: Mary-Ann Johnson <MaryAnn.Johnson@displaylink.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The xHCI slot ID is one-based, not zero-based. Fix the length of the
xhci->slot[] array to account for this, and add assertions to check
that the hardware returns a valid slot ID in response to the Enable
Slot command.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Deferral of a packet for neighbour discovery is not really an error.
If we fail to discover a neighbour then the failure will eventually be
reported by the call to neighbour_destroy() when any outstanding I/O
buffers are discarded.
The current behaviour breaks PXE booting on FreeBSD, which seems to
treat the error return from PXENV_UDP_WRITE as a fatal error and so
never proceeds to poll PXENV_UDP_READ (and hence never allows iPXE to
receive the ARP reply and send the deferred UDP packet).
Change neighbour_tx() to return success when deferring a packet. This
fixes interoperability with FreeBSD and removes transient neighbour
cache misses from the "ifstat" error output, while leaving genuine
neighbour discovery failures visible via "ifstat" (once neighbour
discovery times out, or the interface is closed).
Debugged-by: Wissam Shoukair <wissams@mellanox.com>
Tested-by: Wissam Shoukair <wissams@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When jumbo frames are enabled, the Linux ixgbe physical function
driver will disable the virtual function's receive datapath by
default, and will enable it only if the virtual function negotiates
API version 1.1 (or higher) and explicitly selects an MTU.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Several popular public cloud providers do not provide any sensible
mechanism for obtaining debug output from an OS which is failing to
boot. For example, Amazon EC2 provides the "Get System Log" facility,
which occasionally deigns to report a random subset of the characters
emitted via the VM's serial port, but usually returns only a blank
screen. (Amazingly, this is still superior to the debugging
facilities provided by Azure.)
Work around these shortcomings by adding a console type which sends
output to a magically detected raw disk partition, and including such
a partition within any iPXE .usb-format image.
To use this facility:
- build an iPXE .usb image with CONSOLE_INT13 enabled
- boot the cloud VM from this image
- after the boot fails, attach the VM's boot disk to a second VM
- from this second VM, use "less -f -R /dev/sdb3" (or similar) to
view the iPXE output.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Virtual functions use a mailbox to communicate with the physical
function driver: this covers functionality such as obtaining the MAC
address.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Intel virtual function NICs almost work with the use of "legacy"
transmit and receive descriptors (which are backwards compatible right
back to the original Intel Gigabit NICs).
Unfortunately the "TX switching" feature (which allows for VM<->VM
traffic to be looped back within the NIC itself) does not work when a
legacy TX descriptor is used: the packet is instead sent onto the
wire.
Fix by allowing for the use of an "advanced" TX descriptor (containing
exactly the same information as is found in the "legacy" descriptor).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The recorded disconnections (in port->disconnected) will currently be
left uncleared if usb_attached() returns an error (e.g. because there
are no drivers for a particular USB device). This is incorrect
behaviour: the disconnection has been handled and the record should be
cleared until the next physical disconnection is detected (via the CSC
bit).
The problem is masked for EHCI, UHCI, and USB hubs, since these will
report a changed port (via usb_port_changed()) only when the
underlying hardware reports a change. xHCI will call
usb_port_changed() in response to any port status event, at which
point the stale value of port->disconnected will be erroneously acted
upon. This can lead to an endless loop of repeatedly enumerating the
same device when a driverless device is attached to an xHCI root hub
port.
Fix by unconditionally clearing port->disconnected in usb_hotplugged().
Reported-by: Robin Smidsrød <robin@smidsrod.no>
Tested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The action of registering a new hub can itself happen in only two
ways: either a new USB hub has been created (in which case we are
already inside a call to usb_hotplug()), or a new root hub has been
created.
In the former case, we do not need to issue a further call to
usb_hotplug(), since the hub's ports will all be marked as changed and
so will be handled after the return from register_usb_hub() anyway.
Calling usb_hotplug() within register_usb_hub() leads to a confusing
order of events, such as:
- root hub port 1 detects a change
- root hub port 2 detects a change
- usb_hotplug() is called
- root hub port 1 finds a USB hub
- usb_hotplug() is called
- this inner call to usb_hotplug() handles root hub port 2
Fix by calling usb_hotplug() only from usb_step() and from
register_usb_bus(). This avoids recursive calls to usb_hotplug() and
ensures that devices are enumerated in the order of detection.
Tested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When USB network card drivers are used, the BIOS' legacy USB
capability is necessarily disabled since there is no way to share the
host controller between the BIOS and iPXE. This currently results in
USB keyboards becoming non-functional in USB-enabled builds of iPXE.
Fix by adding basic support for USB keyboards, enabled by default in
iPXE builds which include USB support.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When an EHCI hotplug action results in the controller disowning the
port, it will result in a hotplug action on the corresponding UHCI or
OHCI controller. Allow such hotplug actions to be carried out as part
of the same call to usb_step() or usb_register_bus(), by maintaining a
single central list of changed ports.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The USB core will currently fail to detect disconnections if a new
device has attached by the time the port is examined in
usb_hotplug().
Fix by recording the fact that a disconnection has taken place
whenever the "connection status changed" (CSC) bit is observed to be
set. (Whether the change represents a disconnection or a
reconnection, it indicates that the port has experienced some time of
being disconnected.)
Note that the time at which a disconnection can be detected varies by
hub type. In particular: root hubs can observe the CSC bit when
polling, and so will record the disconnection before calling
usb_port_changed(), but USB hubs read the port status (and hence the
CSC bit) only during the call to hub_speed(), long after the call to
usb_port_changed().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Rename PCI_CLASS() (which constructs a struct pci_class_id) to
PCI_CLASS_ID(), and provide PCI_CLASS() as a macro which constructs
the 24-bit scalar value of a PCI class code.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The USB API currently assumes that host controllers will have
immediate data buffer space available in which to store the setup
packet. This is true for xHCI, partially true for EHCI (which happens
to have 12 bytes of padding in each transfer descriptor due to
alignment requirements), and not true at all for UHCI.
Include the setup packet within the I/O buffer passed to the host
controller's message() method, thereby eliminating the requirement for
host controllers to provide immediate data buffers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The "vram" setting returns the (Base64-encoded) contents of video RAM,
and can be used to capture a screenshot. For example: after running
memtest.0 and encountering an error, the output can be captured and
sent to a remote server for later diagnosis:
#!ipxe
chain -a http://server/memtest.0 && goto ok || goto bad
:bad
params
param errno ${errno}
param vram ${vram}
chain -a http://server/report.php##params
:ok
Inspired-by: Christian Nilsson <nikize@gmail.com>
Originally-implemented-by: Christian Nilsson <nikize@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The current API for Base16 (and Base64) encoding requires the caller
to always provide sufficient buffer space. This prevents the use of
the generic encoding/decoding functionality in some situations, such
as in formatting the hex setting types.
Implement a generic hex_encode() (based on the existing
format_hex_setting()), implement base16_encode() and base16_decode()
in terms of the more generic hex_encode() and hex_decode(), and update
all callers to provide the additional buffer length parameter.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The settings self-tests include tests for the "ipv6" setting type.
When IPv6 support is not included, this setting type exists (since it
is referred to by some dual-stack code, such as dns.c) but is
non-functional.
Force IPv6 support to be included within a settings self-test build
using an explicit REQUIRE_OBJECT() macro.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This changed in Linux kernel the same way in commit 7067e701
("ath9k_hw: remove confusing logic inversion in an ANI variable") by
Felix Fietkau.
Additionally this fixes "error: logical not is only applied to the
left hand side of comparison" with GCC 5.1.0.
Signed-off-by: Christian Hesse <mail@eworm.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This fixes "initialization discards 'const' qualifier from pointer
target type" warnings with GCC 5.1.0.
Signed-off-by: Christian Hesse <mail@eworm.de>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
I218-LM (rev 3) is found in Lenovo Thinkpad X250. The remaining
device IDs are from linux/drivers/net/ethernet/intel/e1000e/hw.h
Signed-off-by: Christian Hesse <mail@eworm.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The USB bus drivers (ehci.c and xhci.c) have PCI device ID tables and
hence PCI_ROM() lines, but should probably not be included in the
all-drivers build on this basis, since they do nothing useful unless a
USB network driver is also present.
Fix by constructing the all-drivers list based on the driver class
(i.e. the portion of the source path immediately after "drivers/").
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On some RTL8169 onboard NICs (observed with a Lenovo ThinkPad 11e),
the EEPROM is not merely not present: any attempt to read from the
non-existent EEPROM will crash and reboot the system.
The equivalent code to read from the EEPROM was removed from the Linux
r8169 driver in 2009 with a comment suggesting that it was similarly
found to be unreliable on some systems.
Fix by accessing the EEPROM only on RTL8139 NICs, and assuming that
the MAC address will always be correctly preset on RTL8169 NICs.
Reported-by: Evan Prohaska <eprohaska@edkey.org>
Tested-by: Evan Prohaska <eprohaska@edkey.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The emulated Intel 82545em in some versions of VMware (observed with
ESXi v5.1) seems to sometimes fail to set the RXT0 bit in the
interrupt cause register (ICR), causing iPXE to stop receiving
packets. Work around this problem (for the 82545em only) by always
polling the receive queue regardless of the state of the ICR.
Reported-by: Slava Bendersky <volga629@networklab.ca>
Tested-by: Slava Bendersky <volga629@networklab.ca>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The assembler on OpenBSD 5.7 seems not to correctly handle the
combinations of .struct and .previous used in unlzma.S, and ends up
complaining about an "attempt to allocate data in absolute section".
Work around this problem by explicitly resetting the section after the
data structure definitions.
Reported-by: Jiri B <jirib@devio.us>
Tested-by: Jiri B <jirib@devio.us>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
PCI v3.0 supports a "device list" which allows the ROM to claim
support for multiple PCI device IDs (but only a single vendor ID).
Add support for building such ROMs by scanning the build target
element list and incorporating any device IDs into the ROM's device
list header. For example:
make bin/8086153a--8086153b.mrom
would build a ROM claiming support for both 8086:153a and 8086:153b.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Entropy gathering via timer ticks is slow under UEFI (of the order of
20-30 seconds on some machines). Use the EFI_RNG_PROTOCOL if
available, to speed up the process of entropy gathering.
Note that some implementations (including EDK2) will fail if we
request fewer than 32 random bytes at a time, and that the RNG
protocol provides no guarantees about the amount of entropy provided
by a call to GetRNG(). We take the (hopefully pessimistic) view that
a 32-byte block returned by GetRNG() will contain at least the 1.3
bits of entropy claimed by min_entropy_per_sample().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
At least one NII implementation (in a Microsoft Surface tablet) seems
to fail to report the absence (sic) of TX completions properly. Work
around this by checking for TX completions only when we expect to see
one.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some NII implementations will fail the GET_STATUS operation if we
request the media status. Fix by doing so only if GET_INIT_INFO
reported that media status is supported.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Our current behaviour when booting as a ROM is to autoboot only from
devices which are attached via the PCI bus:dev.fn address passed to
the ROM's initialisation vector.
Add a build configuration option AUTOBOOT_ROM_FILTER (enabled by
default) to control this behaviour. This allows for ROMs to be built
which will attempt to boot from any detected device, even if not
attached via the original PCI bus:dev.fn address. (This is
particularly useful when building combined EHCI/xHCI ROMs for USB
network boot, since the BIOS may request a boot via the EHCI
controller but the xHCI driver will reroute the root hub ports to the
xHCI controller.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
In theory USB3 ports do not require a reset to enable the port.
Experimentation shows that this is sometimes required, particularly
when rerouting ports from EHCI to xHCI and switching speeds.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Running util/parserom.pl on all source files (637) one by one takes
approximately 35 seconds because of the startup cost of each invocation.
With the utility rewritten to support multiple source files it now takes
approximately 1 second to scan all source files for ROM declarations.
The --exclude-driver and --exclude-driver-class options have been added,
making it possible to skip certain source files from being scanned at all.
In addition --debug option has been added to more easily trace progress.
Finally --help option was added to show usage information.
Signed-off-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We hook the UEFI ExitBootServices() event and use it to trigger a call
to shutdown_boot(). This does not automatically cause drivers to be
disconnected from their devices, since device enumeration is now
handled by the UEFI core rather than by iPXE. (Under the old and
dubiously compatible device model, iPXE used to perform its own device
enumeration and so the call to shutdown_boot() would indeed have
caused drivers to be disconnected.)
Fix by replicating parts of the dummy "EFI root device" from
efiprefix.c to efidrvprefix.c, so that the call to shutdown_boot()
will call efi_driver_disconnect_all().
Originally-fixed-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
SHA-512/224 is almost identical to SHA-512, with differing initial
hash values and a truncated output length.
This implementation has been verified using the NIST SHA-512/224 test
vectors.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
SHA-512/256 is almost identical to SHA-512, with differing initial
hash values and a truncated output length.
This implementation has been verified using the NIST SHA-512/256 test
vectors.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
SHA-384 is almost identical to SHA-512, with differing initial hash
values and a truncated output length.
This implementation has been verified using the NIST SHA-384 test
vectors.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
SHA-224 is almost identical to SHA-256, with differing initial hash
values and a truncated output length.
This implementation has been verified using the NIST SHA-224 test
vectors.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Update the digest self-tests to use okx(), and centralise concepts and
data shared between tests for multiple algorithms to reduce duplicated
code.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
None of the x86_64 builds currently have any way of invoking these
functions. They are included only to avoid introducing unnecessary
architecture-specific dependencies into the self-test suite.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 8ab4b00 ("[libc] Rewrite setjmp() and longjmp()") introduced a
regression in which the saved values of %ebx, %esi, and %edi were all
accidentally restored into %esp. The result is that the second and
subsequent returns from setjmp() would effectively corrupt %ebx, %esi,
%edi, and the stack pointer %esp.
Use of setjmp() and longjmp() is generally discouraged: our only use
occurs as part of the implementation of PXENV_RESTART_TFTP, since the
PXE API effectively mandates its use here. The call to setjmp()
occurs at the start of pxe_start_nbp(), where there are almost
certainly no values held in %ebx, %esi, or %edi. The corruption of
these registers therefore had no visible effect on program execution.
The corruption of %esp would have been visible on return from
pxe_start_nbp(), but there are no known PXE NBPs which first call
PXENV_RESTART_TFTP and subsequently attempt to return to the PXE base
code. The effect on program execution was therefore similar to that
of moving the stack to a pseudo-random location in the 32-bit address
space; this will often allow execution to complete successfully since
there is a high chance that the pseudo-random location will be unused.
The regression therefore went undetected for around one month.
Fix by restoring the correct registers from the saved jmp_buf
structure.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
xHCI provides a somewhat convoluted mechanism for specifying details
of a transaction translator. Hubs must be marked as such in the
device slot context. The only opportunity to do so is as part of a
Configure Endpoint command, which can be executed only when opening
the hub's interrupt endpoint.
We add a mechanism for host controllers to intercept the opening of
hub devices, providing xHCI with an opportunity to update the internal
device slot structure for the corresponding USB device to indicate
that the device is a hub. We then include the hub-specific details in
the input context whenever any Configure Endpoint command is issued.
When a device is opened, we record the device slot and port for its
transaction translator (if any), and supply these as part of the
Address Device command.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Support low-speed and full-speed devices attached to a USB2 hub. Such
devices use a transaction translator (TT) within the USB2 hub, which
asynchronously initiates transactions on the lower-speed bus and
returns the result via a split completion on the high-speed bus.
We make the simplifying assumption that there will never be more than
sixteen active interrupt endpoints behind a single transaction
translator; this assumption allows us to schedule all periodic start
splits in microframe 0 and all periodic split completions in
microframes 2 and 3. (We do not handle isochronous endpoints.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The current endpoint reset logic defers the reset until the caller
attempts to enqueue a new transfer to that endpoint. This is
insufficient when dealing with endpoints behind a transaction
translator, since the transaction translator is a resource shared
between multiple endpoints.
We cannot reset the endpoint as part of the completion handling, since
that would introduce recursive calls to usb_poll(). Instead, we
add the endpoint to a list of halted endpoints, and perform the reset
on the next call to usb_step().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The endpoint may already have enqueued TRBs at the time that
xhci_endpoint_reset() is called. Ring the doorbell to resume
processing these TRBs immediately, rather than waiting until the next
call to xhci_endpoint_message() or xhci_endpoint_stream().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Several of the USB timeouts were chosen on the principle of "pick an
arbitrary but ridiculously large value, just to be safe". It turns
out that some of the timeouts permitted by the USB specification are
even larger: for example, control transactions are allowed to take up
to five seconds to complete.
Fix up these USB timeout values to match those found in the USB2
specification.
Debugged-by: Robin Smidsrød <robin@smidsrod.no>
Tested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
xHCI (and EHCI) nominally provide a mechanism for releasing ownership
of the host controller back to the BIOS, which can then potentially
restore legacy USB keyboard functionality.
This is a rarely used code path, since most operating systems claim
ownership and never attempt to later return to the BIOS. On some
systems (observed with a Lenovo X1 Carbon), this code path leads to
obscure and interesting bugs: if the xHCI and EHCI controllers are
both claimed and later released back to the BIOS, then a subsequent
call to INT 16,0305 to set the keyboard repeat rate to a non-default
value will lock the system.
Obscure though this sequence of operations may sound, it is exactly
what happens when using iPXE to boot a Linux kernel via a USB network
card. There is old and probably unwanted code in Linux's
arch/x86/boot/main.c which sets the keyboard repeat rate (with the
accompanying comment "Set keyboard repeat rate (why?)"). When booting
Linux via a USB network card on a Lenovo X1 Carbon, the system
therefore locks up immediately after jumping to the kernel's entry
point.
Work around this problem by preventing the release of ownership back
to the BIOS if it is known that we are shutting down to boot an OS.
This should allow legacy USB keyboard functionality to be restored if
the user chooses to exit iPXE, while avoiding the rarely used code
paths (and corresponding BIOS bugs) if the user chooses instead to
boot an OS.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When using iPXE as an option ROM for a PCI USB controller (e.g. via
qemu's "-device nec-usb-xhci,romfile=..." syntax), the ROM prefix will
set the PCI bus:dev.fn address of the USB controller as the PCI
autoboot device. This will cause iPXE to fail to boot from any
detected USB network devices, since they will not match the autoboot
bus type (or location).
Fix by allowing the autoboot bus type and location to match against
the network device or any of its parent devices. This allows the
match to succeed for USB network devices attached to the selected PCI
USB controller.
Reported-by: Dan Ellis <Dan.Ellis@displaylink.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
If the BIOS fails to gracefully release ownership of the xHCI
controller, we can forcibly claim it by disabling all SMIs via the
USB legacy support control/status register.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
RX FIFO overflow is almost inevitable since the (usable) USB2 bus
bandwidth is approximately one quarter of the Ethernet bandwidth.
Avoid flooding the console with RX FIFO overflow messages in a
standard debug build.
With TCP SACK implemented, the RX FIFO overflow no longer causes a
catastrophic drop in throughput. Experimentation shows that HTTP
downloads now progress at a fairly smooth 250Mbps, which is around the
maximum speed attainable for a USB2 NIC.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The TCP Selective Acknowledgement option (specified in RFC2018)
provides a mechanism for the receiver to indicate packets that have
been received out of order (e.g. due to earlier dropped packets).
iPXE often operates in environments in which there is a high
probability of packet loss. For example, the legacy USB keyboard
emulation in some BIOSes involves polling the USB bus from within a
system management interrupt: this introduces an invisible delay of
around 500us which is long enough for around 40 full-length packets to
be dropped. Similarly, almost all 1Gbps USB2 devices will eventually
end up dropping packets because the USB2 bus does not provide enough
bandwidth to sustain a 1Gbps stream, and most devices will not provide
enough internal buffering to hold a full TCP window's worth of
received packets.
Add support for sending TCP Selective Acknowledgements. This provides
the sender with more detailed information about which packets have
been lost, and so allows for a more efficient retransmission strategy.
We include a SACK-permitted option in our SYN packet, since
experimentation shows that at least Linux peers will not include a
SACK-permitted option in the SYN-ACK packet if one was not present in
the initial SYN. (RFC2018 does not seem to mandate this behaviour,
but it is consistent with the approach taken in RFC1323.) We ignore
any received SACK options; this is safe to do since SACK is only ever
advisory and we never have to send non-trivial amounts of data.
Since our TCP receive queue is a candidate for cache discarding under
low memory conditions, we may end up discarding data that has been
reported as received via a SACK option. This is permitted by RFC2018.
We follow the stricture that SACK blocks must not report data which is
no longer held by the receiver: previously-reported blocks are
validated against the current receive queue before being included
within the current SACK block list.
Experiments in a qemu VM using forced packet drops (by setting
NETDEV_DISCARD_RATE to 32) show that implementing SACK improves
throughput by around 400%.
Experiments with a USB2 NIC (an SMSC7500) show that implementing SACK
improves throughput by around 700%, increasing the download rate from
35Mbps up to 250Mbps (which is approximately the usable bandwidth
limit for USB2).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Several of the assembly files in arch/i386/prefix were missed by the
automated relicensing tool due to missing licence declarations, code
dating back to the initial git revision, etc. Manual review shows
that these files may be relicensed.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This driver is functional but any downloads via a TCP-based protocol
tend to perform poorly. The 1Gbps Ethernet line rate is substantially
higher than the 480Mbps (in practice around 280Mbps) provided by USB2,
and the device has only 32kB of internal buffer memory. Our 256kB TCP
receive window therefore rapidly overflows the RX FIFO, leading to
multiple dropped packets (usually within the same TCP window) and
hence a low overall throughput.
Reducing the TCP window size so that the RX FIFO does not overflow
greatly increases throughput, but is not a general-purpose solution.
Further investigation is required to determine how other OSes
(e.g. Linux) cope with this scenario. It is possible that
implementing TCP SACK would provide some benefit.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Most devices expose at least the link up/down status via a bit in a
MAC register, since the MAC generally already needs to know whether or
not the link is up. Some devices (e.g. the SMSC75xx USB NIC) expose
this information to software only via the MII registers.
Provide a generic mii_check_link() implementation to check the BMSR
and report the link status via netdev_link_{up,down}().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Microsoft IIS supports only MD5-sess for Digest authentication.
Requested-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE already sends RX notifications to the backend when needed, but
does not set the "feature-rx-notify" flag. As of XenServer 6.5, this
flag is mandatory and omitting it will cause the backend to fail.
Fix by setting the "feature-rx-notify" flag, to inform the backend
that we will send notifications.
Reported-by: Shalom Bhooshi <shalom.bhooshi@citrix.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Restore the original values of XUSB2PR and USB3PSSEN, in case we are
booting an OS with no support for xHCI.
Suggested-by: Dan Ellis <Dan.Ellis@displaylink.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Intel PCH controllers default to routing USB2 ports to EHCI rather
than xHCI, and default to disabling SuperSpeed connections.
Manipulate the PCI configuration space registers as necessary to
reroute ports and enable SuperSpeed.
Originally-fixed-by: Dan Ellis <Dan.Ellis@displaylink.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Relicense files with kind permission from
Stefan Hajnoczi <stefanha@redhat.com>
alongside the contributors who have already granted such relicensing
permission.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Rewrite (and relicense) the header files which are included in all
builds of iPXE (including non-Linux builds).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
At some point in the past few years, binutils became more aggressive
at removing unused symbols. To function as a symbol requirement, a
relocation record must now be in a section marked with @progbits and
must not be in a section which gets discarded during the link (either
via --gc-sections or via /DISCARD/).
Update REQUIRE_SYMBOL() to generate relocation records meeting these
criteria. To minimise the impact upon the final binary size, we use
existing symbols (specified via the REQUIRING_SYMBOL() macro) as the
relocation targets where possible. We use R_386_NONE or R_X86_64_NONE
relocation types to prevent any actual unwanted relocation taking
place. Where no suitable symbol exists for REQUIRING_SYMBOL() (such
as in config.c), the macro PROVIDE_REQUIRING_SYMBOL() can be used to
generate a one-byte-long symbol to act as the relocation target.
If there are versions of binutils for which this approach fails, then
the fallback will probably involve killing off REQUEST_SYMBOL(),
redefining REQUIRE_SYMBOL() to use the current definition of
REQUEST_SYMBOL(), and postprocessing the linked ELF file with
something along the lines of "nm -u | wc -l" to check that there are
no undefined symbols remaining.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The valgrind headers are not x86-specific; they detect the CPU
architecture and contain inline assembly for multiple architectures.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Unregistering a child settings block can have almost arbitrary
effects, due to the call to apply_settings(). Avoid potentially
dereferencing a stale pointer by using list_first_entry() rather than
list_for_each_entry_safe() to iterate over the list of child settings.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The code in list.h was originally taken from the Linux kernel many
years ago, but has been rewritten to the point that no original code
remains, and may therefore be relicensed.
The functions and data structures remain largely API-compatible, to
facilitate the conversion of Linux network drivers to iPXE.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
These files cannot be automatically relicensed by util/relicense.pl
since they either contain unusual but trivial contributions (such as
the addition of __nonnull function attributes), or contain lines
dating back to the initial git revision (and so require manual
knowledge of the code's origin).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Relicence files with kind permission from the following contributors:
Alex Williamson <alex.williamson@redhat.com>
Eduardo Habkost <ehabkost@redhat.com>
Greg Jednaszewski <jednaszewski@gmail.com>
H. Peter Anvin <hpa@zytor.com>
Marin Hannache <git@mareo.fr>
Robin Smidsrød <robin@smidsrod.no>
Shao Miller <sha0.miller@gmail.com>
Thomas Horsten <thomas@horsten.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Relicense files authored by Dan Lynch while working as an employee of
Fen Systems Ltd., with permission from Fen Systems Ltd.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The UBDL relicensing tool (util/relicense.pl) is designed to identify
files which may be relicensed under a dual GPL+UBDL licence. It uses
git-blame to identify the author of each line (using the -M and -C
options to track lines moved or copied between files), and relicenses
files for which all authors have given permission.
The relicensing tool will ignore certain types of lines identified by
git-blame:
- empty lines
- comments
- standalone opening or closing braces
- "#include ..."
- "return 0;"
- "return rc;"
- "PCI_ROM(...)"
- "FILE_LICENCE(...)"
These lines either contain no meaningful content (e.g. empty lines),
contain only non-copyrightable facts (e.g. PCI ROM IDs) or are
sufficiently common within the codebase that git-blame is likely to
misattribute their origin (e.g. "return 0").
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add the text for the Unmodified Binary Distribution Licence. This
Licence allows for the distribution of unmodified binaries built from
publicly available source code, without imposing the obligations of
the GNU General Public License upon anyone who chooses to distribute
only the unmodified binaries built from that source code. See the
licence text for the precise terms and conditions.
Add the licence GPL2_OR_LATER_OR_UBDL to the set of licences which can
be declared using FILE_LICENCE(), and add the corresponding support to
licence.pl.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add the standard warranty disclaimer and Free Software Foundation
address paragraphs to the licence text where these are not currently
present.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The code in lzma_literal() checks to see if we are at the start of the
compressed input data in order to determine whether or not a most
recent output byte exists. This check is incorrect, since
initialisation of the decompressor will always consume the first five
bytes of the compressed input data.
Fix by instead checking whether or not we are at the start of the
output data stream. This is, in any case, a more logical check.
This issue was masked during development and testing since virtual
machines tend to zero the initial contents of RAM; the spuriously-read
"most recent output byte" is therefore likely to already be a zero
when running in a virtual machine.
Reported-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The 0xe9 debug port exists only on virtual machines. Provide an
option to print debug output on the BIOS console, to allow for
debugging on real hardware.
Note that this option can be used only if the decompressor is called
in flat real mode; the easiest way to achieve this is to build with
DEBUG=libprefix.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow the decompressor the option of generating debugging output via
the BIOS console by calling it in flat real mode (rather than 16-bit
protected mode) when libprefix.S is built with debugging enabled.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
LZMA performs an extra normalisation after decompression is complete,
which does not affect the output but may consume an extra byte from
the input (and so may affect which byte is identified as being the
start of the next block).
Reported-by: Robin Smidsrød <robin@smidsrod.no>
Tested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE uses DHCP timeouts loosely based on values recommended by the
specification, but often abbreviated to reduce timeouts for reliable
and/or simple network topologies. Extract the DHCP timing parameters
to config/dhcp.h and document them. The resulting default iPXE
behavior is exactly the same, but downstreams are now afforded the
opportunity to implement spec-compliant behavior via config file
overrides.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
LZMA provides significantly better compression (by ~15%) than the
current NRV2B algorithm.
We use a raw LZMA stream (aka LZMA1) to avoid the need for code to
parse the LZMA2 block headers. We use parameters {lc=2,lp=0,pb=0} to
reduce the stack space required by the decompressor to acceptable
levels (around 8kB). Using lc=3 or pb=2 would give marginally better
compression, but at the cost of substantially increasing the required
stack space.
The build process now requires the liblzma headers to be present on
the build system, since we do not include a copy of an LZMA compressor
within the iPXE source tree. The decompressor is written from scratch
(based on XZ Embedded) and is entirely self-contained within the
iPXE source.
The branch-call-jump (BCJ) filter used to improve the compressibility
is specific to iPXE. We choose not to use liblzma's built-in BCJ
filter since the algorithm is complex and undocumented. Our BCJ
filter achieves approximately the same results (on typical iPXE
binaries) with a substantially simpler algorithm.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some decompression algorithms (e.g. LZMA) require large amounts of
temporary stack space, which may not be made available by all
prefixes. Use .bss16 as a temporary stack for the duration of the
calls to install_block (switching back to the external stack before we
start making calls into code which might access variables in .bss16),
and allow the decompressor to define a global symbol to force a
minimum value on the size of .bss16.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Other hypervisors (e.g. KVM) may provide an unusable subset of the
Hyper-V features, and our attempts to use these non-existent features
cause the guest to reboot.
Fix by explicitly checking for the Hyper-V features that we use.
Reported-by: Ján ONDREJ (SAL) <ondrejj@salstar.sk>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The implementation of strtoul() has a partially unknown provenance.
Rewrite this code to avoid potential licensing uncertainty.
Since we now use -ffunction-sections, there is no need to place
strtoull() in a separate file from strtoul().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The implementation of inet_aton() has an unknown provenance. Rewrite
this code to avoid potential licensing uncertainty.
Also move the code from core/misc.c to its logical home in net/ipv4.c,
and add a few extra test cases.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When a command times out, abort it (via the Command Abort bit in the
Command Ring Control Register) so that subsequent commands may execute
as expected.
This improves robustness when a device fails to respond to the Set
Address command, since the subsequent Disable Slot command will now
succeed.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
If the Disable Slot command fails then the hardware may continue to
write to the slot context. Leak the memory used by the slot context
to avoid future memory corruption.
This situation has been observed in practice when a Set Address
command fails, causing the command ring to become temporarily
unresponsive.
Note that there is no need to similarly leak memory on the failure
path in xhci_device_open(), since in the event of a failure the
hardware is never informed of the slot context address.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The 8254 timer code (used to implement udelay()) has an unknown
provenance. Rewrite this code to avoid potential licensing
uncertainty.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As with memcpy(), we can reduce the code size (by an average of 0.2%)
by giving the compiler more visibility into what memset() is doing,
and by avoiding the "rep" prefix on short fixed-length sequences of
string operations.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some of the C library string functions have an unknown provenance.
Reimplement all such functions to avoid potential licensing
uncertainty.
Remove the inline-assembler versions of strlen(), memswap(), and
strncmp(); these save a minimal amount of space (around 40 bytes in
total) and are not performance-critical.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide a generic framework for allocating, refilling, and optionally
recycling I/O buffers used by bulk IN and interrupt endpoints.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Hardened versions of gcc default to building position-independent
code, which breaks our i386 build. Our build process therefore
detects such platforms and automatically adds "-fno-PIE -nopie" to the
gcc command line.
On x86_64, we choose to build position-independent code (in order to
reduce the final binary size and, in particular, the number of
relocations required for UEFI binaries). The workaround therefore
breaks the build process for x86_64 binaries on such platforms.
Fix by moving the workaround to the i386-specific portion of the
Makefile.
Reported-by: Jan Kundrát <jkt@kde.org>
Debugged-by: Jan Kundrát <jkt@kde.org>
Debugged-by: Marin Hannache <git@mareo.fr>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
UEFI binaries may be relocated to any location within the 64-bit
address space. We compile as position-independent code with hidden
visibility, which should force all relocation records to be either
PC-relative (in which case no PE relocations are required) or full
64-bit relocations. There should be no R_X86_64_32 relocation
records, since that would imply an invalid assumption that code could
not be relocated above 4GB.
Remove support for R_X86_64_32 relocation records from util/elf2efi.c,
so that any such records result in a build failure rather than a
potential runtime failure.
Reported-by: Jan Kundrát <jkt@kde.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When building hvmloader for Xen tools the iPXE objects are also linked
into the binary. Unfortunately the linker will place them in the
order found in the archive. Since this order is random the resulting
hvmloader binary differs when it was built from identical sources but
on different build hosts. To help with creating a reproducible binary
the elements in blib.a must simply be sorted before passing them to
$(AR).
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit a60f2dd ("[usb] Try multiple USB device configurations")
changed the behaviour of register_usb() such that if no drivers are
found then the device will be closed and the memory used will be
freed.
If a port status change subsequently occurs while the device is still
physically attached, then usb_hotplug() will see this as a new device
having been attached, since there is no device recorded as being
currently attached to the port. This can lead to spurious hotplug
events (or even endless loops of hotplug events, if the process of
opening and closing the device happens to generate a port status
change).
Fix by using a separate flag to indicate that a device is physically
attached (even if we have no corresponding struct usb_device).
Reported-by: Dan Ellis <Dan.Ellis@displaylink.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>