Commit Graph

2513 Commits

Author SHA1 Message Date
Michael Brown
9bc559850c [fdt] Allow an initrd to be specified when creating a device tree
Allow an initrd location to be specified in our constructed device
tree via the "linux,initrd-start" and "linux,initrd-end" properties.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-21 14:31:18 +01:00
Michael Brown
c1cd54ad74 [initrd] Move initrd reshuffling to be architecture-independent code
There is nothing x86-specific in initrd.c, and a variant of the
reshuffling logic will be required for executing bare-metal kernels on
RISC-V and AArch64.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-21 12:12:16 +01:00
Michael Brown
e2f4dba2b7 [lkrn] Add support for EFI zboot compressed kernel images
Current RISC-V and AArch64 kernels found in the wild tend not to be in
the documented kernel format, but are instead "EFI zboot" kernels
comprising a small EFI executable that decompresses and executes the
inner payload (which is a kernel in the expected format).

The EFI zboot header includes a recognisable magic value "zimg" along
with two fields describing the offset and length of the compressed
payload.  We can therefore treat this as an archive image format,
extracting the payload as-is and then relying on our existing ability
to execute compressed images.

This is sufficient to allow iPXE to execute the Fedora 42 RISC-V
kernel binary as currently published.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-20 14:29:57 +01:00
Michael Brown
ecac4a34c7 [lkrn] Add basic support for the RISC-V Linux kernel image format
The RISC-V and AArch64 bare-metal kernel images share a common header
format, and require essentially the same execution environment: loaded
close to the start of RAM, entered with paging disabled, and passed a
pointer to a flattened device tree that describes the hardware and any
boot arguments.

Implement basic support for executing bare-metal RISC-V and AArch64
kernel images.  The (trivial) AArch64-specific code path is untested
since we do not yet have the ability to build for any bare-metal
AArch64 platforms.  Constructing and passing an initramfs image is not
yet supported.

Rename the IMAGE_BZIMAGE build configuration option to IMAGE_LKRN,
since "bzImage" is specific to x86.  To retain backwards compatibility
with existing local build configurations, we leave IMAGE_BZIMAGE as
the enabled option in config/default/pcbios.h and treat IMAGE_LKRN as
a synonym for IMAGE_BZIMAGE when building for x86 BIOS.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-20 13:08:38 +01:00
Michael Brown
d0c35b6823 [bios] Use generic external heap based on the system memory map
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-19 20:47:21 +01:00
Michael Brown
4d560af2b0 [uheap] Add a generic external heap based on the system memory map
Add an implementation of umalloc() using the generalised model of a
heap, placing the external heap in the largest usable region obtained
from the system memory map.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-19 19:36:25 +01:00
Michael Brown
490f1ecad8 [malloc] Allow heap to specify block and pointer alignments
Size-tracked pointers allocated via umalloc() have historically been
aligned to a page boundary, as have the edges of the hidden memory
region covering the external heap.

Allow the block and size-tracked pointer alignments to be specified as
heap configuration parameters.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-19 19:36:23 +01:00
Michael Brown
c6ca3d3af8 [malloc] Allow for the existence of multiple heaps
Create a generic model of a heap as a list of free blocks with
optional methods for growing and shrinking the heap.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-19 19:35:56 +01:00
Michael Brown
83449702e0 [memmap] Remove now-obsolete get_memmap()
All memory map users have been updated to use the new system memory
map API.  Remove get_memmap() and its associated definitions.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-16 18:16:41 +01:00
Michael Brown
3812860e39 [bios] Describe umalloc() heap as an in-use memory area
Use the concept of an in-use memory region defined as part of the
system memory map API to describe the umalloc() heap.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-16 16:18:36 +01:00
Michael Brown
3f6ee95737 [fdtmem] Update to use the generic system memory map API
Provide an implementation of the system memory map API based on the
system device tree, excluding any memory outside the size of the
accessible physical address space and defining an in-use region to
cover the relocated copy of iPXE and the system device tree.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-16 16:18:36 +01:00
Michael Brown
bab3d76717 [memmap] Define an API for managing the system memory map
Define a generic system memory map API, based on the abstraction
created for parsing the FDT memory map and adding a concept of hidden
in-use memory regions as required to support patching the BIOS INT 15
memory map.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-16 16:12:15 +01:00
Michael Brown
e0c4cfa81e [fdtmem] Record size of accessible physical address space
The size of accessible physical address space will be required for the
runtime memory map, not just at relocation time.  Make this size an
additional parameter to fdt_register() (matching the prototype for
fdt_relocate()), and record the value for future reference.

Note that we cannot simply store the limit in fdt_relocate() since it
is called before .data is writable and before .bss is zeroed.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-14 22:09:51 +01:00
Michael Brown
4566f59757 [riscv] Avoid potentially overwriting the scratch area during relocation
We do not currently describe the temporary page table or the temporary
stack as areas to be avoided during relocation of the iPXE image to a
new physical address.

Perform the copy of the iPXE image and zeroing of the .bss within
libprefix.S, after we have no futher use for the temporary page table
or the temporary initial stack.  Perform the copy and registration of
the system device tree in C code after relocation is complete and the
new stack (within .bss) has been set up.

