[legal] Add mechanism for explicit per-file licence declarations
For partly historical reasons, various files in the gPXE source tree
are licensed under different, though compatible, terms. Most of the
code is licensed under GPLv2 with the "or later" clause, but there are
exceptions such as:
The string.h file, which derives from Linux and is licensed as
Public Domain.
The EFI header files, which are taken from the EDK2 source tree and
are licensed under BSD.
The 3c90x driver, which has a custom GPL-like licence text.
Introduce a FILE_LICENCE() macro to make licensing more explicit.
This macro should be applied exactly once to each source (.c, .S or
.h) file. It will cause a corresponding zero-sized common symbol to
be added to any .o files generated from that source file (and hence to
any final gPXE binaries generated from that source file). Determining
the applicable licences to generated files can then be done using e.g.
$ objdump -t bin/process.o | grep __licence
00000000 O *COM* 00000001 .hidden __licence_gpl2_or_later
indicating that bin/process.o is covered entirely by the GPLv2
with the "or later" clause, or
$ objdump -t bin/rtl8139.dsk.tmp | grep __licence
00033e8c g O .bss.textdata 00000000 .hidden __licence_gpl2_only
00033e8c g O .bss.textdata 00000000 .hidden __licence_gpl2_or_later
00033e8c g O .bss.textdata 00000000 .hidden __licence_public_domain
indicating that bin/rtl8139.dsk includes both code licensed under
GPLv2 (both with and without the "or later" clause) and code licensed
as Public Domain.
Determining the result of licence combinations is currently left as an
exercise for the reader.
The Mac compiler treats "#pragma pack()" as gcc's "#pragma pack(pop)",
and so dies if the pragma pack stack is empty. Adding a "#pragma
pack(1)" immediately beforehand is enough to keep the Mac compiler
happy.
The combination of "#pragma pack(1)", "#pragma pack()" won't actually
achieve anything on a Mac, but it will at least build. (With gcc, the
"#pragma pack()" overrides any previous pragmas, so is still useful.)
Suggested-by: Joshua Oreman <oremanj@rwcr.net>
[tables] Incorporate table data type information into table definition
Eliminate the potential for mismatches between table names and the
table entry data type by incorporating the data type into the
definition of the table, rather than specifying it explicitly in each
table accessor method.
[tables] Redefine methods for accessing linker tables
Intel's C compiler (icc) chokes on the zero-length arrays that we
currently use as part of the mechanism for accessing linker table
entries. Abstract away the zero-length arrays, to make a port to icc
easier.
Introduce macros such as for_each_table_entry() to simplify the common
case of iterating over all entries in a linker table.
Represent table names as #defined string constants rather than
unquoted literals; this avoids visual confusion between table names
and C variable or type names, and also allows us to force a
compilation error in the event of incorrect table names.
[settings] Allow for autovivification of settings blocks
Allow for settings blocks to be created on demand. This allows for
constructions such as
set defaults/filename http://bootserver/bootfile
set defaults/priority 0xff
dhcp net0
chain ${filename}
which will boot from the DHCP-provided filename, or from
"http://bootserver/bootfile" if the DHCP server does not provide a
filename.
(Note that "priority" gets interpreted as a signed integer, so setting
"defaults/priority" to 0xff will cause the "defaults" settings block
to have an effective priority of -1.)
Having a default script containing
#!gpxe
autoboot
can cause problems when entering commands to load and start a kernel
manually; the default script image will still be present when the
kernel is started and so will be treated as an initrd. It is possible
to work around this by typing "imgfree" before any other commands, but
this is counter-intuitive.
Fix by allowing the embedded image list to be empty (in which case we
just call autoboot()), and making this the default.
Reported by alkisg@gmail.com.
[iscsi] Include credentials in iBFT only if used during iSCSI login
Avoid passing credentials in the iBFT that were available but not
required for login. This works around a problem in the Microsoft
iSCSI initiator, which will refuse to initiate sessions if the CHAP
password is fewer than 12 characters, even if the target ends up not
asking for CHAP authentication.
[crypto] Change cipher_{en,de}crypt() to void functions
It is a programming error, not a runtime error, if we attempt to use
block ciphers with an incorrect blocksize, so use an assert() rather
than an error status return.
[crypto] Split crypto_algorithm into {digest,cipher,pubkey}_algorithm
The various types of cryptographic algorithm are fundamentally
different, and it was probably a mistake to try to handle them via a
single common type.
pubkey_algorithm is a placeholder type for now.
[pxeprefix] Add .kkpxe image type and ability to return via PXE stack
Certain combinations of PXE stack and BIOS result in a broken INT 18
call, which will leave the system displaying a "PRESS ANY KEY TO
REBOOT" message instead of proceeding to the next boot device. On
these systems, returning via the PXE stack is the only way to continue
to the next boot device. Returning via the PXE stack works only if we
haven't already blown away the PXE base code in pxeprefix.S.
In most circumstances, we do want to blow away the PXE base code.
Base memory is a limited resource, and it is desirable to reclaim as
much as possible. When we perform an iSCSI boot, we need to place the
iBFT above the 512kB mark, because otherwise it may not be detected by
the loaded OS; this may not be possible if the PXE base code is still
occupying that memory.
Introduce a new prefix type .kkpxe which will preserve both the PXE
base code and the UNDI driver (as compared to .kpxe, which preserves
the UNDI driver but uninstalls the PXE base code). This prefix type
can be used on systems that are known to experience the specific
problem of INT 18 being broken, or in builds (such as gpxelinux.0) for
which it is particularly important to know that returning to the BIOS
will work.
Written by H. Peter Anvin <hpa@zytor.com> and Stefan Hajnoczi
<stefanha@gmail.com>, minor structural alterations by Michael Brown
<mcb30@etherboot.org>.
[comboot] Allow for tail recursion of COMBOOT images
Multi-level menus via COMBOOT rely on the COMBOOT program being able
to exit and invoke a new COMBOOT program (the next menu). This works,
but rapidly (within about five iterations) runs out of space in gPXE's
internal stack, since each new image is executed in a new function
context.
Fix by allowing tail recursion between images; an image can now
specify a replacement image for itself, and image_exec() will perform
the necessary tail recursion.
This patch extends the embedded image feature to allow multiple
embedded images instead of just one.
gPXE now always boots the first embedded image on startup instead of
doing the hardcoded DHCP boot (aka autoboot).
Based heavily upon a patch by Stefan Hajnoczi <stefanha@gmail.com>.
[pxe] Obey lists of PXE Boot Servers and associated Discovery Control bits
Various combinations of options 43.6, 43.7 and 43.8 dictate which
servers we send Boot Server Discovery requests to, and which servers
we should accept responses from. Obey these options, and remove the
explicit specification of a single Boot Server from start_pxebs() and
dependent functions.
[iobuf] Add iob_disown() and use it where it simplifies code
There are many functions that take ownership of the I/O buffer they
are passed as a parameter. The caller should not retain a pointer to
the I/O buffer. Use iob_disown() to automatically nullify the
caller's pointer, e.g.:
xfer_deliver_iob ( xfer, iob_disown ( iobuf ) );
This will ensure that iobuf is set to NULL for any code after the call
to xfer_deliver_iob().
iob_disown() is currently used only in places where it simplifies the
code, by avoiding an extra line explicitly setting the I/O buffer
pointer to NULL. It should ideally be used with each call to any
function that takes ownership of an I/O buffer. (The SSA
optimisations will ensure that use of iob_disown() gets optimised away
in cases where the caller makes no further use of the I/O buffer
pointer anyway.)
If gcc ever introduces an __attribute__((free)), indicating that use
of a function argument after a function call should generate a
warning, then we should use this to identify all applicable function
call sites, and add iob_disown() as necessary.
The DHCP client code now implements only the mechanism of the DHCP and
PXE Boot Server protocols. Boot Server Discovery can be initiated
manually using the "pxebs" command. The menuing code is separated out
into a user-level function on a par with boot_root_path(), and is
entered in preference to a normal filename boot if the DHCP vendor
class is "PXEClient" and the PXE boot menu option exists.
Try to qualify relative names in the DNS resolver using the DHCP Domain
Name. For example:
DHCP Domain Name: etherboot.org
(Relative) Name: www
yields:
www.etherboot.org
Only names with no dots ('.') will be modified. A name with one or more
dots is unchanged.
PXE dictates a mechanism for boot menuing, involving prompting the
user with a variable message, waiting for a predefined keypress,
displaying a boot menu, and waiting for a selection.
This breaks the currently desirable abstraction that DHCP is a process
that can happen in the background without any user interaction.
[console] Allow KEY_xxx constants to cover F8 function key
F8 is represented by the ANSI escape sequence "^[[19~", which is not
representable as a KEY_xxx constant using the current encoding scheme.
Adapt the encoding scheme to allow F8 to be represented, since PXE
requires that we may need to prompt the user to press F8.
Remove the lazy assumption that ProxyDHCP == "DHCP with option 60 set
to PXEClient", and explicitly separate the notion of ProxyDHCP from
the notion of packets containing PXE options.
Pick out the first boot menu item from the boot menu (option 43.9) and
pass it to the boot server as the boot menu item (option 43.71).
Also improve DHCP debug messages to include more details of the
packets being transmitted.
[dhcp] Add preliminary support for PXE Boot Servers
Some PXE configurations require us to perform a third DHCP transaction
(in addition to the real DHCP transaction and the ProxyDHCP
transaction) in order to retrieve information from a "Boot Server".
This is an experimental implementation, since the actual behaviour is
not well specified in the PXE spec.
[tcpip] Allow for transmission to multicast IPv4 addresses
When sending to a multicast address, it may be necessary to specify
the source address explicitly, since the multicast destination address
does not provide enough information to deduce the source address via
the miniroute table.
Allow the source address specified via the data-xfer metadata to be
passed down through the TCP/IP stack to the IPv4 layer, which can use
it as a default source address.
[efi] Provide component name protocol and device path protocol interfaces
Include a minimal component name protocol so that the driver name
shows up as something other than "<UNKNOWN>" in the driver list, and a
device path protocol so that the network interface shows up as a
separate device in the device list, rather than being attached
directly to the PCI device.
Incidentally, the EFI component name protocol reaches new depths for
signal-to-noise ratio in program code. A typical instance within the
EFI development kit will use an additional 300 lines of code to
provide slightly less functionality than GNU gettext achieves with
three additional characters.
elf2efi converts a suitable ELF executable (containing relocation
information, and with appropriate virtual addresses) into an EFI
executable. It is less tightly coupled with the gPXE build process
and, in particular, does not require the use of a hand-crafted PE
image header in efiprefix.S.
elf2efi correctly handles .bss sections, which significantly reduces
the size of the gPXE EFI executable.