Add support for building iPXE as a 64-bit or 32-bit RISC-V binary, for
either UEFI or Linux userspace platforms. For example:
# RISC-V 64-bit UEFI
make CROSS=riscv64-linux-gnu- bin-riscv64-efi/ipxe.efi
# RISC-V 32-bit UEFI
make CROSS=riscv64-linux-gnu- bin-riscv32-efi/ipxe.efi
# RISC-V 64-bit Linux
make CROSS=riscv64-linux-gnu- bin-riscv64-linux/tests.linux
qemu-riscv64 -L /usr/riscv64-linux-gnu/sys-root \
./bin-riscv64-linux/tests.linux
# RISC-V 32-bit Linux
make CROSS=riscv64-linux-gnu- SYSROOT=/usr/riscv32-linux-gnu/sys-root \
bin-riscv32-linux/tests.linux
qemu-riscv32 -L /usr/riscv32-linux-gnu/sys-root \
./bin-riscv32-linux/tests.linux
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Several new relocations types have been added in LoongArch ABI version
2.10. In particular:
- R_LARCH_B16 (18-bit PC-relative jump)
- R_LARCH_B21 (23-bit PC-relative jump)
- R_LARCH_PCREL20_S2 (22-bit PC-relative offset)
Also relocation relaxations have been introduced. Recent GCC (13.2)
and binutils 2.41+ use these types of relocations, which confuses
elf2efi tool. As a result, iPXE EFI images for LoongArch fail to
build with the following error:
Unrecognised relocation type 103
Fix by ignoring R_LARCH_B{16,21} and R_LARCH_PCREL20_S2 (as with other
PC-relative relocations), and by ignoring relaxations (R_LARCH_RELAX).
Relocation relaxations are basically optimizations: ignoring them
results in a correct binary (although it might be suboptimal).
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add definitions for relocation types that may be missing on older
versions of the host system's elf.h.
This mirrors wimboot commit 47f6298 ("[efi] Add potentially missing
relocation types").
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The result of multiplying a uint16_t by another uint16_t will be a
signed int. Comparing this against a size_t will perform an unwanted
sign extension.
Fix by explicitly casting e_phnum to an unsigned int, thereby matching
the data type used for the loop index variable (and avoiding the
unwanted sign extension).
This mirrors wimboot commit 15f6162 ("[efi] Fix Coverity warning about
unintended sign extension").
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add additional PC-relative relocation types that may be encountered
when converting binaries compiled with clang.
This mirrors the relevant elf2efi portions of wimboot commit 7910830
("[build] Support building with the clang compiler").
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The clang compiler does not (and apparently will not ever) allow for
variable-length arrays within structs.
Work around this limitation by using a fixed-length array to hold the
PDB filename in the debug section.
This mirrors wimboot commit f52c3ff ("[efi] Allow compiling elf2efi
with clang").
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Hybrid bzImage and UEFI binaries (such as wimboot) may place sections
at explicit offsets within the PE file, as described in commit b30a098
("[efi] Use load memory address as file offset for hybrid binaries").
This can leave a gap after the PE headers that is not covered by any
section. It is not entirely clear whether or not such gaps are
permitted in binaries submitted for Secure Boot signing.
To minimise potential problems, extend the PE header size to cover any
space before the first explicitly placed section.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
iPXE images are linked with a starting virtual address of zero. Other
images (such as wimboot) may use a non-zero starting virtual address.
There is no direct equivalent of the PE ImageBase address field within
ELF object files. Choose to use the highest possible address that
accommodates all sections and the PE header itself, since this will
minimise the memory allocated to hold the loaded image.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The BaseOfCode (and, in PE32, BaseOfData) fields imply an assumption
that binaries are laid out as code followed by initialised data
followed by uninitialised data. This assumption may not be valid for
complex binaries such as wimboot.
Remove this implicit assumption, and use arguably justifiable values
for the assorted summary start and size fields within the PE headers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Hybrid bzImage and UEFI binaries (such as wimboot) may include 16-bit
sections such as .bss16 that do not need to consume an entry in the PE
section list. Treat any such sections as hidden.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The PE debug information generated by elf2efi is used only to hold the
image filename, and the debug information is located via the relevant
data directory entry rather than via the section table.
Make the .debug section a hidden section in order to save one entry in
the PE section list. Choose to place the debug information in the
unused space at the end of the PE headers, since it no longer needs to
satisfy the general section alignment constraints.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 1e4c378 ("[efi] Shrink size of data directory in PE header")
reduced the number of entries used in the data directory and reduced
the recorded size of the NT "optional" header, but did not also adjust
the recorded overall size of the PE headers, resulting in unused space
between the PE headers and the first section.
Fix by reducing the initial recorded size of the PE headers by the
size of the omitted data directory entries.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Hybrid bzImage and UEFI binaries (such as wimboot) include a bzImage
header within a section starting at offset zero, with the PE header
effectively occupying unused space within this section.
Allow for this by treating a section placed at offset zero as hidden,
and by deferring the writing of the PE header until after the output
sections have been written.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Hybrid bzImage and UEFI binaries (such as wimboot) may be loaded as a
single contiguous blob without reference to the PE headers, and the
placement of sections within the PE file must therefore be known at
link time.
Use the load memory address (extracted from the ELF program headers)
to determine the physical placement of the section within the PE file
when generating a hybrid binary.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The images generated by elf2efi can be loaded anywhere in the address
space, and are not limited to the low 2GB.
Indicate this by setting the "large address aware" flag within the PE
header, for compatibility with EFI images generated by the EDK2 build
process. (The EDK2 PE loader does not ever check this flag, and it is
unlikely that any other EFI PE loader ever does so, but we may as well
report it accurately.)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Indicate that the binary is compatible with W^X protections by setting
the NXCOMPAT bit in the DllCharacteristics field of the PE header.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Hybrid bzImage and UEFI binaries (such as wimboot) may include 16-bit
executable code that is opaque data from the perspective of a UEFI PE
binary, as described in wimboot commit fe456ca ("[efi] Use separate
.text and .data PE sections").
The ELF section will be marked as containing both executable code and
writable data. Choose to treat such a section as a data section
rather than a code section, since that matches the expected semantics
for ELF files that we expect to process.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Hybrid bzImage and UEFI binaries (such as wimboot) include a bzImage
header within a section starting at offset zero, with the PE header
effectively occupying unused space within this section. This section
should not appear as a named section in the resulting PE file.
Allow for the existence of hidden sections that do not result in a
section header being written to the PE file.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Hybrid 32-bit BIOS and 64-bit UEFI binaries (such as wimboot) may
include R_X86_64_32 relocation records for the 32-bit BIOS portions.
These should be ignored when generating PE relocation records, since
they apply only to code that cannot be executed within the context of
the 64-bit UEFI binary, and creating a 4-byte relocation record is
invalid in a binary that may be relocated anywhere within the 64-bit
address space (see commit 907cffb "[efi] Disallow R_X86_64_32
relocations").
Add a "--hybrid" option to elf2efi, which will cause R_X86_64_32
relocation records to be silently discarded.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Hybrid bzImage and UEFI binaries (such as wimboot) require the PE
header to be kept as small as possible, since the bzImage header
starts at a fixed offset 0x1f1.
The EFI_IMAGE_OPTIONAL_HEADER structures in PeImage.h define an
optional header containing 16 data directory entries, of which the
last eight are unused in binaries that we create. Shrink the data
directory to contain only the first eight entries, to minimise the
overall size of the PE header.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Hybrid bzImage and UEFI binaries (such as wimboot) require the PE
header to be kept as small as possible, since the bzImage header
starts at a fixed offset 0x1f1.
The PE header currently includes 128 bytes of zero padding between the
DOS and NT header portions. This padding has been present since
commit 81d92c6 ("[efi] Add EFI image format and basic runtime
environment") first added support for EFI images in iPXE, and was
included on the basis of matching the observed behaviour of the
Microsoft toolchain. There appears to be no requirement for this
padding to exist: EDK2 binaries built with gcc include only 64 bytes
of zero padding, Linux kernel binaries include 66 bytes of non-zero
padding, and wimboot binaries include no padding at all.
Remove the unnecessary padding between the DOS and NT header portions
to minimise the overall size of the PE header.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As with util/elf2efi32 and util/elf2efi64 in commit a99e435 ("[efi] Do
not rely on ProcessorBind.h when building host binaries"), build
util/efirom without using any architecture-specific EDK2 headers since
the build host's CPU architecture may not be supported by EDK2.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
We cannot rely on the EDK2 ProcessorBind.h headers when compiling a
binary for execution on the build host itself (e.g. elf2efi), since
the host's CPU architecture may not even be supported by EDK2.
Fix by skipping ProcessorBind.h when building a host binary, and
defining the bare minimum required to allow other EDK2 headers to
compile cleanly.
Reported-by: Michal Suchánek <msuchanek@suse.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The BIOS console's interpretation of LShift+RShift as equivalent to
AltGr requires the shifted ASCII characters to be present in the AltGr
mapping table, to allow AltGr-Shift-<key> to be interpreted in the
same way as AltGr-<key>.
For keyboard layouts that have different ASCII characters for
AltGr-<key> and AltGr-Shift-<key>, this will potentially leave the
character for AltGr-<key> inaccessible via the BIOS console if the
BIOS requires the use of the LShift+RShift workaround. This
theoretically affects the numeric keys in the Lithuanian ("lt")
keyboard layout (where the numerals are accessed via AltGr-<key> and
punctuation characters via AltGr-Shift-<key>), but the simple
workaround for that keyboard layout is to avoid using AltGr and Shift
entirely since the unmodified numeric keys are not remapped anyway.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The AltGr remapping table is constructed to include only keys that are
not reachable after applying the basic remapping table. The logic
currently fails to include keys that are omitted entirely from the
basic remapping table since they would map to a non-ASCII character.
Fix this logic by allowing the remapping tables to include null
mappings, which are then elided only at the point of constructing the
C code fragment.
Reported-by: Christian Nilsson <nikize@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Treat dead keys in target keymaps as producing the closest equivalent
ASCII character, since many of these characters are otherwise
unrepresented on the keyboard.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Several keyboard layouts define ASCII characters as accessible only
via the AltGr modifier. Add support for this modifier to ensure that
all ASCII characters are accessible.
Experiments suggest that the BIOS console is likely to fail to
generate ASCII characters when the AltGr key is pressed. Work around
this limitation by accepting LShift+RShift (which will definitely
produce an ASCII character) as a synonym for AltGr.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Separate the concept of a keyboard mapping from a list of remapped
keys, to allow for the possibility of supporting multiple keyboard
mappings at runtime.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The key with scancode 86 appears in the position between left shift
and Z on a US keyboard, where it typically fails to exist entirely.
Most US keyboard maps define this nonexistent key as generating "\|",
with the notable exception of "loadkeys" which instead reports it as
generating "<>". Both of these mapping choices duplicate keys that
exist elsewhere in the map, which causes problems for our ASCII-based
remapping mechanism.
Work around these quirks by treating the key as generating "\|" with
the high bit set, and making it subject to remapping. Where the BIOS
generates "\|" as expected, this allows us to remap to the correct
ASCII value.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Rewrite genkeymap.pl in Python with added sanity checks, and update
the list of keyboard mappings to remove those no longer supported by
the underlying "loadkeys" tool.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As of commit f1e9e2b ("[efi] Align EFI image sections by page size"),
the VirtualSize fields for the .reloc and .debug sections have been
rounded up to the (4kB) image alignment. This breaks the PE
relocation logic in the UEFI shim, which requires the VirtualSize
field to exactly match the size as recorded in the data directory.
Fix by setting the VirtualSize field to the unaligned size of the
section, as is already done for normal PE sections (i.e. those other
than .reloc and .debug).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add the "--uefi" option when invoking isohybrid on an EFI-bootable
image, to create a partition mapping to the EFI system partition
embedded within the ISO image.
This allows the resulting isohybrid image to be booted on UEFI systems
that will not recognise an El Torito boot catalog on a non-CDROM
device.
Originally-fixed-by: Christian Hesse <mail@eworm.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As of commit f1e9e2b ("[efi] Align EFI image sections by page size"),
our SectionAlignment has been increased to 4kB in order to allow for
page-level memory protection to be applied by the UEFI firmware, with
FileAlignment left at 32 bytes.
The PE specification states that the value for FileAlignment "should
be a power of 2 between 512 and 64k, inclusive", and that "if the
SectionAlignment is less than the architecture's page size, then
FileAlignment must match SectionAlignment".
Testing shows that signtool.exe will reject binaries where
FileAlignment is less than 512, unless FileAlignment is equal to
SectionAlignment. This indicates a somewhat zealous interpretation of
the word "should" in the PE specification.
Work around this interpretation by increasing FileAlignment from 32
bytes to 512 bytes, and add explanatory comments for both
FileAlignment and SectionAlignment.
Debugged-by: Andreas Hammarskjöld <junior@2PintSoftware.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit 79c0173 ("[build] Create util/genfsimg for building
filesystem-based images") introduced the new genfsimg, which lacks the
-l option when building ISO files. This option is required to build
level 2 (long plain) ISO9660 filenames, which are required when using
the .lkrn extensions on older versions of ISOLINUX.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
After a PE image is fully loaded and relocated, the loader code may
opt to zero discardable sections for security reasons. This includes
relocation and debug information, as both contain hints about specific
locations within the binary. Mark both generated sections as
discardable, which follows the PE specification.
Signed-off-by: Marvin Häuser <mhaeuser@posteo.de>
For optimal memory permission management, PE sections need to be
aligned by the platform's minimum page size. Currently, the PE
section alignment is fixed to 32 bytes, which is below the typical 4kB
page size. Align all sections to 4kB and adjust ELF to PE image
conversion accordingly.
Signed-off-by: Marvin Häuser <mhaeuser@posteo.de>
Use the reference implementation of the EFI compression algorithm
(taken from the EDK2 codebase, with minor bugfixes to allow
compilation with -Werror) to compress EFI ROM images.
Inspired-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Support for building with the Intel C compiler (icc) was added in 2009
in the expectation that UEFI support would eventually involve
compiling iPXE to EFI Byte Code.
EFI Byte Code has never found any widespread use: no widely available
compilers can emit it, Microsoft refuses to sign EFI Byte Code
binaries for UEFI Secure Boot, and I have personally never encountered
any examples of EFI Byte Code in the wild.
The support for using the Intel C compiler has not been tested in over
a decade, and would almost certainly require modification to work with
current releases of the compiler.
Simplify the build process by removing this old legacy code.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
As of commit 7c3d186 ("[build] Check that mkisofs equivalent supports
the required options"), we may refuse to use a mkisofs equivalent if
it does not support the options required to produce the requested
output file.
This can result in confusing error messages since the user is unaware
of the reason for which the installed mkisofs or genisoimage has been
rejected.
Fix by explicitly reporting the reason why each possible mkisofs
equivalent could not be used.
Signed-off-by: Michael Brown <mcb30@ipxe.org>