This provides a clean separation of responsibilities between the
RISC-V libprefix.S and the architecture-independent fdtmem.c.  The
prefix is responsible only for relocating iPXE to the new physical
address returned from fdtmem_relocate(), and doesn't need to know or
care where fdtmem.c is planning to place the copy of the device tree.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-13 14:00:34 +01:00
Michael Brown
6fe9ce66ae [fdtmem] Add ability to parse FDT memory map for a relocation address
Add code to parse the devicetree memory nodes, memory reservations
block, and reserved memory nodes to construct an ordered and
non-overlapping description of the system memory map, and use this to
identify a suitable address to which iPXE may be relocated at runtime.

We choose to place iPXE on a superpage boundary (as required by the
paging code), and to use the highest available address within
accessible memory.  This mirrors the approach taken for x86 BIOS
builds, where we have long assumed that any image format that we might
need to support may require specific fixed addresses towards the
bottom of the memory map, but is very unlikely to require specific
fixed addresses towards the top of the memory map (since those
addresses may not exist, depending on the amount of installed RAM).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-11 18:23:08 +01:00
Michael Brown
95ede670bc [riscv] Hold virtual address offset in the thread pointer register
iPXE does not make use of any thread-local storage.  Use the otherwise
unused thread pointer register ("tp") to hold the current value of
the virtual address offset, rather than using a global variable.

This ensures that virt_offset can be made valid even during very early
initialisation (when iPXE may be executing directly from read-only
memory and so cannot update a global variable).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-11 13:46:21 +01:00
Michael Brown
f988ec09e0 [fdt] Generalise access to "reg" property
The "reg" property is also used by non-device nodes, such as the nodes
describing the system memory map.

Provide generalised functionality for parsing the "#address-cells",
"#size-cells", and "reg" properties.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-09 19:09:57 +01:00
Michael Brown
134d76379e [build] Formalise mechanism for accessing absolute symbols
In a position-dependent executable, where all addresses are fixed
at link time, we can use the standard technique as documented by
GNU ld to get the value of an absolute symbol, e.g.:

    extern char _my_symbol[];

    printf ( "Absolute symbol value is %x\n", ( ( int ) _my_symbol ) );

This technique may not work in a position-independent executable.
When dynamic relocations are applied, the runtime addresses will no
longer be equal to the link-time addresses.  If the code to obtain the
address of _my_symbol uses PC-relative addressing, then it will
calculate the runtime "address" of the absolute symbol, which will no
longer be equal the the link-time "address" (i.e. the correct value)
of the absolute symbol.

Define macros ABS_SYMBOL(), ABS_VALUE_INIT(), and ABS_VALUE() that
provide access to the correct values of absolute symbols even in
position-independent code, and use these macros wherever absolute
symbols are accessed.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-09 15:14:03 +01:00
Michael Brown
1d58d928fe [libc] Display assertion failure message before incrementing counter
During early initialisation on some platforms, the .data and .bss
sections may not yet be writable.

Display the assertion message before attempting to increment the
assertion failure counter, since writing to the assertion counter may
trigger a CPU exception that ends up resetting the system.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-09 14:36:00 +01:00
Michael Brown
0279015d09 [uaccess] Generalise librm's virt_offset mechanism for RISC-V
The virtual offset memory model used for i386-pcbios and x86_64-pcbios
can be generalised to also cover riscv32-sbi and riscv64-sbi.  In both
architectures, the 32-bit builds will use a circular map of the 32-bit
address space, and the 64-bit builds will use an identity map for the
relevant portion of the physical address space, with iPXE itself
placed in the negative (kernel) address space.

Generalise and document the virt_offset mechanism, and set it as the
default for both PCBIOS and SBI platforms.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-05-08 00:12:33 +01:00
Michael Brown
1534b0a6e9 [uaccess] Remove redundant virt_to_user() and userptr_t
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>
2025-04-30 16:26:16 +01:00
Michael Brown
a169d73593 [uaccess] Reduce scope of included uaccess.h header
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>
2025-04-30 16:16:02 +01:00
Michael Brown
05ad7833c5 [image] Make image data read-only to most consumers
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>
2025-04-30 15:38:15 +01:00
Michael Brown
cd803ff2e2 [image] Add the concept of a static image
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>
2025-04-30 15:38:15 +01:00
Michael Brown
b6f9e4bab0 [uaccess] Remove redundant copy_from_user() and copy_to_user()
Remove the now-redundant copy_from_user() and copy_to_user() wrapper
functions.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-30 15:32:03 +01:00
Michael Brown
9962c0a58f [bofm] Remove userptr_t from BOFM table parsing and updating
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-29 13:42:42 +01:00
Michael Brown
0800723845 [bofm] Allow BOFM tests to be run without a BOFM-capable device driver
The BOFM tests are not part of the standard unit test suite, since
they are designed to allow for exercising real BOFM driver code
outside of the context of a real IBM blade server.

