]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[pxeprefix] Add a minimal iPXE NBP metadata header
authorMichael Brown <mcb30@ipxe.org>
Sun, 22 Feb 2026 23:13:00 +0000 (23:13 +0000)
committerMichael Brown <mcb30@ipxe.org>
Sun, 22 Feb 2026 23:23:37 +0000 (23:23 +0000)
There is no fixed structure for a PXE NBP: the format is just an
opaque block of executable code that is loaded into memory verbatim
and executed by jumping to the first byte.  It is consequently
impossible for external code to unambiguously identify a PXE NBP, or
to inspect any metadata about the NBP's functionality.

The first five bytes of an iPXE NBP are already fixed as being an ljmp
instruction that resets the code segment to 0x7c0 and continues
execution from the following byte.  We can extend this to include a
minimal header as follows:

    Offset    Content
    ------    -------
    0         ljmp instruction (0xea)
    1-2       ljmp offset (and therefore length of header)
    3-4       ljmp segment (0x07c0)
    5+        Metadata fields
    \_ 5      CPU architecture (0x32=i386, 0x64=x86_64)
    \_ 6-7    Magic value (0x18ae)

This is backwards-compatible to existing binaries (which effectively
have zero bytes of metadata following the ljmp instruction), and
allows for future expansion by appending metadata fields (with the
ljmp offset used to determine the overall header length and therefore
the presence of further fields).

In this initial version of the header, define a magic value (used to
differentiate an iPXE NBP from other binaries that happen to start
with an ljmp instruction), and a single-byte value that encodes
whether this binary is built for 32-bit or 64-bit CPUs.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/x86/prefix/pxeprefix.S

index 067af99fa6a85f1647184d8cbff9ca48e1f40d4c..db8359fbfb9f8dfed37d5c3c34cda5e4c557c2bb 100644 (file)
@@ -24,6 +24,16 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 #define EB_MAGIC_1 ( 'E' + ( 't' << 8 ) + ( 'h' << 16 ) + ( 'e' << 24 ) )
 #define EB_MAGIC_2 ( 'r' + ( 'b' << 8 ) + ( 'o' << 16 ) + ( 'o' << 24 ) )
 
+/* Magic signature word */
+#define IPXE_NBP_MAGIC 0x18ae
+
+/* Architecture byte */
+#ifdef __x86_64__
+#define IPXE_NBP_ARCH 0x64
+#else
+#define IPXE_NBP_ARCH 0x32
+#endif
+
 /* Prefix memory layout:
  *
  *     iPXE binary image
@@ -44,7 +54,21 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
        .section ".prefix", "ax", @progbits
        .globl  _pxe_start
 _pxe_start:
+       /* iPXE NBP magic header:
+        *
+        * Offset       Content
+        * ------       -------
+        * 0            ljmp instruction (0xea)
+        * 1-2          ljmp offset (and therefore length of header)
+        * 3-4          ljmp segment (0x07c0)
+        * 5+           Metadata fields
+        * \_ 5         CPU architecture (0x32=i386, 0x64=x86_64)
+        * \_ 6-7       Magic value (0x18ae)
+        *
+        */
        jmp     $0x7c0, $1f
+       .byte   IPXE_NBP_ARCH
+       .word   IPXE_NBP_MAGIC
 1:
        /* Preserve registers for possible return to PXE */
        pushfl