The drive specification alone does not necessarily contain enough
information to perform a SAN boot (or local disk boot) under UEFI. If
the next-stage bootloader is installed in the EFI system partition
under a non-standard name (e.g. "\EFI\debian\grubx64.efi") then this
explicit boot filename must also be specified.
Generalise this concept to use a "SAN boot configuration parameters"
structure (currently containing only the optional explicit boot
filename), to allow for easy expansion to provide other parameters
such as the partition UUID or volume label.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We currently use the SAN device pointer as the debug message stream
identifier. This pointer is not always available: for example, when
booting from a local disk there is no underlying SAN device.
Switch to using the drive number as the debug message colour stream
identifier, so that all block device debug messages may be colourised
consistently.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Newer versions of the GNU assembler (observed with binutils 2.41) will
complain about the ".arch i386" in files assembled with "as --64",
with the message "Error: 64bit mode not supported on 'i386'".
In files such as stack.S that contain no instructions to be assembled,
the ".arch i386" is redundant and may be removed entirely.
In the remaining files, fix by moving ".arch i386" below the relevant
".code16" or ".code32" directive, so that the assembler is no longer
expecting 64-bit instructions to be used by the time that the ".arch
i386" directive is encountered.
Reported-by: Ali Mustakim <alim@forwardcomputers.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The .text directive is entirely redundant when followed by a .section
directive giving an explicit section name and attributes.
Remove these unnecessary directives to simplify the code.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Support scanning for the 64-bit SMBIOS3 entry point in addition to the
32-bit SMBIOS2 entry point.
Prefer use of the 32-bit entry point if present, since this is
guaranteed to be within accessible memory.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The PCI cloud API (PCIAPI_CLOUD) currently selects the first PCI API
that successfully discovers a PCI device address range. The ECAM API
may discover an address range but subsequently be unable to map the
configuration space region, which would result in the selected PCI API
being unusable.
Fix by instead selecting the first PCI API that can be successfully
used to discover a PCI device.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The special key range (from KEY_MIN upwards) currently overlaps with
the valid range for Unicode characters, and therefore prohibits the
use of Unicode key values outside the ASCII range.
Create space for Unicode key values by moving the special keys to the
range immediately above the maximum valid Unicode character. This
allows the existing encoding of special keys as an efficiently packed
representation of the equivalent ANSI escape sequence to be maintained
almost as-is.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As noted in commit 3c83843 ("[rng] Check for several functioning RTC
interrupts"), experimentation shows that Hyper-V cannot be trusted to
reliably generate RTC interrupts. (As noted in commit f3ba0fb
("[hyperv] Provide timer based on the 10MHz time reference count
MSR"), Hyper-V appears to suffer from a general problem in reliably
generating any legacy interrupts.) An alternative entropy source is
therefore required for an image that may be used in a Hyper-V Gen1
virtual machine.
The x86 RDRAND instruction provides a suitable alternative entropy
source, but may not be supported by all CPUs. We must therefore allow
for multiple entropy sources to be compiled in, with the single active
entropy source selected only at runtime.
Restructure the internal entropy API to allow a working entropy source
to be detected and chosen at runtime.
Enable the RDRAND entropy source for all x86 builds, since it is
likely to be substantially faster than any other source.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 74222cd ("[rng] Check for functioning RTC interrupt") added a
check that the RTC is capable of generating interrupts via the legacy
PIC, since this mechanism appears to be broken in some Hyper-V virtual
machines.
Experimentation shows that the RTC is sometimes capable of generating
a single interrupt, but will then generate no subsequent interrupts.
This currently causes rtc_entropy_check() to falsely detect that the
entropy gathering mechanism is functional.
Fix by checking for several RTC interrupts before declaring that it is
a functional entropy source.
Reported-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When chainloading iPXE from a VLAN device, the MAC address within the
cached DHCPACK will match the MAC address of the trunk device created
by iPXE, and the cached DHCPACK will then end up being erroneously
applied to the trunk device. This tends to break outbound IPv4
routing, since both the trunk and VLAN devices will have the same
assigned IPv4 address.
Fix by recording the VLAN tag along with the cached DHCPACK, and
treating the VLAN tag as part of the filter used to match the cached
DHCPACK against candidate network devices.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Pretty much all physical machines and off-the-shelf virtual machines
will provide a functional PCI BIOS. We therefore default to using
only the PCI BIOS, with no fallback to an alternative mechanism if the
PCI BIOS fails.
AWS EC2 provides the opportunity to experience some exceptions to this
rule. For example, the t3a.nano instances in eu-west-1 have no
functional PCI BIOS at all. As of commit 83516ba ("[cloud] Use
PCIAPI_DIRECT for cloud images") we therefore use direct Type 1
configuration space accesses in the images built and published for use
in the cloud.
Recent experience has discovered yet more variation in AWS EC2
instances. For example, some of the metal instance types have
multiple PCI host bridges and the direct Type 1 accesses therefore
see only a subset of the PCI devices.
Attempt to accommodate future such variations by making the PCI I/O
API selectable at runtime and choosing ECAM (if available), falling
back to the PCI BIOS (if available), then finally falling back to
direct Type 1 accesses.
This is implemented as a dedicated PCIAPI_CLOUD API, rather than by
having the PCI core select a suitable API at runtime (as was done for
timers in commit 302f1ee ("[time] Allow timer to be selected at
runtime"). The common case will remain that only the PCI BIOS API is
required, and we would prefer to retain the optimisations that come
from inlining the configuration space accesses in this common case.
Cloud images are (at present) disk images rather than ROM images, and
so the increased code size required for this design approach in the
PCIAPI_CLOUD case is acceptable.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow pcibios_discover() to return an empty range if the INT 1A,B101
PCI BIOS installation check call fails.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow pci_find_next() to discover devices beyond the first PCI
segment, by generalising pci_num_bus() (which implicitly assumes that
there is only a single PCI segment) with pci_discover() (which has the
ability to return an arbitrary contiguous chunk of PCI bus:dev.fn
address space).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow for linked-in code to override the mechanism used to locate an
ACPI table, thereby opening up the possibility of ACPI self-tests.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Accumulate UTF-8 characters in fbcon_putchar(), and require the frame
buffer console's .glyph() method to accept Unicode character values.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Several keyboard layouts define ASCII characters as accessible only
via the AltGr modifier. Add support for this modifier to ensure that
all ASCII characters are accessible.
Experiments suggest that the BIOS console is likely to fail to
generate ASCII characters when the AltGr key is pressed. Work around
this limitation by accepting LShift+RShift (which will definitely
produce an ASCII character) as a synonym for AltGr.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Handle Ctrl and CapsLock key modifiers within key_remap(), to provide
consistent behaviour across different console types.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The key with scancode 86 appears in the position between left shift
and Z on a US keyboard, where it typically fails to exist entirely.
Most US keyboard maps define this nonexistent key as generating "\|",
with the notable exception of "loadkeys" which instead reports it as
generating "<>". Both of these mapping choices duplicate keys that
exist elsewhere in the map, which causes problems for our ASCII-based
remapping mechanism.
Work around these quirks by treating the key as generating "\|" with
the high bit set, and making it subject to remapping. Where the BIOS
generates "\|" as expected, this allows us to remap to the correct
ASCII value.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
To minimise code size, our keyboard mapping works on the basis of
allowing the BIOS to convert the keyboard scancode into an ASCII
character and then remapping the ASCII character.
This causes problems with keyboard layouts such as "fr" that swap the
shifted and unshifted digit keys, since the ASCII-based remapping will
spuriously remap the numeric keypad (which produces the same ASCII
values as the digit keys).
Fix by checking that the keyboard scancode is within the range of keys
that vary between keyboard mappings before attempting to remap the
ASCII character.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow for the DSDT/SSDT signature-scanning and value extraction code
to be reused for extracting a pass-through MAC address.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit cd3de55 ("[efi] Record cached DHCPACK from loaded image's
device handle, if present") added the ability for a chainloaded UEFI
iPXE to reuse an IPv4 address and DHCP options previously obtained by
a built-in PXE stack, without needing to perform a second DHCP
request.
Extend this to also record the cached ProxyDHCPOFFER and PXEBSACK
obtained from the EFI_PXE_BASE_CODE_PROTOCOL instance installed on the
loaded image's device handle, if present.
This allows a chainloaded UEFI iPXE to reuse a boot filename or other
options that were provided via a ProxyDHCP or PXE boot server
mechanism, rather than by standard DHCP.
Tested-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The INT 13 extensions provide a mechanism for accessing disks using
linear (LBA) rather than C/H/S addressing. SAN protocols such as
iSCSI invariably support only linear addresses and so iPXE currently
provides LBA access to all SAN disks (with autodetection and emulation
of an appropriate geometry for C/H/S accesses).
Most BIOSes will not report support for INT 13 extensions for floppy
disk drives, and some operating systems may be confused by a floppy
drive that claims such support.
Minimise surprise by reporting the existence of support for INT 13
extensions only for non-floppy drive numbers. Continue to provide
support for all drive numbers, to avoid breaking operating systems
that may unconditionally use the INT 13 extensions without first
checking for support.
Reported-by: Valdo Toost <vtoost@hot.ee>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The "used" attribute can be applied only to functions or variables,
which prevents the use of __asmcall as a type attribute.
Fix by removing "used" from the definition of __asmcall for i386 and
x86_64 architectures, and adding explicit __used annotations where
necessary.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The ACPI API currently expects platforms to provide access to a single
contiguous ACPI table. Some platforms (e.g. Linux userspace) do not
provide a convenient way to obtain the entire ACPI table, but do
provide access to individual tables.
All iPXE consumers of the ACPI API require access only to individual
tables.
Redefine the internal API to make acpi_find() an API method, with all
existing implementations delegating to the current RSDT-based
implementation.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Split out the portions of cachedhcp.c that can be shared between BIOS
and UEFI (both of which can provide a buffer containing a previously
obtained DHCP packet, and neither of which provide a means to
determine the length of this DHCP packet).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The semantics of the assembler's .align directive vary by CPU
architecture. For the ARM builds, it specifies a power of two rather
than a number of bytes. This currently leads to the .einfo entries
(which do not appear in the final binary) having an alignment of 256
bytes for the ARM builds.
Fix by switching to the GNU-specific directive .balign, which is
consistent across architectures
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Define pci_ioremap() as a wrapper around ioremap() that could allow
for a non-zero address translation offset.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This caused iPXE to reject images even when enough memory was
available.
Signed-off-by: David Decotigny <ddecotig@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 6149e0a ("[librm] Provide symbols for inline code placed into
other sections") may cause build failures due to duplicate label names
if the compiler chooses to duplicate inline assembly code.
Fix by using the "%=" special format string to include a
guaranteed-unique number within the label name.
The "%=" will be expanded only if constraints exist for the inline
assembly. This fix therefore requires that all REAL_CODE() fragments
use a (possibly empty) constraint list.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow the ACPI power management timer to be used if enabled via
TIMER_ACPI in config/timer.h. This provides an alternative timer on
systems where the standard 8254 PIT is unavailable or unreliable.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some older operating systems (e.g. RHEL6) use a non-default filename
on the root disk and rely on setting an EFI variable to point to the
bootloader. This does not work when performing a SAN boot on a
machine where the EFI variable is not present.
Fix by allowing a non-default filename to be specified via the
"sanboot --filename" option or the "san-filename" setting. For
example:
sanboot --filename \efi\redhat\grub.efi \
iscsi:192.168.0.1::::iqn.2010-04.org.ipxe.demo:rhel6
or
option ipxe.san-filename code 188 = string;
option ipxe.san-filename "\\efi\\redhat\\grub.efi";
option root-path "iscsi:192.168.0.1::::iqn.2010-04.org.ipxe.demo:rhel6";
Originally-implemented-by: Vishvananda Ishaya Abrams <vish.ishaya@oracle.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Describe all SAN devices via ACPI tables such as the iBFT. For tables
that can describe only a single device (i.e. the aBFT and sBFT), one
table is installed per device. For multi-device tables (i.e. the
iBFT), all devices are described in a single table.
An underlying SAN device connection may be closed at the time that we
need to construct an ACPI table. We therefore introduce the concept
of an "ACPI descriptor" which enables the SAN boot code to maintain an
opaque pointer to the underlying object, and an "ACPI model" which can
build tables from a list of such descriptors. This separates the
lifecycles of ACPI descriptions from the lifecycles of the block
device interfaces, and allows for construction of the ACPI tables even
if the block device interface has been closed.
For a multipath SAN device, iPXE will wait until sufficient
information is available to describe all devices but will not wait for
all paths to connect successfully. For example: with a multipath
iSCSI boot iPXE will wait until at least one path has become available
and name resolution has completed on all other paths. We do this
since the iBFT has to include IP addresses rather than DNS names. We
will commence booting without waiting for the inactive paths to either
become available or close; this avoids unnecessary boot delays.
Note that the Linux kernel will refuse to accept an iBFT with more
than two NIC or target structures. We therefore describe only the
NICs that are actually required in order to reach the described
targets. Any iBFT with at most two targets is therefore guaranteed to
describe at most two NICs.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The INT13 console type (CONSOLE_INT13) autodetects at initialisation
time a magic partition to be used for logging iPXE console output. If
the INT13 drive number mapping is subsequently changed (e.g. because
iPXE was used to perform a SAN boot), then the console logging output
will be written to the incorrect disk.
Fix by recording the INT13 vector at initialisation time, and using
this original vector to emulate INT13 calls for all subsequent
accesses. This should be robust against drive remapping performed
either by ourselves or by another bootloader (e.g. a chainloaded
undionly.kpxe which then performs a SAN boot).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some partition tables have partitions that are not aligned to a
cylinder boundary, which confuses the current geometry guessing logic.
Enhance the existing logic to ensure that we never reduce our guesses
for the number of heads or sectors per track, and add extra logic to
calculate the exact number of sectors per track if we find a partition
that starts within cylinder zero.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add basic support for multipath block devices. The "sanboot" and
"sanhook" commands now accept a list of SAN URIs. We open all URIs
concurrently. The first connection to become available for issuing
block device commands is marked as the active path and used for all
subsequent commands; all other connections are then closed. Whenever
the active path fails, we reopen all URIs and repeat the process.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The concept of the SAN drive number is meaningful only in a BIOS
environment, where it represents the INT13 drive number (0x80 for the
first hard disk). We retain this concept in a UEFI environment to
allow for a simple way for iPXE commands to refer to SAN drives.
Centralise the concept of the default drive number, since it is shared
between all supported environments.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
INT 13 calls return a status value via %ah, with CF set if %ah is
non-zero (indicating an error). Our wrappers zero the whole of %ax if
CF is clear, to allow C code (which has no easy access to CF) to
simply test for a non-zero status to detect an error.
The current code assigns the returned status to a uint8_t, effectively
testing %al rather than %ah. Fix by treating the returned status as a
uint16_t instead.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Avoid using a zero sector count to guess the disk geometry, since that
would result in a division by zero when calculating the number of
cylinders.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow the active timer (providing udelay() and currticks()) to be
selected at runtime based on probing during the INIT_EARLY stage of
initialisation.
TICKS_PER_SEC is now a fixed compile-time constant for all builds, and
is independent of the underlying clock tick rate. We choose the value
1024 to allow multiplications and divisions on seconds to be converted
to bit shifts.
TICKS_PER_MS is defined as 1, allowing multiplications and divisions
on milliseconds to be omitted entirely. The 2% inaccuracy in this
definition is negligible when using the standard BIOS timer (running
at around 18.2Hz).
TIMER_RDTSC now checks for a constant TSC before claiming to be a
usable timer. (This timer can be tested in KVM via the command-line
option "-cpu host,+invtsc".)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The ACPI power off sequence may not take effect immediately. Delay
for one second, to eliminate potentially confusing log messages such
as "Could not power off: Error 0x43902001 (http://ipx".
Reported-by: Leonid Vasetsky <leonidv@velostrata.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On some platforms (observed in a small subset of Microsoft Azure
(Hyper-V) virtual machines), the RTC appears to be incapable of
generating an interrupt via the legacy PIC. The RTC status registers
show that a periodic interrupt has been asserted, but the PIC IRR
shows that IRQ8 remains inactive.
On such systems, iPXE will currently freeze during the "iPXE
initialising devices..." message.
Work around this problem by checking that RTC interrupts are being
raised before returning from rtc_entropy_enable(). If no interrupt is
seen within 100ms, then we assume that the RTC interrupt mechanism is
broken. In these circumstances, iPXE will continue to initialise but
any subsequent attempt to generate entropy will fail. In particular,
HTTPS connections will fail with an error indicating that no entropy
is available.
Signed-off-by: Michael Brown <mcb30@ipxe.org>