Allow for the BOFM tests to be run without a real BOFM driver, by
providing a dummy driver for the specified PCI test device.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-29 13:39:12 +01:00
Michael Brown
4e909cc2b0 [build] Remove some long-obsolete unused header files
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-29 12:17:16 +01:00
Michael Brown
6c9dc063f6 [peerdist] Remove never-used peerdist_msg_blk() macro
The peerdist_msg_blk() macro seems to have been introduced in the
original commit that added pccrr.h, but this macro was never used by
the version of the code present in that commit.

Remove this unused macro and the corresponding nonexistent external
function declaration.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-29 12:08:33 +01:00
Michael Brown
54c4217bdd [peerdist] Remove userptr_t from PeerDist content information parsing
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-29 11:28:45 +01:00
Michael Brown
837b77293b [xferbuf] Simplify and generalise data transfer buffers
Since all data transfer buffer contents are now accessible via direct
pointer dereferences, remove the unnecessary abstractions for read and
write operations and create two new data transfer buffer types: a
fixed-size buffer, and a void buffer that records its size but can
never receive non-zero lengths of data.  These replace the custom data
buffer types currently implemented for EFI PXE TFTP downloads and for
block device translations.

A new operation xferbuf_detach() is required to take ownership of the
data accumulated in the data transfer buffer, since we no longer rely
on the existence of an independently owned external data pointer for
data transfer buffers allocated via umalloc().

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-29 11:27:22 +01:00
Michael Brown
0b45db3972 [uaccess] Remove redundant UNULL definition
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-28 17:36:18 +01:00
Michael Brown
083e273bbc [efi] Add ability to reboot to firmware setup menu
Add the ability to reboot to the firmware setup menu (if supported) by
setting the relevant value in the OsIndications variable.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-28 14:01:17 +01:00
Michael Brown
7eaa2daf6f [reboot] Generalise warm reboot indicator to a flags bitmask
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>
2025-04-28 13:44:53 +01:00
Michael Brown
ba2135d0fd [multiboot] Remove userptr_t from Multiboot and ELF image parsing
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>
2025-04-28 13:06:18 +01:00
Michael Brown
15c1111c78 [build] Remove unsafe disable function wrapper from legacy NIC drivers
The legacy NIC drivers do not consistently take a second parameter in
their disable function.  We currently use an unsafe function wrapper
that declares no parameters, and rely on the ABI allowing a second
parameter to be silently ignored if not expected by the caller.  As of
GCC 15, this hack results in an incompatible pointer type warning.

Fix by removing the hack, and instead updating all relevant legacy NIC
drivers to take an unused second parameter in their disable function.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-27 18:40:52 +01:00
Michael Brown
58e6729cb6 [build] Fix typo in xenver.h header guard
GCC 15 helpfully reports mismatched #ifdef and #define lines in header
guards.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-27 18:40:03 +01:00
Michael Brown
4c8bf666f4 [pnm] Remove userptr_t from PNM image parsing
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-25 17:23:37 +01:00
Michael Brown
aa3cc56ab2 [fbcon] Remove userptr_t from framebuffer console drivers
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>
2025-04-25 12:44:28 +01:00
Michael Brown
2f11f466e6 [block] Remove userptr_t from block device abstraction
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>
2025-04-24 17:11:30 +01:00
Michael Brown
2742ed5d77 [uaccess] Remove now-obsolete memchr_user()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-24 16:35:49 +01:00
Michael Brown
e8ffe2cd64 [uaccess] Remove trivial uses of userptr_t
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-24 01:40:05 +01:00
Michael Brown
839540cb95 [umalloc] Remove userptr_t from user memory allocations
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>
2025-04-23 14:43:04 +01:00
Michael Brown
0bf0f8716a [smbios] Remove userptr_t from SMBIOS structure parsing
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>
2025-04-23 10:08:16 +01:00
Michael Brown
0b3fc48fef [acpi] Remove userptr_t from ACPI table parsing
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>
2025-04-22 14:21:06 +01:00
Michael Brown
c059b34170 [deflate] Remove userptr_t from decompression code
Simplify the deflate, zlib, and gzip decompression code by assuming
that all content is fully accessible via pointer dereferences.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-22 12:32:12 +01:00
Michael Brown
b89a34b07f [image] Remove userptr_t from image definition
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-22 12:21:26 +01:00
Michael Brown
e98b84f1b9 [crypto] Remove userptr_t from CMS verification and decryption
Simplify the CMS code by assuming that all content is fully accessible
via pointer dereferences.  This avoids the need to use fragment loops
for calculating digests and decrypting (or reencrypting) data.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-22 00:28:07 +01:00
Michael Brown
3f8937d2f3 [crypto] Remove userptr_t from ASN.1 parsers
Simplify the ASN.1 code by assuming that all objects are fully
accessible via pointer dereferences.  This allows the concept of
"additional data beyond the end of the cursor" to be removed, and
simplifies parsing of all ASN.1 image formats.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-21 23:30:13 +01:00
Michael Brown
04d0b2fdf9 [uaccess] Remove redundant read_user()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
2025-04-21 18:55:30 +01:00