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>
In real mode, code segments are always writable. In protected mode,
code segments can never be writable. The precise implementation of
this attribute differs between CPU generations, with subtly different
behaviour arising on the transitions from protected mode to real mode.
At the point of transition (when the PE bit is cleared in CR0) the
hidden portion of the %cs descriptor will retain whatever attributes
were in place for the protected-mode code segment, including the fact
that the segment is not writable. The immediately following code will
perform a far control flow transfer (such as ljmp or lret) in order to
load a real-mode value into %cs.
On the Pentium and later CPUs, the retained protected-mode attributes
will be ignored for any accesses via %cs while the CPU is in real
mode. A write via %cs will therefore be allowed even though the
hidden portion of the %cs descriptor still describes a non-writable
segment.
On the 486 and earlier CPUs, the retained protected-mode attributes
will not be ignored for accesses via %cs. A write via %cs will
therefore cause a CPU fault. To obtain normal real-mode behaviour
(i.e. a writable %cs descriptor), special logic is added to the ljmp
instruction that populates the hidden portion of the %cs descriptor
with real-mode attributes when a far jump is executed in real mode.
The result is that writes via %cs will cause a CPU fault until the
first ljmp instruction is executed, after which writes via %cs will be
allowed as expected in real mode.
The transition code in libprefix.S currently uses lret to load a
real-mode value into %cs after clearing the PE bit. Experimentation
shows that only the ljmp instruction will work to load real-mode
attributes into the hidden portion of the %cs descriptor: other far
control flow transfers (such as lret, lcall, or int) do not do so.
When running on a 486 or earlier CPU, this results in code within
libprefix.S running with a non-writable code segment after a mode
transition, which in turn results in a CPU fault when real-mode code
in liba20.S attempts to write to %cs:enable_a20_method.
Fix by constructing and executing an ljmp instruction, to trigger the
relevant descriptor population logic on 486 and earlier CPUs. This
ljmp instruction is constructed on the stack, since the .prefix
section may be executing directly from ROM (or from memory that the
BIOS has write-protected in order to emulate an ISA ROM region) and so
cannot be modified.
Reported-by: Nikolai Zhubr <n-a-zhubr@yandex.ru>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
SBAT defines an encoding for security generation numbers stored as a
CSV file within a special ".sbat" section in the signed binary. If a
Secure Boot exploit is discovered then the generation number will be
incremented alongside the corresponding fix.
Platforms may then record the minimum generation number required for
any given product. This allows for an efficient revocation mechanism
that consumes minimal flash storage space (in contrast to the DBX
mechanism, which allows for only a single-digit number of revocation
events to ever take place across all possible signed binaries).
Add SBAT metadata to iPXE EFI binaries to support this mechanism.
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 ARM versions of the big-integer inline assembly functions include
constraints to indicate that the output value is modified by the
assembly code. These constraints are not present in the equivalent
code for the x86 versions.
As of GCC 11, this results in the compiler reporting that the output
values may be uninitialized.
Fix by including the relevant memory output constraints.
Reported-by: Christian Hesse <mail@eworm.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE will construct CPIO headers for images that have a non-empty
command line, thereby allowing raw images (without CPIO headers) to be
injected into a dynamically constructed initrd. This feature is
currently implemented within the BIOS-only bzImage format support.
Split out the CPIO header construction logic to allow for reuse in
other contexts such as in a UEFI build.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Avoid using the "rdtsc" instruction unless profiling is enabled. This
allows the non-debug build of the UNDI driver to be used on a CPU such
as a 486 that does not support the TSC.
Reported-by: Nikolai Zhubr <n-a-zhubr@yandex.ru>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The decompressor uses the i486 "bswap" instruction, but does not
require any instructions that exist only on i586 or above. Update the
".arch" directive to reflect the requirements of the code as
implemented.
Reported-by: Martin Habets <habetsm.xilinx@gmail.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>
There is no method for obtaining the number of PCI buses when using
PCIAPI_DIRECT, and we therefore currently scan all possible bus
numbers. This can cause a several-second startup delay in some
virtualised environments, since PCI configuration space access will
necessarily require the involvement of the hypervisor.
Ameliorate this situation by defaulting to scanning only a single bus,
and expanding the number of PCI buses to accommodate any subordinate
buses that are detected during enumeration.
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>
When building as a Linux userspace application, iPXE currently
implements its own system calls to the host kernel rather than relying
on the host's C library. The output binary is statically linked and
has no external dependencies.
This matches the general philosophy of other platforms on which iPXE
runs, since there are no external libraries available on either BIOS
or UEFI bare metal. However, it would be useful for the Linux
userspace application to be able to link against host libraries such
as libslirp.
Modify the build process to perform a two-stage link: first picking
out the requested objects in the usual way from blib.a but with
relocations left present, then linking again with a helper object to
create a standard hosted application. The helper object provides the
standard main() entry point and wrappers for the Linux system calls
required by the iPXE Linux drivers and interface code.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow for the possibility of linking to platform libraries for the
Linux userspace build by adding an iPXE-specific symbol prefix.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Recent versions of the GNU assembler (observed with GNU as 2.35 on
Fedora 33) will produce a warning message
Warning: no instruction mnemonic suffix given and no register
operands; using default for `bts'
The operand size affects only the potential range for the bit number.
Since we pass the bit number as an unsigned int, it is already
constrained to 32 bits for both i386 and x86_64.
Silence the assembler warning by specifying an explicit 32-bit operand
size (and thereby matching the choice that the assembler would
otherwise make automatically).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Assume that preservation of the %xmm registers is unnecessary during
installation of iPXE into memory, since this is an operation that by
its nature substantially disrupts large portions of the system anyway
(such as the E820 memory map). This assumption allows us to utilise
the existing CPUID code to check that FXSAVE/FXRSTOR are supported.
Test for support during the call to init_librm and store the flag for
use during subsequent calls to virt_call.
Reduce the scope of TIVOLI_VMM_WORKAROUND to affecting only the call
to check_fxsr(), to reduce #ifdef pollution in the remaining code.
Debugged-by: Johannes Heimansberg <git@jhe.dedyn.io>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The __asmcall declaration has no effect on a void function with no
parameters, but should be included for completeness since the function
is called directly from assembly code.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide a generic raw image prefix, which assumes that the iPXE image
has been loaded in its entirety on a paragraph boundary.
The resulting .raw image can be loaded via RPL using an rpld.conf file
such as:
HOST {
ethernet = 00:00:00:00:00:00/6;
FILE {
path="ipxe.raw";
load=0x2000;
};
execute=0x2000;
};
Debugged-by: Johannes Heimansberg <git@jhe.dedyn.io>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
A zero-length initrd file will currently cause an endless loop during
reshuffling as the empty image is repeatedly swapped with itself.
Fix by terminating the inner loop before considering an image as a
candidate to be swapped with itself.
Reported-by: Pico Mitchell <pico@randomapplications.com>
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>
Some versions of GNU ld (observed with binutils 2.36 on Arch Linux)
introduce a .note.gnu.property section marked as loadable at a high
address and with non-empty contents. This adds approximately 128MB of
garbage to the BIOS .usb disk images.
Fix by using a custom linker script for the prefix-only binaries such
as the USB disk partition table and MBR, in order to allow unwanted
sections to be explicitly discarded.
Reported-by: Christian Hesse <mail@eworm.de>
Tested-by: Christian Hesse <mail@eworm.de>
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>
Several distributions include versions of gcc that are patched to
create position-independent executables by default. These have caused
multiple problems over the years: see e.g. commits fe61f6d ("[build]
Fix compilation when gcc is patched to default to -fPIE -Wl,-pie"),
5de1346 ("[build] Apply the "-fno-PIE -nopie" workaround only to i386
builds"), 7c395b0 ("[build] Use -no-pie on newer versions of gcc"),
and decee20 ("[build] Disable position-independent code for ARM64 EFI
builds").
The build system currently attempts to work around these mildly broken
patched versions of gcc for the i386 and arm64 architectures. This
misses the relatively obscure bin-x86_64-pcbios build platform, which
turns out to also require the same workaround.
Attempt to preempt the next such required workaround by moving the
existing i386 version to apply to all platforms and all architectures,
unless -fpie has been requested explicitly by another Makefile (as is
done by arch/x86_64/Makefile.efi).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add a few more ABSOLUTE() expressions to convince the FreeBSD linker
that already-absolute symbols are, in fact, absolute.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some versions of objcopy will spuriously complain when asked to
extract the .zinfo section since doing so will nominally alter the
load addresses of the (non-loadable) .bss.* sections.
Avoid these warnings by placing the .zinfo section at the very end of
the load memory address space.
Allocate non-overlapping load memory addresses for the (non-loadable)
.bss.* sections, in the hope of avoiding spurious warnings about
overlapping load addresses.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Consolidate the remaining logic common to initrd_init() and imgmem()
into a shared image_memory() function.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Generalise util/geniso, util/gensdsk, and util/genefidsk to create a
single script util/genfsimg that can be used to build either FAT
filesystem images or ISO images.
Extend the functionality to allow for building multi-architecture UEFI
bootable ISO images and combined BIOS+UEFI images.
For example:
./util/genfsimg -o combined.iso \
bin-x86_64-efi/ipxe.efi \
bin-arm64-efi/ipxe.efi \
bin/ipxe.lkrn
would generate a hybrid image that could be used as a CDROM (or hard
disk or USB key) on legacy BIOS, x86_64 UEFI, or ARM64 UEFI.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The malloc_dma() function allocates memory with specified physical
alignment, and is typically (though not exclusively) used to allocate
memory for DMA.
Rename to malloc_phys() to more closely match the functionality, and
to create name space for functions that specifically allocate and map
DMA-capable buffers.
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 change fixes the offset used when retrieving the iPXE stack
pointer after a COM32 binary returns. The iPXE stack pointer is saved
at the top of the available memory then the the top of the stack for
the COM32 binary is set just below it. However seven more items are
pushed on the COM32 stack before the entry point is invoked so when
the COM32 binary returns the location of the iPXE stack pointer is 28
(and not 24) bytes above the current stack pointer.
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>
The only remaining use case in iPXE for the CPU direction flag is in
__memcpy_reverse() where it is set to allow the use of "rep movsb" to
perform the memory copy. This matches the equivalent functionality in
the EDK2 codebase, which has functions such as InternalMemCopyMem that
also temporarily set the direction flag in order to use "rep movsb".
As noted in commit d2fb317 ("[crypto] Avoid temporarily setting
direction flag in bigint_is_geq()"), some UEFI implementations are
known to have buggy interrupt handlers that may reboot the machine if
a timer interrupt happens to occur while the direction flag is set.
Work around these buggy UEFI implementations by using the
(unoptimised) generic_memcpy_reverse() on i386 or x86_64 UEFI
platforms.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The UEFI specification states that the calling convention for IA-32
and x64 includes "Direction flag in EFLAGS is clear". This
specification covers only the calling convention used at the point of
calling functions annotated with EFIAPI. The specification explicitly
states that other functions (such as private functions or static
library calls) are not required to follow the UEFI calling
conventions.
The reference EDK2 implementation follows this specification. In
particular, the EDK2 interrupt handlers will clear the direction flag
before calling any EFIAPI functions, and will restore the direction
flag when returning from the interrupt handler. Some EDK2 private
library functions (most notably InternalMemCopyMem) may set the
direction flag temporarily in order to make efficient use of CPU
string operations.
The current implementation of iPXE's bigint_is_geq() for i386 and
x86_64 will similarly set the direction flag temporarily in order to
make efficient use of CPU string operations.
On some UEFI implementations (observed with a Getac RX10 tablet), a
timer interrupt that happens to occur while the direction flag is set
will reboot the machine. This very strongly indicates that the UEFI
timer interrupt handler is failing to clear the direction flag before
performing an affected operation (such as copying a block of memory).
Work around such buggy UEFI implementations by rewriting
bigint_is_geq() to avoid the use of string operations and so obviate
the requirement to temporarily set the direction flag.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some versions of gcc (observed with the cross-compiling gcc 9.3.0 in
Ubuntu 20.04) default to enabling -fPIE. Experimentation shows that
this results in the emission of R_AARCH64_ADR_GOT_PAGE relocation
records for __stack_chk_guard. These relocation types are not
supported by elf2efi.c.
Fix by explicitly disabling position-independent code for ARM64 EFI
builds.
Debugged-by: Antony Messerli <antony@mes.ser.li>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Reduce the size of the USB disk image in the common case that
CONSOLE_INT13 is not enabled.
Originally-implemented-by: Romain Guyard <romain.guyard@mujin.co.jp>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
It is currently not possible to build the all-drivers iPXE binaries
for ARM, since there is no implementation for inb(), outb(), etc.
There is no common standard for accessing I/O space on ARM platforms,
and there are almost no ARM-compatible peripherals that actually
require I/O space accesses.
Provide dummy implementations that behave as though no device is
present (i.e. ignore writes, return all bits high for reads). This is
sufficient to allow the all-drivers binaries to link, and should cause
drivers to behave as though no I/O space peripherals are present in
the system.
Signed-off-by: Michael Brown <mcb30@ipxe.org>