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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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 "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 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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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 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>
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>
Use PRODUCT_SHORT_NAME instead of a hardcoded "iPXE" for strings which
are typically shown in the user interface.
Note that this only allows for customisation of the user interface.
Where the "iPXE" string serves a technical purpose (such as in the
HTTP User-Agent), the string cannot be customised.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some devices return multiple packets in a single poll. Handle such
devices gracefully by enqueueing received PXE UDP packets (along with
a pseudo-header to hold the IPv4 addresses and port numbers) and
dequeueing them on subsequent calls to PXENV_UDP_READ.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Fetching the TFTP file size is currently implemented via a custom
"tftpsize://" protocol hack. Generalise this approach to instead
close the TFTP connection whenever the parent data-transfer interface
is closed.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow drivers to specify a supported PCI class code. To save space in
the final binary, make this an attribute of the driver rather than an
attribute of a PCI device ID list entry.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The EDK2 codebase uses -malign-double for 32-bit builds, which causes
64-bit integers to be naturally aligned. This affects the layout of
some structures (including EFI_BLOCK_IO_MEDIA).
This mirrors wimboot commit 7b8f39d ("[build] Fix building of 32-bit
UEFI version").
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The .mrom payload has a code type of 0xff and so the initialisation
length field (single byte at offset 0x02) does not need to be
present. Use only the PCI header's image length field, which allows
the .mrom payload to be up to 32MB in size.
Inspired-by: Swift Geek <swiftgeek@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
mromprefix.S currently uses the initialisation length field (single
byte at offset 0x02) to determine the length of a ROM image within a
multi-image ROM BAR. For PCI ROM images with a code type other than
0, the initialisation length field may not be present.
Fix by using the PCI header's image length field instead.
Inspired-by: Swift Geek <swiftgeek@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The build process has for a long time assumed that every ROM is a PCI
ROM, and will always include the PCI header and PCI-related
functionality (such as checking the PCI BIOS version, including the
PCI bus:dev.fn address within the ROM product name string, etc.).
While real ISA cards are no longer in use, some virtualisation
environments (notably VirtualBox) have support only for ISA ROMs.
This can cause problems: in particular, VirtualBox will call our
initialisation entry point with random garbage in %ax, which we then
treat as the PCI bus:dev.fn address of the autoboot device: this
generally prevents the default boot sequence from using any network
devices.
Create .isarom and .pcirom prefixes which can be used to explicitly
specify the type of ROM to be created. (Note that the .mrom prefix
always implies a PCI ROM, since the .mrom mechanism relies on
reconfiguring PCI BARs.)
Make .rom a magic prefix which will automatically select the
appropriate PCI or ISA ROM prefix for ROMs defined via a PCI_ROM() or
ISA_ROM() macro. To maintain backwards compatibility, we default to
building a PCI ROM for anything which is not directly derived from a
PCI_ROM() or ISA_ROM() macro (e.g. bin/intel.rom).
Add a selection of targets to "make everything" to ensure that the
(relatively obscure) ISA ROM build process is included within the
per-commit QA checks.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Since some PnP BIOSes fail to set %es:di to point to the PnP signature
on entry, we identify a PnP BIOS by scanning through the top 64kB of
base memory looking for the PnP structure. We therefore don't
actually use the values of %es:di provided to the initialisation entry
point, and so there is no need to preserve them.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Using version 1 grant tables limits guests to using 16TB of grantable
RAM, and prevents the use of subpage grants. Some versions of the Xen
hypervisor refuse to allow the grant table version to be set after the
first grant references have been created, so the loaded operating
system may be stuck with whatever choice we make here. We therefore
currently use version 2 grant tables, since they give the most
flexibility to the loaded OS.
Current versions (7.2.0) of the Windows PV drivers have no support for
version 2 grant tables, and will merrily create version 1 entries in
what the hypervisor believes to be a version 2 table. This causes
some confusion.
Avoid this problem by attempting to use version 1 tables, since
otherwise we may render Windows unable to boot.
Play nicely with other potential bootloaders by accepting either
version 1 or version 2 grant tables (if we are unable to set our
requested version).
Note that the use of version 1 tables on a 64-bit system introduces a
possible failure path in which a frame number cannot fit into the
32-bit field within the v1 structure. This in turn introduces
additional failure paths into netfront_transmit() and
netfront_refill_rx().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
At some point during XenServer development history, the Windows PV
drivers changed to using a PCI device ID of 5853:0002 rather than
5853:0001. Current (7.2.0) drivers will bind to either 5853:0001 or
5853:0002, and the general approach taken by the world at large
(including Amazon EC2) seems to be to use only 5853:0001.
However, the current version of XenServer (6.2.0) will create the
platform device as 5853:0002 (via the platform:device_id VM parameter)
for any VMs created using the built-in templates for Windows Vista or
later.
Accept either PCI ID, since the underlying device is identical.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We currently treat network devices as available for use via the SNP
API only if RX queue processing has been frozen. (This is similar in
spirit to the way that RX queue processing is frozen for the network
device currently exposed via the PXE API.)
The default state of a freshly created network device is for the RX
queue to not be frozen, and thus to be unavailable for use via SNP.
This causes problems when devices are added through code paths other
than _efidrv_start() (which explicitly releases devices for use via
SNP).
We don't actually need to freeze RX queue processing, since calls via
the SNP API will always use netdev_poll() rather than net_poll(), and
so will never trigger the RX queue processing code path anyway.
We can therefore simplify the code to use a single global flag to
indicate whether network devices are claimed for use by iPXE or
available for use via SNP. Using a global flag allows the default
state for dynamically created network devices to behave sensibly.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add basic support for Xen PV-HVM domains (detected via the Xen
platform PCI device with IDs 5853:0001), including support for
accessing configuration via XenStore and enumerating devices via
XenBus.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When a 32-bit iPXE binary is running on a system which allocates PCI
memory BARs above 4GB, our PCI subsystem will return the base address
for any such BARs as zero (with a warning message if DEBUG=pci is
enabled). Currently, ioremap() will happily map an address pointing
to the start of physical memory, providing no sensible indication of
failure.
Fix by always returning NULL if we are asked to ioremap() a zero bus
address.
With a totally flat memory model (e.g. under EFI), this provides an
accurate failure indication since no PCI peripheral will be mapped to
the zero bus address.
With the librm memory model, there is the possibility of a spurious
NULL return from ioremap() if the bus address happens to be equal to
virt_offset. Under the current virtual memory map, the NULL virtual
address will always be the start of .textdata, and so this problem
cannot occur; a NULL return from ioremap() will always be an accurate
failure indication.
Debugged-by: Anton D. Kachalov <mouse@yandex-team.ru>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide a single instance of EFI_DRIVER_BINDING_PROTOCOL (attached to
our image handle); this matches the expectations scattered throughout
the EFI specification.
Open the underlying hardware device using EFI_OPEN_PROTOCOL_BY_DRIVER
and EFI_OPEN_PROTOCOL_EXCLUSIVE, to prevent other drivers from
attaching to the same device.
Do not automatically connect to devices when being loaded as a driver;
leave this task to the platform firmware (or to the user, if loading
directly from the EFI shell).
When running as an application, forcibly disconnect any existing
drivers from devices that we want to control, and reconnect them on
exit.
Provide a meaningful driver version number (based on the build
timestamp), to allow platform firmware to automatically load newer
versions of iPXE drivers if multiple drivers are present.
Include device paths within debug messages where possible, to aid in
debugging.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some external code (observed with FreeBSD's bootloader) will continue
to make INT 13 calls after reconfiguring the 8259 PIC to change the
vector offsets for IRQs. If an IRQ (e.g. the timer IRQ) subsequently
occurs while iPXE is in protected mode, this will cause a general
protection fault since the corresponding IDT entry is empty.
A general protection fault is INT 0x0d, which happens to overlap with
the original IRQ5. We therefore do have an ISR set up to handle a
general protection fault, but this ISR simply reflects the interrupt
down to the real-mode INT 0x0d and then attempts to return. Since our
ISR is expecting a hardware interrupt rather than a general protection
fault, it doesn't remove the error code from the stack before issuing
the iret instruction; it therefore attempts to return to a garbage
address. Since the segment part of this address is likely to be
invalid, a second general protection fault occurs. This cycle
continues until we run out of stack space and triple fault.
Fix by reflecting all INTs down to real mode. This actually reduces
the code size by four bytes (but increases the bss size by almost
2kB).
Reported-by: Brian Rak <dn@devicenull.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The bzImage boot protocol allows the real-mode code to be loaded at
any segment within base memory. (The fact that both iPXE and recent
versions of Syslinux will load the real-mode code at 1000:0000 is a
coincidence; it is not guaranteed by the specification.)
Fix by making the code relocatable.
Reported-by: Andrew Stuart <andrew@shopcusa.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Rework geniso and genliso to provide a single merged utility for
generating ISO images.
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The .lkrn prefix currently provides a zImage kernel with unused setup
sectors and the whole iPXE binary placed within the "protected mode
kernel" portion of the zImage.
The work carried out years ago to create the .mrom format provides a
mechanism allowing the iPXE binary to be split into a small real-mode
header and a larger payload. This neatly matches the way that a
bzImage is loaded: the "setup sectors" can contain the header and the
"protected mode kernel" can contain the payload.
This removes the size restrictions on an iPXE .lkrn image (and hence
on derived image formats such as .iso).
Also remove obsolete copyright information, since none of the original
code or functionality now remains.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Interrupt processing adds noise to profiling results. Allow
interrupts (from within protected mode) to be profiled separately,
with time spent within the interrupt handler being excluded from any
other profiling currently in progress.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
PXENV_UNDI_ISR calls may implicitly refill the underlying receive
ring, and so could continue to retrieve packets indefinitely. Place
an upper limit on the number of calls to PXENV_UNDI_ISR per call to
undinet_poll().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When making a call from real mode to protected mode, we save and
restore the global and interrupt descriptor table registers. The
restore currently takes place after returning to real mode, which
generates two EXCEPTION_NMIs and corresponding VM exits when running
under KVM on an Intel CPU.
Avoid the VM exits by restoring the descriptor table registers inside
prot_to_real, while still running in protected mode.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Ensure that all segment registers have zero in the low two bits before
transitioning to protected mode. This allows the CPU state to
immediately be deemed to be "valid", and eliminates the need for any
further emulated instructions.
Load the protected-mode interrupt descriptor table after switching to
protected mode, since this avoids triggering an EXCEPTION_NMI and
corresponding VM exit.
This reduces the time taken by real_to_prot under KVM by around 50%.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On an Intel CPU supporting VMX, KVM will emulate instructions while
the CPU state remains "invalid". In real mode, the CPU state is
defined to be "invalid" if any segment register has a base which is
not equal to (sreg<<4) or a limit which is not equal to 64kB.
We don't actually use the base stored in the REAL_DS descriptor for
any significant purpose. Change the base stored in this descriptor to
be equal to (REAL_DS<<4). A segment register loaded with REAL_DS is
then automatically valid in both real and protected modes. This
allows KVM to stop emulating instructions much sooner.
The only use of REAL_DS for memory accesses currently occurs in the
indirect ljmp within prot_to_real. Change this to a direct ljmp,
storing rm_cs in .text16 as part of the ljmp instruction. This
removes the only memory access via REAL_DS (thereby allowing for the
above descriptor base address hack), and also simplifies the ljmp
instruction (which will still have to be emulated).
Load the real-mode interrupt descriptor table register before
switching to real mode, since this avoids triggering an EXCEPTION_NMI
and corresponding VM exit.
This reduces the time taken by prot_to_real under KVM by around 65%.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The mode-transition code involves paths which switch back and forth
between the .text and .text16 sections. At present, only the start of
each function is labelled, which makes it difficult to decode
addresses within the parts of the function existing in a different
section.
Add explicit labels at the start of each section change, so that
addresses can be meaningfully decoded to the nearest label.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Now that we can handle interrupts while in protected mode, there is no
need to switch to real mode just to halt the CPU.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The currticks() function is called at least once per TCP packet, and
so is performance-critical. Switching to real mode just to allow the
timer interrupt to fire is expensive when running inside a virtual
machine, and imposes a significant performance cost.
Fix by enabling interrupts without switching to real mode. This
results in an approximately 100% increase in download speed when
running under KVM.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We now have the ability to handle interrupts while in protected mode,
and so no longer need to set up a dedicated interrupt descriptor table
while running COM32 executables.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When running in a virtual machine, switching to real mode may be
expensive. Allow interrupts to be enabled while in protected mode and
reflected down to the real-mode interrupt handlers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We currently use flat real mode wherever real mode is required. This
guarantees that we will not surprise some unsuspecting external caller
which has carefully set up flat real mode by suddenly reducing the
segment limits to 64kB.
However, operating in flat real mode imposes a severe performance
penalty in some virtualisation environments, since some CPUs cannot
fully virtualise flat real mode and so the hypervisor must fall back
to emulation. In particular, operating under KVM on a pre-Westmere
Intel CPU will be at least an order of magnitude slower, to the point
that there is a visible teletype effect when printing anything to the
BIOS console. (Older versions of KVM used to cheat and ignore the
"flat" part of flat real mode, which masked the problem.)
Switch (back) to using genuine real mode with 64kB segment limits
instead of flat real mode. Hopefully this won't break anything.
Add an explicit switch to flat real mode before returning to the BIOS
from the ROM prefix, since we know that a PMM BIOS will call the ROM
initialisation point (and potentially the BEV) in flat real mode.
As noted in previous commit messages, it is not possible to restore
the real-mode segment limits after a transition to protected mode,
since there is no way to know which protected-mode segment descriptor
was originally used to initialise the limit portion of the segment
register.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We observed some time ago (in commit 4ce8d61 "Import various libgcc
functions from syslinux") that gcc seems to treat calls to the
implicit arithmetic functions (e.g. __udivdi3()) as being affected by
-mregparm but unaffected by -mrtd.
This seems to be no longer the case with current gcc versions, which
treat calls to these functions as being affected by both -mregparm and
-mrtd, as expected.
There is nothing obvious in the gcc changelogs to indicate precisely
when this happened. From experimentation with available gcc versions,
the change occurred sometime between v4.6.3 and v4.7.2. We assume
that only versions up to v4.6.x require the special treatment.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some BIOSes (observed with a ProLiant DL360p Gen8 SE) perform no range
checking whatsoever on the parameters passed to INT10,06 and will
therefore happily write to an area beyond the end of video RAM. The
area immediately following the video RAM tends to be the VGA BIOS ROM
image. Overwriting the VGA BIOS leads to an interesting variety of
crashes and reboots.
Fix by specifying an exact width and height to be cleared, rather than
passing in large values and relying upon the BIOS to truncate them to
the appropriate range.
Reported-by: Alex Davies <adavies@jumptrading.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some UEFI builds will set up a timer to continuously poll any SNP
devices. This can drain packets from the network device's receive
queue before iPXE gets a chance to process them.
Use netdev_rx_[un]freeze() to explicitly indicate when we expect our
network devices to be driven via the external SNP API (as we do with
the UNDI API on the standard BIOS build), and disable the SNP API
except when receive queue processing is frozen.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
EFIRC() uses PLATFORM_TO_ERRNO(), which evaluates its argument twice
(and can't trivially use a braced-group expression or an inline
function to avoid this, since it gets used outside of function
context).
The expression "EFIRC(main())" will therefore end up calling main()
twice, which is not the intended behaviour. Every other instance of
EFIRC() is of the simple form "EFIRC(rc)", so fix by converting this
instance to match.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE will detect timeout failures in several situations: network
link-up, DHCP, TCP connection attempts, unacknowledged TCP data, etc.
This does not cover all possible circumstances. For example, if a
connection to a web server is successfully established and the web
server acknowledges the HTTP request but never sends any data in
response, then no timeout will be triggered. There is no timeout
defined within the HTTP specifications, and the underlying TCP
connection will not generate a timeout since it has no way to know
that the HTTP layer is expecting to receive data from the server.
Add a "--timeout" parameter to "imgfetch", "chain", etc. If no
progress is made (i.e. no data is downloaded) within the timeout
period, then the download will be aborted.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit c429bf0 ("[romprefix] Store boot bus:dev.fn address as autoboot
device location") introduced a regression by using register %cx to
temporarily hold the PCI bus:dev.fn address, despite the fact that %cx
was already being used to hold the stored BIOS stack segment.
Consequently, when returning to the BIOS after a failed or cancelled
boot attempt, iPXE would end up calling INT 18 with the stack segment
set equal to the PCI bus:dev.fn address. Writing to essentially
random areas of memory tends to upset even the more robust BIOSes.
Fix by using register %ax to temporarily hold the PCI bus:dev.fn
address.
Reported-by: Anton D. Kachalov <mouse@yandex-team.ru>
Tested-by: Anton D. Kachalov <mouse@yandex-team.ru>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE currently pads initrd images to a multiple of 4kB and inserts
zero padding between images, as required by some versions of the Linux
kernel. The overall length reported via the ramdisk_size field in the
bzImage header includes this zero padding.
This causes problems when using memdisk to load a gzip-compressed disk
image. memdisk treats the ramdisk_size field as containing the exact
length of the initrd image, and uses this length to locate the 8-byte
gzip footer. This will generally cause memdisk to fail to decompress
the disk image.
Fix by reporting the exact length of the initrd image set, including
any padding inserted between images but excluding any padding added at
the end of the final image.
Reported-by: Levente LEVAI <levail@aviatronic.hu>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
qemu can load an option ROM which is not associated with a particular
PCI device using the "-option-rom" syntax. Under these circumstances,
we should ignore the PCI bus:dev.fn address that we expect to find in
%ax on entry to the initialisation vector.
Fix by using the PCI bus:dev.fn address only if it is non-zero. Since
00:00.0 will always be the host bridge, it can never be the address of
a network card.
Reported-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Per the BIOS Boot Specification, the initialization phase of the ROM
is called with the PFA (PCI Function Address) in the %ax register.
The intention is that the ROM code will store that device address
somewhere and use it for booting from that device when the Boot Entry
Vector (BEV) is called. iPXE does store the PFA, but doesn't use it
to select the boot network device. This renders BIOS IPL lists fairly
ineffective.
Fix by using the BBS-specified bus:dev.fn address as the autoboot
device location.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE currently prints a "Press Ctrl-B" banner twice: once when the ROM
is first called for initialisation and again if we attempt to boot
from the ROM. This slows boot, especially when the NIC is not the
primary boot device. Tools such as libguestfs make use of QEMU VMs
for performing maintenance on disk images and may make use of NICs in
the VM for network support. If iPXE introduces a static init-time
delay, that directly translates to increased runtime for the tools.
Fix by allowing the ROM banner timeout to be configured independently
of the main banner timeout.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add support for parsing of URIs containing literal IPv6 addresses
(e.g. "http://[fe80::69ff:fe50:5845%25net0]/boot.ipxe").
Duplicate URIs by directly copying the relevant fields, rather than by
formatting and reparsing a URI string. This relaxes the requirements
on the URI formatting code and allows it to focus on generating
human-readable URIs (e.g. by not escaping ':' characters within
literal IPv6 addresses). As a side-effect, this allows relative URIs
containing parameter lists (e.g. "../boot.php##params") to function
as expected.
Add validity check for FTP paths to ensure that only printable
characters are accepted (since FTP is a human-readable line-based
protocol with no support for character escaping).
Construct TFTP next-server+filename URIs directly, rather than parsing
a constructed "tftp://..." string,
Add self-tests for URI functions.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Rename the "--bpp" option to "--depth", to free up the single-letter
option "-b" for "--bottom" in preparation for adding margin support.
This does not break backwards compatibility with documented features,
since the "console" command has not yet been documented.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow for an arbitrary margin to be specified in the console
configuration. If the actual screen size does not match the requested
screen size, then update any margins specified so that they remain in
the same place relative to the requested screen size. If margins are
unspecified (i.e. zero), then leave them as zero.
The underlying assumption here is that any specified margins are
likely to describe an area within a background picture, and so should
remain in the same place relative to that background picture.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use the magic colour facility to cause the user interface background
to become transparent when we have a background picture.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The vgabios used by bochs and qemu (and other virtualisation products)
has a bug in its implementation of INT 10,4f00 which causes the high
16 bits of %ebx and %edx to become corrupted.
The vgabios code uses a "pushaw"/"popaw" pair to preserve the low 16
bits of all non-segment registers. The vgabios code is compiled using
bcc, which generates 8086-compatible code and so never touches the
high 16 bits of the 32-bit registers. However, the function
vbe_biosfn_return_controller_information() includes the line:
size_64k = (Bit16u)((Bit32u)cur_info->info.XResolution *
cur_info->info.XResolution *
cur_info->info.BitsPerPixel) >> 19;
which generates an implicit call to the "lmulul" function. This
function is implemented in vbe.c as:
; helper function for memory size calculation
lmulul:
and eax, #0x0000FFFF
shl ebx, #16
or eax, ebx
SEG SS
mul eax, dword ptr [di]
mov ebx, eax
shr ebx, #16
ret
which modifies %eax, %ebx, and %edx (as a result of the "mul"
instruction, which places its result into %edx:%eax).
Work around this problem by marking %ebx and %edx as being clobbered
by the call to INT 10,4f00. (%eax is already used as an output
register, so does not need to be on the clobber list.)
Reported-by: Oliver Rath <rath@mglug.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The fetch_setting() family of functions may currently modify the
definition of the specified setting (e.g. to add missing type
information). Clean up this interface by requiring callers to provide
an explicit buffer to contain the completed definition of the fetched
setting, if required.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
There is no requirement for VBE modes to be listed in increasing order
of resolution. With the present logic, this can cause e.g. a 1024x768
mode to be selected if the user asks for 640x480, if the 1024x768 mode
is earlier in the mode list.
Define a scoring system for modes as
score = ( width * height - bpp )
and choose the mode with the lowest score among all acceptable modes.
This should prefer to choose the mode closest to the requested
resolution, with a slight preference for higher colour depths.
Reported-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The VirtualBox BIOS fails to retrieve mode information (with status
0x0100) for some modes within the mode list. Skip any such modes,
rather than treating this as a fatal error.
Reported-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The VESA frame buffer console uses the VESA BIOS extensions (VBE) to
enumerate video modes, selects an appropriate mode, and then hands off
to the generic frame buffer code.
The font is extracted from the VGA BIOS, avoiding the need to provide
an external font file.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Syslinux 6.x places its files into a bios subdirectory, and requires
that a ldlinux.c32 module be included within the ISO image. Add the
relevant search paths for isolinux.bin, and include the file
ldlinux.c32 within the ISO image if it exists.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The retrieval of the cached DHCPACK and the creation of network
devices are both currently scheduled as STARTUP_NORMAL. It is
therefore possible that the cached DHCPACK will not be retrieved in
time for cachedhcp_probe() to apply it to the relevant network device.
Fix by retrieving the cached DHCPACK at initialisation time rather
than at startup time.
As an optimisation, an unclaimed cached DHCPACK can be freed
immediately after the last network device has been created, rather
than waiting until shutdown.
Reported-by: Espen Braastad <espen.braastad@redpill-linpro.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Most network upper-layer drivers do not implement all three methods
(probe, notify, and remove). Save code by making all methods
optional.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When chainloading, always retrieve the cached DHCPACK packet from the
underlying PXE stack, and apply it as the original contents of the
"net<X>.dhcp" settings block. This allows cached DHCP settings to be
used for any chainloaded iPXE binary (not just undionly.kkpxe).
This change eliminates the undocumented "use-cached" setting. Issuing
the "dhcp" command will now always result in a fresh DHCP request.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 238050d ("[build] Work around bug in gcc >= 4.8") works around
one instance of a bug in recent versions of gcc, in which "ebp" cannot
be specified within an asm clobber list.
Some versions of gcc seem to exhibit the same bug on other points in
the codebase. Fix by changing all instances of "ebp" in a clobber
list to use the push/pop %ebp workaround instead.
Originally-implemented-by: Víctor Román Archidona <contacto@victor-roman.es>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow CPUID values to be read using the syntax
${cpuid/<register>.<function>}
For example, ${cpuid/2.0x80000001} will give the value of %ecx after
calling CPUID with %eax=0x80000001. Values for <register> are encoded
as %eax=0, %ebx=1, %ecx=2, %edx=3.
The numeric encoding is more sophisticated than described above,
allowing for settings such as the CPU model (obtained by calling CPUID
with %eax=0x80000002-0x80000004 inclusive and concatenating the values
returned in %eax:%ebx:%ecx:%edx). See the source code for details.
The "cpuvendor" and "cpumodel" settings provide easy access to these
more complex CPUID settings.
This functionality is intended to complement the "cpuid" command,
which allows for testing individual CPUID feature bits.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
There are currently two conflicting usages of the term "named setting"
within iPXE: one refers to predefined settings (such as show up in the
"config" UI), the other refers to settings identified by a name (such
as "net0.dhcp/ip").
Split these usages into the term "predefined setting" and "named
setting" to avoid ambiguity.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Our use of --gc-sections causes the linker to discard the symbols
defined by FILE_LICENCE(), meaning that the resulting licence
determination is incomplete.
We must use the KEEP() directive in the linker script to force the
linker to not discard the licence symbols. Using KEEP(*(COMMON))
would be undesirable, since there are some symbols in COMMON which we
may wish to discard.
Fix by placing symbols defined by PROVIDE_SYMBOL() (which is used by
FILE_LICENCE()) into a special ".provided" section, which we then mark
with KEEP(). All such symbols are zero-length, so there is no cost in
terms of the final binary size.
Since the symbols are no longer in COMMON, the linker will reject
symbols with the same name coming from multiple objects. We therefore
append the object name to the licence symbol, to ensure that it is
unique.
Reported-by: Marin Hannache <git@mareo.fr>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
gcc 4.8 and 4.9 fail to compile pxe_call.c with the error "bp cannot
be used in asm here". Other points in the codebase which use "ebp" in
the asm clobber list do not seem to be affected.
Unfortunately gcc provides no way to specify %ebp as an output
register, so we cannot use this as a workaround. The only viable
solution is to explicitly push/pop %ebp within the asm itself. This
is ugly for two reasons: firstly, it may be unnecessary; secondly, it
may cause gcc to generate invalid %esp-relative addresses if the asm
happens to use memory operands. This specific block of asm uses no
memory operands and so will not generate invalid code.
Reported-by: Daniel P. Berrange <berrange@redhat.com>
Reported-by: Christian Hesse <list@eworm.de>
Originally-fixed-by: Christian Hesse <list@eworm.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some versions of Linux apparently complain if initrds are not aligned
to a page boundary. Fix by changing INITRD_ALIGN from 4 bytes to 4096
bytes.
The amount of padding at the end of each initrd will now often be
sufficient to allow the cpio header to be prepended without crossing
an alignment boundary. The final location of the initrd may therefore
end up being slightly higher than the post-shuffle location.
bzimage_load_initrd() must therefore now copy the initrd body prior to
copying the cpio header, otherwise the start of the initrd body may be
overwritten by the cpio header. (Note that the guarantee that an
initrd will never need to overwrite an initrd at a higher location
still holds, since the overall length of each initrd cannot decrease
as a result of adding a cpio header.)
Reported-by: Dave Hansen <dave@sr71.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 2422647 ("[prefix] Allow prefix to specify an arbitrary maximum
address for relocation") introduced a regression into the UNDI ROM
loader by preserving an extra register on the stack without modifying
the %sp-relative addresses used in the routine.
Fix by correcting the %sp-relative addresses to allow for the extra
preserved variable.
Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When the $(eval) function is available (in GNU make >= 3.80), we can
evaluate many of the dynamically-generated Makefile rules directly.
This avoids generating a few hundred Makefile fragments in the
filesystem, and so speeds up the build process.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Create an explicit concept of "settings scope" and eliminate the magic
values used for numerical setting tags.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Report the cause of the failure when we are unable to open the .mrom
payload. There are two possible failure cases:
- Unable to find a suitable memory BAR to borrow (e.g. if the NIC
doesn't have a memory BAR that is at least as large as the
expansion ROM BAR, or if the memory BAR has been assigned a 64-bit
address which won't fit into the 32-bit expansion ROM BAR). This
will be reported as "BABABABA".
- Unable to find correct ROM image within the BAR. This will be
reported as the address (within the borrowed BAR) at which we first
fail to find a valid 55AA signature.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Exploit the redefinition of iPXE error codes to include a "platform
error code" to allow for meaningful conversion of EFI_STATUS values to
iPXE errors and vice versa.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The low 8 bits of an iPXE error code are currently defined as the
closest equivalent PXE error code. Generalise this scheme to
platforms other than PC-BIOS by extending this definition to "closest
equivalent platform error code". This allows for the possibility of
returning meaningful errors via EFI APIs.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The implementation of INT 10,06 on some BIOSes (observed with both
Hyper-V and a Dell OptiPlex 7010) seems to treat %dx=0xffff as a
special value meaning "do absolutely nothing". Fix by using
%dx=0xfefe, which should still be sufficient to cover any realistic
screen size.
Reported-by: John Clark <skyman@iastate.edu>
Tested-by: John Clark <skyman@iastate.edu>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Abstract out the ability to reboot the system to a separate reboot()
function (with platform-specific implementations), add an EFI
implementation, and make the existing "reboot" command available under
EFI.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 2629b7e ("[pcbios] Inhibit all calls to INT 15,e820 and INT
15,e801 during POST") introduced a regression into .lkrn images when
used with no corresponding initrd.
Specifically, the semantics of the "maximum address for relocation"
value passed to install_prealloc() in %ebp changed so that zero became
a special value meaning "inhibit use of INT 15,e820 and INT 15,e801".
The %ebp value meaing "no upper limit on relocation" was changed from
zero to 0xffffffff, and all prefixes providing fixed values for %ebp
were updated to match the new semantics.
The .lkrn prefix provides the initrd base address as the maximum
address for relocation. When no initrd is present, this address will
be zero, and so will unintentionally trigger the "inhibit INT 15,e820
and INT 15,e801" behaviour.
Fix by explicitly setting %ebp to 0xffffffff if no initrd is present
before calling install_prealloc().
Reported-by: Ján ONDREJ (SAL) <ondrejj@salstar.sk>
Tested-by: Ján ONDREJ (SAL) <ondrejj@salstar.sk>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
If a multifunction PCI device exposes an iPXE ROM via each function,
then each function will display a "Press Ctrl-B to configure iPXE"
prompt, and delay for two seconds. Since a single instance of iPXE
can drive all functions on the multifunction device, this simply adds
unnecessary delay to the boot process.
Fix by inhibiting the "Press Ctrl-B" prompt for all except the first
function on a PCI device.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Many BIOSes do not construct the full system memory map until after
calling the option ROM initialisation entry points. For several
years, we have added sanity checks and workarounds to accommodate
charming quirks such as BIOSes which report the entire 32-bit address
space (including all memory-mapped PCI BARs) as being usable RAM.
The IBM x3650 takes quirky behaviour to a new extreme. Calling either
INT 15,e820 or INT 15,e801 during POST doesn't just get you invalid
data. We could cope with invalid data. Instead, these nominally
read-only API calls manage to trash some internal BIOS state, with the
result that the system memory map is _never_ constructed. This tends
to confuse subsequent bootloaders and operating systems.
[ GRUB 0.97 fails in a particularly amusing way. Someone thought it
would be a good idea for memcpy() to check that the destination memory
region is a valid part of the system memory map; if not, then memcpy()
will sulk, fail, and return NULL. This breaks pretty much every use
of memcpy() including, for example, those inserted implicitly by gcc
to copy non-const initialisers. Debugging is _fun_ when a simple call
to printf() manages to create an infinite recursion, exhaust the
available stack space, and shut down the CPU. ]
Fix by completely inhibiting calls to INT 15,e820 and INT 15,e801
during POST.
We do now allow relocation during POST up to the maximum address
returned by INT 15,88 (which seems so far to always be safe). This
allows us to continue to have a reasonable size of external heap, even
if the PMM allocation is close to the 1MB mark.
The downside of allowing relocation during POST is that we may
overwrite PMM-allocated memory in use by other option ROMs. However,
the downside of inhibiting relocation, when combined with also
inhibiting calls to INT 15,e820 and INT 15,e801, would be that we
might have no external heap available: this would make booting an OS
impossible and could prevent some devices from even completing
initialisation.
On balance, the lesser evil is probably to allow relocation during
POST (up to the limit provided by INT 15,88). Entering iPXE during
POST is a rare operation; on the even rarer systems where doing so
happens to overwrite a PMM-allocated region, then there exists a
fairly simple workaround: if the user enters iPXE during POST and
wishes to exit iPXE, then the user must reboot. This is an acceptable
cost, given the rarity of the situation and the simplicity of the
workaround.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
romprefix.S currently calls uninstall() with an invalid value in %ax.
Consequently, base memory is not freed after a ROM boot attempt (or
after entering iPXE during POST).
The uninstall() function is physically present in .text16, and so can
use %cs to determine the .text16 segment address. The .data16 segment
address is not required, since uninstall() is called only by code
paths which set up .data16 to immediately follow .text16.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The PXE TFTP API allows the caller to request a particular TFTP block
size. Since mid-2008, iPXE has appended a "?blksize=xxx" parameter to
the TFTP URI constructed internally; nothing has ever parsed this
parameter. Nobody seems to have cared that this parameter has been
ignored for almost five years.
Fix by using xfer_window(), which provides a fairly natural way to
convey the block size information from the PXE TFTP API to the TFTP
protocol layer.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some PXE stacks are known to claim that IRQs are supported, but then
never generate interrupts. No satisfactory solution has been found to
this problem; the workaround is to add the PCI vendor and device IDs
to a list of devices which will be treated as simply not supporting
interrupts.
This is something of a hack, since it will generate false positives
for identical devices with a working PXE stack (e.g. those that have
been reflashed with iPXE), but it's an improvement on the current
situation.
Reported-by: Richard Moore <rich@richud.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
At present, loading a bzImage via iPXE requires enough RAM to hold two
copies of each initrd file. Remove this constraint by rearranging the
initrds in place.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
No code from the original source remains within this file; relicense
under GPL2+ with a new copyright notice.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Current versions of gcc require -maccumulate-outgoing-args if any
sysv_abi functions call ms_abi functions. This requirement is likely
to be lifted in future gcc versions, so test explicitly to see if the
current version of gcc requires -maccumulate-outgoing-args.
This problem is currently masked since the implied
-fasynchronous-unwind-tables (which is the default in current gcc
versions) implies -maccumulate-outgoing-args.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 73eb3f1 ("[int13] Zero all possible registers when jumping to a
boot sector") introduced a regression preventing the SAN-booting of
boot sectors which rely upon %dl containing the correct drive number
(such as most CD-ROM boot sectors).
Fix by not zeroing %edx.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
At least one boot sector (the DUET boot sector used for bootstrapping
EFI from a non-EFI system) fails to initialise the high words of
registers before using them in calculations, leading to undefined
behaviour.
Work around such broken boot sectors by explicitly zeroing the
contents of all registers apart from %cs:%ip and %ss:%sp.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Almost all clients of the raw-packet interfaces (UNDI and SNP) can
handle only Ethernet link layers. Expose an Ethernet-compatible link
layer to local clients, while remaining compatible with IPoIB on the
wire. This requires manipulation of ARP (but not DHCP) packets within
the IPoIB driver.
This is ugly, but it's the only viable way to allow IPoIB devices to
be driven via the raw-packet interfaces.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
COMBOOT images are detected by looking for a ".com" or ".cbt" filename
extension. There are widely-used files with a ".com" extension, such
as "wdsnbp.com", which are PXE images rather than COMBOOT images.
Avoid false detection of PXE images as COMBOOT images by accepting
only a ".cbt" extension as indicating a COMBOOT image.
Interestingly, this bug has been present for a long time but was
frequently concealed because the filename was truncated to fit the
fixed-length "name" field in struct image. (PXE binaries ending in
".com" tend to be related to Windows deployment products and so often
use pathnames including backslashes, which iPXE doesn't recognise as a
path separator and so treats as part of a very long filename.)
Commit 1c127a6 ("[image] Simplify image management commands and
internal API") made the image name a variable-length field, and so
exposed this flaw in the COMBOOT image detection algorithm.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow the file mode to be specified using a "mode=" command line
parameter. For example:
initrd http://web/boot/bootlocal.sh /opt/bootlocal.sh mode=755
Requested-by: Bryce Zimmerman <bryce.zimmerman@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some AMI BIOSes apparently break in exciting ways when asked for PMM
allocations for sizes that are not multiples of 4kB.
Fix by rounding up the image source area to the nearest 4kB. (The
temporary decompression area is already rounded up to the nearest
128kB, to facilitate sharing between multiple iPXE ROMs.)
Reported-by: Itay Gazit <itayg@mellanox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Cygwin's assembler treats '/' as a comment character.
Reported-by: Steve Goodrich <steve.goodrich@se-eng.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Similarly to FreeBSD, OpenBSD requires the object format to be
specified as elf_i386_obsd rather than elf_i386.
Reported-by: Jiri B <jirib@devio.us>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
PCI3.0 allows us to report a "runtime size" which can be smaller than
the actual ROM size. On systems that support PMM our runtime size
will be small (~2.5kB), which helps to conserve the limited option ROM
space. However, there is no guarantee that the PMM allocation will
succeed, and so we need to report the worst-case runtime size in the
PCI header.
Move the "shrunk ROM size" field from the PCI header to a new "iPXE
ROM header", allowing it to be accessed by ROM-manipulation utilities
such as disrom.pl.
Reported-by: Anton D. Kachalov <mouse@yandex-team.ru>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
PXENV_FILE_CMDLINE is an iPXE extension, and will not be supported by
most PXE stacks. Do not report any errors to the user, since in
almost all cases the error will mean simply "not loaded by iPXE".
Reported-by: Patrick Domack <patrickdk@patrickdk.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Attempt to restore the network device to the state it was in prior to
calling the NBP. This simplifies the task of taking follow-up action
in an iPXE script.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some BIOSes (observed on a Supermicro system with an AMI BIOS) seem to
use the area immediately below 0x7c00 to store data related to the
boot process. This data is currently liable to be overwritten by the
temporary stack used while decompressing and installing iPXE.
Try to avoid any such problems by placing the temporary stack
immediately after the loaded iPXE binary. Any memory used by the
stack could then potentially have been overwritten anyway by a larger
binary.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The setup_move_size field is not defined in protocol versions earlier
than 2.00 (and is obsolete in versions later than 2.01). In binaries
using versions earlier than 2.00, the relevant location is likely to
contain executable code.
Interestingly, this bug has been present since support for pre-2.00
protocol versions was added in 2009, and has been unexpectedly
modifying the memtest86+ code fragment:
mov $0x92, %dx
inb %dx, %al
Fortuitously, the modification exactly overwrote the value loaded into
%dx, and so the net effect was limited to causing Fast Gate A20
detection to always fail.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The undinet driver always has to make a copy of the received frame
into an I/O buffer. Align this copy sensibly so that subsequent
operations are as fast as possible.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The generic TCP/IP checksum implementation requires approximately 10
CPU clocks per byte (as measured using the TSC). Improve this to
approximately 0.5 CPU clocks per byte by using "lodsl ; adcl" in an
unrolled loop.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Calculating the TCP/IP checksum on received packets accounts for a
substantial fraction of the response latency.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The "rep" prefix can be used with an iteration count of zero, which
allows the variable-length memcpy() to be implemented without using
any conditional jumps.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
PMM defines the return code 0xffffffff as meaning "unsupported
function". It's hard to imagine a PMM BIOS that doesn't support
pmmAllocate(), but apparently such things do exist.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
A .mrom image currently assumes that it is the first image within the
expansion ROM BAR, which may not be correct when multiple images are
present.
Fix by scanning through the BAR until we locate an image matching our
build ID.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The header of a .mrom image declares its length to be only a few
kilobytes; the remainder is accessed via a sideband mechanism. This
makes it difficult to append an additional ROM image, such as an EFI
ROM.
Add a second, dummy ROM header covering the payload portion of the
.mrom image, allowing consumers to locate any appended ROM images in
the usual way.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Avoid potential confusion in the documentation by using a
vendor-neutral name for the extended (AMD-defined) feature set.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The WinCE, a.out and FreeBSD loaders are designed to be #included by
core/loader.c, which no longer exists. These old loaders are not
usable anymore and cause compilation failures when enabled in
config/general.h.
Signed-off-by: Marin Hannache <mareo@mareo.fr>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Solaris assumes that there is enough space above the Multiboot modules
to use as a decompression and scratch area. This assumption is
invalid when using iPXE, which places the Multiboot modules near the
top of (32-bit) memory.
Fix by copying the modules to an area of memory immediately following
the loaded kernel.
Debugged-by: Michael Brown <mcb30@ipxe.org>
Debugged-by: Scott McWhirter <scottm@joyent.com>
Tested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow iPXE settings to be specified in the .vmx file via the VMware
GuestInfo mechanism. For example:
guestinfo.ipxe.filename = "http://boot.ipxe.org/demo/boot.php"
guestinfo.ipxe.dns = "192.168.0.1"
guestinfo.ipxe.net0.ip = "192.168.0.15"
guestinfo.ipxe.net0.netmask = "255.255.255.0"
guestinfo.ipxe.net0.gateway = "192.168.0.1"
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Solaris kernels seem to rely on having the full kernel path present in
the multiboot command line; if only the kernel name is present then
the boot fails with the error message
krtld: failed to open 'unix'
Debugged-by: Michael Brown <mcb30@ipxe.org>
Debugged-by: Scott McWhirter <scottm@joyent.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Using __from_text16() and __from_data16() in inline asm constraints
sometimes defeats gcc's ability to simplify expressions down to
compile-time constants.
Reported-by: Jason Kohles <jkohles@palantir.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
At present, we always hide an extra sizeof(struct external_memory), to
account for the header on the lowest allocated block. This header
ceases to exist when there are no allocated blocks remaining.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
An ANSI escape sequence context cannot be shared between multiple
users. Make the ANSI escape sequence context part of the line console
definition and provide individual contexts for each user.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The output from text-based user interfaces such as the "config"
command is not generally meaningful for logfile-based consoles such as
syslog and vmconsole.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add the concept of a "console usage", such as "standard output" or
"debug messages". Allow usages to be associated with each console
independently. For example, to send debugging output via the serial
port, while preventing it from appearing on the local console:
#define CONSOLE_SERIAL CONSOLE_USAGE_ALL
#define CONSOLE_PCBIOS ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_DEBUG )
If no usages are explicitly specified, then a default set of usages
will be applied. For example:
#define CONSOLE_SERIAL
will have the same affect as
#define CONSOLE_SERIAL CONSOLE_USAGE_ALL
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Remove the name, cmdline, and action parameters from imgdownload() and
imgdownload_string(). These functions now simply download and return
an image.
Add the function imgacquire(), which will interpret a "name or URI
string" parameter and return either an existing image or a newly
downloaded image.
Use imgacquire() to merge similar image-management commands that
currently differ only by whether they take the name of an existing
image or the URI of a new image to download. For example, "chain" and
"imgexec" can now be merged.
Extend imgstat and imgfree commands to take an optional list of
images.
Remove the arbitrary restriction on the length of image names.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
There is no INT 10 call for "display character with attribute,
advancing the cursor and scrolling the screen as necessary". We
therefore make two INT 10 calls: INT 10,09 to write the character with
its attribute at the current cursor position, and then INT 10,0e to
(re)write the character (leaving the attribute unchanged), advance the
cursor position and scroll as necessary.
This confuses the serial-over-LAN console redirection feature provided
by some BIOSes.
Fix by performing the INT10,09 only when necessary to change the
existing attribute.
Reported-by: Itay Gazit <itaygazit@gmail.com>
Tested-by: Itay Gazit <itaygazit@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
RSA requires modular exponentiation using arbitrarily large integers.
Given the sizes of the modulus and exponent, all required calculations
can be done without any further dynamic storage allocation. The x86
architecture allows for efficient large integer support via inline
assembly using the instructions that take advantage of the carry flag
(e.g. "adcl", "rcrl").
This implemention is approximately 80% smaller than the (more generic)
AXTLS implementation.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Minimise code size by forcing the use of memory addresses for
__bswap_16s() and __bswap_64s(). (__bswap_32s() cannot avoid loading the
value into a register.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Fix a strict-aliasing error on certain versions of gcc.
Reported-by: Marko Myllynen <myllynen@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use the "bswap" instruction to shrink the size of byte-swapping code,
and provide the in-place variants __bswap_{16,32,64}s.
"bswap" is available only on 486 and later processors. (We already
assume the presence of "cpuid" and "rdtsc", which are available only
on Pentium and later processors.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some PXE stacks (observed with a QLogic 8242) will always try to
prepend a link-layer header, even if the caller uses P_UNKNOWN to
indicate that the link-layer header has already been filled in. This
results in an invalid packet being transmitted.
Work around these faulty PXE stacks where possible by stripping the
existing link-layer header and allowing the PXE stack to (re)construct
the link-layer header itself.
Originally-fixed-by: Buck Huppmann <buckh@pobox.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The RTC-based entropy source uses the nanosecond-scale CPU TSC to
measure the time between two 1kHz interrupts generated by the CMOS
RTC. In a physical machine these clocks are driven from independent
crystals, resulting in some observable clock drift. In a virtual
machine, the CMOS RTC is typically emulated using host-OS
constructions such as SIGALRM.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
ANS X9.82 specifies several Approved Sources of Entropy Input (SEI).
One such SEI uses an entropy source as the Source of Entropy Input,
condensing each entropy source output after each GetEntropy call.
This can be implemented relatively cheaply in iPXE and avoids the need
to allocate potentially very large buffers.
(Note that the terms "entropy source" and "Source of Entropy Input"
are not synonyms within the context of ANS X9.82.)
Use the iPXE API mechanism to allow entropy sources to be selected at
compilation time.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
initrd_init() calls umalloc() to allocate space for the initrd image,
but does so before hide_etherboot() has been called. It is therefore
possible for the initrd to end up overwriting iPXE itself.
Fix by converting initrd_init() from an init_fn to a startup_fn.
Originally-fixed-by: Till Straumann <strauman@slac.stanford.edu>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The command line may be situated in an area of base memory that will
be overwritten by iPXE's real-mode segments, causing the command line
to be corrupted before it can be used.
Fix by creating a copy of the command line on the prefix stack (below
0x7c00) before installing the real-mode segments.
Reported-by: Dave Hansen <dave@sr71.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
PXENV_FILE_EXIT_HOOK is designed to allow ipxelinux.0 to unload both
the iPXE and pxelinux components without affecting the underlying PXE
stack. Unfortunately, it causes unexpected behaviour in other
situations, such as when loading a non-embedded pxelinux.0 via
undionly.kpxe. For example:
PXE ROM -> undionly.kpxe -> pxelinux.0 -> chain.c32 to boot hd0
would cause control to return to iPXE instead of booting from the hard
disk. In some cases, this would result in a harmless but confusing
"No more network devices" message; in other cases stranger things
would happen, such as being returned to the iPXE shell prompt.
The fundamental problem is that when pxelinux detects
PXENV_FILE_EXIT_HOOK, it may attempt to specify an exit hook and then
exit back to iPXE, assuming that iPXE will in turn exit cleanly via
the specified exit hook. This is not a valid assumption in the
general case, since the action of exiting back to iPXE does not
directly cause iPXE to exit itself. (In the specific case of
ipxelinux.0, this will work since the embedded script exits as soon as
pxelinux.0 exits.)
Fix the unexpected behaviour in the non-ipxelinux.0 cases by including
support for PXENV_FILE_EXIT_HOOK only when using a new .kkkpxe format.
The ipxelinux.0 build process should therefore now use undionly.kkkpxe
instead of undionly.kkpxe.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Very nasty things can happen if a NULL network device is used. Check
that pxe_netdev is non-NULL at the applicable entry points, so that
this type of problem gets reported to the caller rather than being
allowed to crash the system.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On at least one PXE stack (Realtek r8169), PXENV_UNDI_INITIALIZE has
been observed to fail intermittently due to a media test failure (PXE
error 0x00000061). Retrying the call to PXENV_UNDI_INITIALIZE
succeeds, and the NIC is then usable.
It is worth noting that this particular Realtek PXE stack is already
known to be unreliable: for example, it repeatably fails its own
boot-time media test after every warm reboot.
Fix by attempting PXENV_UNDI_INITIALIZE multiple times, with a short
delay between each attempt to allow the link to settle.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow an initrd (such as an embedded script) to be passed to iPXE when
loaded as a .lkrn (or .iso) image. This allows an embedded script to
be varied without recompiling iPXE.
Signed-off-by: Michael Brown <mcb30@ipxe.org>