The "inc" command allows the numeric value of a setting to be
incremented, allowing for the construction of simple loops within an
iPXE script.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow commands to be placed on the same line as a label. This allows
for improved legibility of loop constructions by incorporating the
loop check condition into the same line as the loop label. For
example, to iterate over network devices using the forthcoming "inc"
command:
set idx:int16 0
:loop isset ${net${idx}/mac} || goto loop_done
echo net${idx} is a ${net${idx}/chip} with MAC ${net${idx}/mac}
inc idx && goto loop
:loop_done
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Initial whitespace is already accepted on lines containing commands,
since it gets ignored by the system() call. Minimise surprise and
allow for neater indentation of scripts by also allowing whitespace on
lines containing labels.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
A deliberate side effect of this commit is that the "read" command
will now preserve the type of the setting, if the setting name
contains no type information. For example:
iPXE> set foo:ipv4 192.168.0.1
iPXE> read foo
192.168.0.100
iPXE> show foo
foo:ipv4 = 192.168.0.100
rather than the arguably unexpected behaviour of resetting the type to
"string".
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use parse_setting_name() and fetchf_setting_copy() in
expand_settings(), to eliminate the call to fetchf_named_setting().
This change also eliminates the potentially large stack-allocated
buffer in expand_settings().
Signed-off-by: Michael Brown <mcb30@ipxe.org>
fetch_settings_copy() currently returns success and a NULL data
pointer to indicate a non-existent setting. This is intended to allow
the caller to differentiate between a non-existent setting and an
error in allocating memory for the copy of the setting.
The underlying settings blocks' fetch() methods provide no way to
perform an existence check separate from an attempt to fetch the
setting. A "non-existent setting" therefore means simply a setting
for which an error was encountered when attempting to fetch from every
settings block within the subtree.
Since any underlying error within a settings block (e.g. a GuestRPC
failure when attempting to retrieve a VMware GuestInfo setting) will
produce the effect of a "non-existent setting", it seems somewhat
meaningless to give special treatment to memory allocation errors
within fetch_setting_copy().
Remove the special treatment and simplify the semantics of
fetch_setting_copy() by directly passing through any underlying error
(including non-existence) encountered while fetching the setting.
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>
The getopt API defines optind as a global variable. When used by the
"autoboot" command, the payload function passed to ifcommon_exec() may
result in a new iPXE script being executed; the commands therein would
then overwrite the value of optind. On returning, ifcommon_exec()
would continue processing the list of interfaces from an undefined
point.
Fix by using a local variable to hold the index within the list of
interfaces.
Reported-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some hardware (observed with an onboard RTL8168) will erroneously
report a buffer overflow error if the received packet exactly fills
the receive buffer.
Fix by adding an extra four bytes of padding to each receive buffer.
Debugged-by: Thomas Miletich <thomas.miletich@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add support for page up, page down, home and end keys, matching the
navigation logic used in the menu user interface.
Originally-implemented-by: Marin Hannache <git@mareo.fr>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Adrian Jamróz <adrian.jamroz@gmail.com>
Modified-by: Thomas Miletich <thomas.miletich@gmail.com>
Signed-off-by: Thomas Miletich <thomas.miletich@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow long script lines to be broken up using backslash continuation.
For example:
choose --default linux --timeout 3000 os \
&& goto boot_${os} || goto cancelled
Requested-by: Robin Smidsrød <robin@smidsrod.no>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
base16_encode() will fail to generate a terminating NUL if the length
of the raw data is zero, since the loop calling sprintf() will never
execute.
Fix by explicitly terminating the result with a NUL.
Reported-by: Marin Hannache <git@mareo.fr>
Debugged-by: Marin Hannache <git@mareo.fr>
Tested-by: Marin Hannache <git@mareo.fr>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Replace the old via-rhine driver with a new version using the iPXE
API.
Includes fixes by Thomas Miletich for:
- MMIO access
- Link detection
- RX completion in RX overflow case
- Reset and EEPROM reloading
- CRC stripping
- Missing cpu_to_le32() calls
- Missing memory barriers
Signed-off-by: Adrian Jamróz <adrian.jamroz@gmail.com>
Modified-by: Thomas Miletich <thomas.miletich@gmail.com>
Tested-by: Thomas Miletich <thomas.miletich@gmail.com>
Tested-by: Robin Smidsrød <robin@smidsrod.no>
Modified-by: Michael Brown <mcb30@ipxe.org>
Tested-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Include a sequence number as the first four bytes of the loopback test
packet payload. When a content mismatch occurs, this gives some
information about the source of the mismatched packet.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow any iPXE command expecting a network device name to accept
"netX" as a synonym for "most recently opened network device".
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add a facility for settings blocks to act as symbolic links to other
settings blocks, and reimplement the "netX" virtual settings block
using this facility.
The primary advantage of this approach is that unscoped settings such
as ${mac} and ${filename} will now reflect the settings obtained from
the most recently opened network device: in most cases, this will mean
the settings obtained from the most recent DHCP attempt. This should
improve conformance to the principle of least astonishment.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow values to be read from PCI configuration space using the syntax
${pci/<busdevfn>.<offset>.<length>}
where <busdevfn> is the bus:dev.fn address of the PCI device
(expressed as a single integer, as returned by ${net0/busloc}),
<offset> is the offset within PCI configuration space, and <length> is
the length within PCI configuration space.
Values are returned in reverse byte order, since PCI configuration
space is little-endian by definition.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Move VMWARE_SETTINGS build configuration option from config/sideband.h
to a new config/settings.h.
Existing instances of config/local/sideband.h will not be affected,
since config.c still #includes config/sideband.h.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow network device's "busloc" setting to be formatted as a PCI
bus:dev.fn address using e.g. ${net0/busloc:busdevfn}.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use hex_decode() to parse "hex" and "hexhyp" settings. Note that this
parser is stricter than the old parser; it now requires exactly two
hex digits for each byte. (The old parser was based upon strtoul()
and so would allow leading whitespace and a leading plus or minus
sign.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Provide a generic hex_decode() routine which can be shared between the
Base16 code and the "hex" and "hexhyp" settings parsers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On large networks with substantial numbers of monitoring agents,
unwanted TCP connection attempts may end up flooding iPXE's ARP cache.
Fix by silently dropping packets received for unrecognised TCP
connections. This should not cause problems, since many firewalls
will also silently drop any such packets.
Reported-by: Jarrod Johnson <jarrod.b.johnson@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Locate the settings block containing the filename, and search only
that settings block for the next-server address. This avoids problems
caused by misconfigured DHCP servers which provide a next-server
address (often defaulting to the DHCP server's own IP address) even
when not providing a filename.
Originally-implemented-by: Alex Williamson <alex.williamson@redhat.com>
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>
RFC2560 mandates that a valid OCSP response will contain exactly one
relevant certificate. However, some OCSP responders include
extraneous certificates. iPXE currently assumes that the first
certificate in the OCSP response is the relevant certificate; OCSP
checks will therefore fail if the responder includes the extraneous
certificates before the relevant certificate.
Fix by using the responder ID to identify the relevant certificate.
Reported-by: Christian Stroehmeier <stroemi@mail.uni-paderborn.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
realtek_destroy_ring() currently does nothing if the card is operating
in legacy (pre-RTL8139C+) mode. In particular, the producer and
consumer counters are incorrectly left holding their current values.
Virtual hardware (e.g. the emulated RTL8139 in qemu and similar VMs)
is tolerant of this behaviour, but real hardware will fail to transmit
if the descriptors are not used in the correct order.
Fix by resetting the producer and consumer counters in
realtek_destroy_ring() even if the card is operating in legacy mode.
Reported-by: Gelip <mrgelip@gmail.com>
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>
If a certificate chain contains no certificate which can be validated
as a standalone certificate (i.e. contains no trusted root
certificates or previously-validated certificates) then iPXE will
currently return a fixed error EACCES_UNTRUSTED. This masks the
actual errors obtained when attempting to validate each certificate as
a standalone certificate, and so makes troubleshooting difficult for
the end user.
Fix by instead returning the error obtained when attempting to
validate the final certificate in the chain as a standalone
certificate. This error is most likely (though not guaranteed) to
represent the "real" problem.
Reported-by: Sven Dreyer <sven@dreyer-net.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Extend the syntax for numerical SMBIOS settings from
smbios/<type>.<offset>.<length>
to
smbios/[<instance>.]<type>.<offset>.<length>
Where SMBIOS provides multiple structures with the same <type>, this
extended syntax allows for access to structures other than the first.
If <instance> is omitted then it will default to zero, giving access
to the first instance (and so matching existing behaviour).
The 16-bit SMBIOS handle (which is an alternative way to disambiguate
multiple instances of the same type of structure) can be accessed, if
required, using
smbios/<instance>.<type>.2.2:uint16
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE allows access to general SMBIOS settings using the syntax:
smbios/<type>.<offset>.<length>
This provides access to any fixed-offset field within an SMBIOS
structure. This syntax is currently overloaded to interpret a zero
<length> as meaning that the byte at <offset> contains a string index;
this provides access to SMBIOS strings (which are not located at fixed
offsets).
The "OEM Strings" SMBIOS structure contains strings which are not
referenced by any fixed string index field within the structure. iPXE
currently provides no way to access these strings.
Fix by overloading the syntax for numerical SMBIOS settings to
interpret an <offset> of zero as implying that <length> contains a
literal string index. The OEM Strings can then be accessed using:
smbios/11.0.1
smbios/11.0.2
smbios/11.0.3
...
The actual byte at offset zero will always contain the structure type,
which is already known since it must be specified in order to access
the structure. There is thus no plausible existing use case for an
offset of zero; overloading the syntax in this way should therefore
not break compatibility with any existing scripts.
The corner case where both <offset> and <length> are zero is undefined
(and, for now, will simply return a "not found" error).
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>
Devices with small transmit descriptor rings may temporarily run out
of space. Provide netdev_tx_defer() to allow drivers to defer packets
for retransmission as soon as a descriptor becomes available.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
On some systems, it appears to be possible for writes to the EEPROM
registers to be delayed for long enough that the EEPROM's setup and
hold times are violated, resulting in invalid data being read from the
EEPROM.
Fix by inserting a PCI read cycle immediately after writes to
RTL_9346CR, to ensure that the write has completed before starting the
udelay() used to time the SPI bus transitions.
Reported-by: Gelip <mrgelip@gmail.com>
Tested-by: Gelip <mrgelip@gmail.com>
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>
Some older RTL8139 chips seem to not immediately update the
RTL_CR.BUFE bit in response to a write to RTL_CAPR. This results in
iPXE seeing a spurious zero-length received packet, and thereafter
being out of sync with the hardware's RX ring offset.
Fix by inserting an extra PCI read cycle after writing to RTL_CAPR, to
give the chip time to react before we next read RTL_CR.
Reported-by: Gelip <mrgelip@gmail.com>
Tested-by: Gelip <mrgelip@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Some onboard RTL8169 NICs seem to leave the EEPROM pins disconnected.
The existing is_valid_ether_addr() test will not necessarily catch
this, since it expects a missing EEPROM to show up as a MAC address of
00:00:00:00:00:00 or ff:ff:ff:ff:ff:ff. When the EEPROM pins are
floating the MAC address may read as e.g. 00:00:00:00:0f:00, which
will not be detected as invalid.
Check the ID word in the first two bytes of the EEPROM (which should
have the value 0x8129 for all RTL8139 and RTL8169 chips), and use this
to determine whether or not an EEPROM is present.
Reported-by: Carl Karsten <carl@nextdayvideo.com>
Tested-by: Carl Karsten <carl@nextdayvideo.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
sparse does not understand -fshort-wchar. Default to using uint16_t
as a wchar_t if not explicitly specified by the compiler, to avoid
large numbers of spurious warnings from sparse.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Linker table entries must be non-static in order to avoid being
completely optimised away by some versions of gcc. Use -Wno-decl to
prevent sparse from warning about these, since the alternative would
be to litter the code with otherwise unnecessary "extern"
declarations.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
sparse does not define __WCHAR_TYPE__ or __WINT_TYPE__. We already
define __WCHAR_TYPE__ if the compiler does not do so; do the same for
__WINT_TYPE__.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
sparse seems to have problems finding compiler.h when specified as
"-include compiler.h"; one possible explanation is that it ignores the
include path. Fix by using "-include include/compiler.h".
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE currently seeds the random number generator using the system
timer tick count. When large numbers of machines are booted
simultaneously, multiple machines may end up choosing the same DHCP
transaction ID (XID) value; this can cause problems.
Fix by using the least significant (and hence most variable) bits of
each network device's link-layer address to perturb the random number
generator. This introduces some per-machine unique data into the
random number generator's seed, and so reduces the chances of DHCP XID
collisions.
This does not affect the ANS X9.82-compatible random bit generator
used by TLS and other cryptography code, which uses an entirely
separate source of entropy.
Originally-implemented-by: Bernhard Kohl <bernhard.kohl@nsn.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add disambiguated errors for LoadImage() and StartImage(), primarily
to demonstrate how to use __einfo_uniqify() and __einfo_platformify()
in the context of EFI platform errors.
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 Intel 10 Gigabit NICs have a datapath that is almost
register-compatible with the Intel 1 Gigabit NICs. Expose common
functionality to avoid duplication of code in the new "intelx" driver.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The Intel 10 Gigabit NICs use the same simplified (aka "legacy")
descriptor format and the same layout for descriptor register blocks
as the Intel 1 Gigabit NICs. The offsets of the descriptor register
blocks are not the same.
Simplify reuse of the existing code by removing all hardcoded offsets
for registers within descriptor register blocks, and ensuring that all
offsets are calculated using the descriptor register block base
address provided via intel_init_ring().
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>