Even though we build with -mno-plt, redundant .got and .got.plt
sections are still generated.
Include these redundant sections within .data (which has identical
section attributes) to simplify the section list.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The ELF hash table is generated when building a position-independent
executable even though it is not required (since we have no dynamic
linker).
Explicitly discard these unneeded sections.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Parsing ELF data is simpler if we don't have to build a single binary
to handle both 32-bit and 64-bit ELF formats.
Allow for separate 32-bit and 64-bit binaries built from util/zbin.c
(as is already done for util/elf2efi.c).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Add code to construct a 32-bit page table to map the whole of the
32-bit address space with a fixed offset selected to map iPXE itself
at its link-time address, and to return with paging enabled and the
program counter updated to a virtual address.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Paging provides an alternative to using relocations: instead of
applying relocation fixups to the runtime addresses, we can set up
virtual addressing so that the runtime addresses match the link-time
addresses.
This opens up the possibility of running portions of iPXE directly
from read-only memory (such as a memory-mapped flash device), subject
to the caveats that .data is not yet writable and .bss is not yet
zeroed. This should allow us to run enough code to parse the memory
map from the FDT, identify a suitable RAM block, and physically
relocate ourselves there.
Add code to construct a 64-bit page table (in a single 4kB buffer) to
identity-map as much of the physical address space as possible, to map
iPXE itself at its link-time address, and to return with paging
enabled and the program counter updated to a virtual address. We use
the highest paging level supported by the CPU, to maximise the amount
of the physical address space covered by the identity map.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Using paging (rather than relocation records) will be easier on 64-bit
RISC-V if we place iPXE within the negative (kernel) virtual address
space.
Allow the link-time address to be non-zero and to vary between 32-bit
and 64-bit builds. Choose addresses that are expected to be amenable
to the use of paging.
There is no particular need to use a non-zero address in the 32-bit
builds, but doing so allows us to validate that the relocation code is
handling this case correctly.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Split out the runtime relocation logic from sbiprefix.S to a new
library libprefix.S.
Since this logically decouples the process of runtime relocation from
the _sbi_start symbol (currently used to determine the base address
for applying relocations), provide an alternative mechanism for the
relocator to determine the base address.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Remove the last remaining traces of the concept of a user pointer,
leaving iPXE with a simpler and cleaner memory model that implicitly
assumes that all memory locations can be reached through pointer
dereferences.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The uaccess.h header is no longer required for any code that touches
external ("user") memory, since such memory accesses are now performed
through pointer dereferences. Reduce the number of files including
this header.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Almost all image consumers do not need to modify the content of the
image. Now that the image data is a pointer type (rather than the
opaque userptr_t type), we can rely on the compiler to enforce this at
build time.
Change the .data field to be a const pointer, so that the compiler can
verify that image consumers do not modify the image content. Provide
a transparent .rwdata field for consumers who have a legitimate (and
now explicit) reason to modify the image content.
We do not attempt to impose any runtime restriction on checking
whether or not an image is writable. The only existing instances of
genuinely read-only images are the various unit test images, and it is
acceptable for defective test cases to result in a segfault rather
than a runtime error.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Not all images are allocated via alloc_image(). For example: embedded
images, the static images created to hold a runtime command line, and
the images used by unit tests are all static structures.
Using image_set_cmdline() (via e.g. the "imgargs" command) to set the
command-line arguments of a static image will succeed but will leak
memory, since nothing will ever free the allocated command line.
There are no code paths that can lead to calling image_set_len() on a
static image, but there is no safety check against future code paths
attempting this.
Define a flag IMAGE_STATIC to mark an image as statically allocated,
generalise free_image() to also handle freeing dynamically allocated
portions of static images (such as the command line), and expose
free_image() for use by static images.
Define a related flag IMAGE_STATIC_NAME to mark the name as statically
allocated. Allow a statically allocated name to be replaced with a
dynamically allocated name since this is a potentially valid use case
(e.g. if "imgdecrypt --name <name>" is used on an embedded image).
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Simplify cmdline_init() by assuming that the externally provided
command line is directly accessible via pointer dereferences.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Simplify bzImage parsing by assuming that the various headers are
directly accessible via pointer dereferences.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Commit ef03849 ("[uaccess] Remove redundant userptr_add() and
userptr_diff()") exposed a signedness bug in the comparison of initrd
locations, since the expression (initrd->data - current) was
effectively no longer coerced to a signed type.
In particular, the common case will be that the top of the initrd
region is the start of the iPXE .textdata region, which has virtual
address zero. This causes initrd->data to compare as being above the
top of the initrd region for all images, when this bug would
previously have been limited to affecting only initrds placed 2GB or
more below the start of .textdata.
Fix by using physical addresses for all comparisons on initrd
locations.
Reported-by: Sven Dreyer <sven@dreyer-net.de>
Reported-by: Harald Jensås <hjensas@redhat.com>
Reported-by: Jan ONDREJ (SAL) <ondrejj@salstar.sk>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow for the possibility of additional reboot types by extending the
reboot() function to use a flags bitmask rather than a single flag.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Simplify Multiboot and ELF image parsing by assuming that the
Multiboot and ELF headers are directly accessible via pointer
dereferences, and add some missing header validations.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Simplify the framebuffer console drivers by assuming that the raw
framebuffer, character cell array, background picture, and glyph data
are all directly accessible via pointer dereferences.
In particular, this avoids the need to copy each glyph during drawing:
the VESA framebuffer driver can simply return a pointer to the glyph
data stored in the video ROM.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Simplify the PXE file API implementation by assuming that all string
buffers are directly accessible via pointer dereferences.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Simplify the PXE API call dispatcher code by assuming that the PXE
parameter block is accessible via a direct pointer dereference. This
avoids the need for the API call dispatcher to know the size of the
parameter block.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Simplify the block device code by assuming that all read/write buffers
are directly accessible via pointer dereferences.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Simplify microcode image parsing by assuming that all image content is
directly accessible via pointer dereferences.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Simplify the microcode update mechanism by assuming that status
reports are accessible via direct pointer dereferences.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Use standard void pointers for umalloc(), urealloc(), and ufree(),
with the "u" prefix retained to indicate that these allocations are
made from external ("user") memory rather than from the internal heap.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Simplify the SMBIOS structure parsing code by assuming that all
structure content is fully accessible via pointer dereferences.
In particular, this allows the convoluted find_smbios_structure() and
read_smbios_structure() to be combined into a single function
smbios_structure() that just returns a direct pointer to the SMBIOS
structure, with smbios_string() similarly now returning a direct
pointer to the relevant string.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Simplify the ACPI table parsing code by assuming that all table
content is fully accessible via pointer dereferences.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Remove the intermediate concept of a user pointer from real address
conversion, leaving real_to_virt() as the directly implemented
function.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Remove the intermediate concept of a user pointer from physical
address conversions, leaving virt_to_phys() and phys_to_virt() as the
directly implemented functions.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The user_to_virt() function is now a straightforward wrapper around
addition, with the addend almost invariably being zero.
Remove this redundant wrapper.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The memcpy_user(), memmove_user(), memcmp_user(), memset_user(), and
strlen_user() functions are now just straightforward wrappers around
the corresponding standard library functions.
Remove these redundant wrappers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
The userptr_add() and userptr_diff() functions are now just
straightforward wrappers around addition and subtraction.
Remove these redundant wrappers.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Clarify the intended usage of userptr_sub() by renaming it to
userptr_diff() (to avoid confusion with userptr_add()), and fix the
existing call sites that erroneously use userptr_sub() to subtract an
offset from a userptr_t value.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Allow for parsing device trees where an external factor (such as a
downloaded image length) determines the maximum length, which must be
validated against the length within the device tree header.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
When running on a platform that uses FDT as its hardware description
mechanism, we are likely to have multiple device tree structures. At
a minimum, there will be the device tree passed to us from the
previous boot stage (e.g. OpenSBI), and the device tree that we
construct to be passed to the booted operating system.
Update the internal FDT API to include an FDT pointer in all function
parameter lists.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
If the UNDI interrupt remains constantly asserted (e.g. because the
BIOS has enabled interrupts for an unrelated device sharing the same
IRQ, or because of bugs in the OEM UNDI driver), then we may get stuck
in an interrupt storm.
We cannot safely chain to the previous interrupt handler (which could
plausibly handle an unrelated device interrupt) since there is no
well-defined behaviour for previous interrupt handlers. We have
observed BIOSes to provide default interrupt handlers that variously
do nothing, send EOI, disable the IRQ, or crash the system.
Fix by disabling the UNDI interrupt whenever our handler is triggered,
and rearm it as needed when polling the network device. This ensures
that forward progress continues to be made even if something causes
the interrupt to be constantly asserted.
Signed-off-by: Michael Brown <mcb30@ipxe.org>