Age | Commit message (Collapse) | Author | Files | Lines |
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Extract part of the logic in initrd_init() to a standalone function
image_set_data().
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>
|
|
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>
|
|
Signed-off-by: David Decotigny <ddecotig@gmail.com>
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>
|
|
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>
|
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
PCI Configuration Space contains fields prog-if at the offset 0x09,
sub-class at the offset 0x0a and base-class at the offset 0x0b (it
respects little endian). PCIR structure uses these fields in the same
order.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Allow the subsystem IDs to be used when checking for PXE stacks with
broken interrupt support.
Suggested-by: Levi Hsieh <Levi.Hsieh@dell.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>
|
|
Provide symbols constructed from the object name and line number for
code fragments placed into alternative sections, such as inline
REAL_CODE() assembly placed into .text16. This simplifies the
debugging task of finding the source code corresponding to a given
instruction pointer.
Note that we cannot use __FUNCTION__ since it is not a preprocessor
macro and so cannot be concatenated with string literals.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
If the underlying PXE stack reports an invalid IRQ number (above
IRQ_MAX), treat this as equivalent to an empty IRQ number and fall
back to using polling mode.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
We currently perform various min-entropy calculations using build-time
floating-point arithmetic. No floating-point code ends up in the
final binary, since the results are eventually converted to integers
and asserted to be compile-time constants.
Though this mechanism is undoubtedly cute, it inhibits us from using
"-mno-sse" to prevent the use of SSE registers by the compiler.
Fix by using fixed-point arithmetic instead.
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>
|
|
When DEBUG=librm_mgmt is enabled, intercept CPU exceptions and provide
a register and stack dump, then drop to an emergency shell. Exiting
from the shell will almost certainly not work, but this provides an
opportunity to view the register and stack dump and carry out some
basic debugging.
Note that we can intercept only the first 8 CPU exceptions, since a
PXE ROM is not permitted to rebase the PIC.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Using "ld --oformat binary" for mbr.bin and usbdisk.bin seems to cause
segmentation faults on some versions of binutils (observed on Fedora
27). Work around this problem by using ld to create an intermediate
ELF object, followed by objcopy (via the existing %.tmp -> %.bin rule)
to create the final binary.
Note that we cannot simply use a single-stage "objcopy -O binary"
since this will not process the relocation records for x86_64: see
commit 1afcccd ("[build] Do not use "objcopy -O binary" for objects
with relocation records").
Reported-by: Brent S <bts@square-r00t.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|
|
Ensure that all headers (PCI, UNDI, PnP, iPXE) are aligned to at least
four bytes, so that all accesses to header fields will be correctly
aligned even when reading directly from the expansion ROM BAR.
Reported-by: Peter von Konigsmark <peter@exablaze.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
|