]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[riscv] Add a .lkrn build target resembling a Linux kernel binary
authorMichael Brown <mcb30@ipxe.org>
Tue, 13 May 2025 11:51:53 +0000 (12:51 +0100)
committerMichael Brown <mcb30@ipxe.org>
Tue, 13 May 2025 12:03:08 +0000 (13:03 +0100)
On x86 BIOS, it has been useful to be able to build iPXE to resemble a
Linux kernel, so that it can be loaded by programs such as syslinux
which already know how to handle Linux kernel binaries.

Add an equivalent .lkrn build target for RISC-V SBI, allowing for
build targets such as:

  make bin-riscv64/ipxe.lkrn

  make bin-riscv64/cgem.lkrn

The Linux kernel header format allows us to specify a required length
(including uninitialised-data portions) and defines that the image
will be loaded at a fixed offset from the start of RAM.  We can
therefore use known-safe areas of memory (within our own .bss) for the
initial temporary page table and stack.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/riscv/Makefile.sbi
src/arch/riscv/prefix/libprefix.S
src/arch/riscv/prefix/lkrnprefix.S [new file with mode: 0644]

index a10680eafe8ad853fff9bea46865d36b4c7ae2da..2546366b2300e9b9c4f75e42a254f6bfd08116f8 100644 (file)
@@ -14,3 +14,4 @@ LDSCRIPT      = arch/riscv/scripts/sbi.lds
 # Media types
 #
 MEDIA          += sbi
+MEDIA          += lkrn
index c5f4961c003efda968cd4e5c9c44a68304231d86..e47bab98102f45adc795bf3c9876637057b40c3f 100644 (file)
@@ -452,6 +452,7 @@ paging_mode_names:
         * This can be used only once .bss is known to be writable.
         */
        .section ".bss.page_table", "a", @nobits
+       .globl  page_table
        .balign PAGE_SIZE
 page_table:
        .space  PAGE_SIZE
diff --git a/src/arch/riscv/prefix/lkrnprefix.S b/src/arch/riscv/prefix/lkrnprefix.S
new file mode 100644 (file)
index 0000000..9493d01
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+       FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+
+/** @file
+ *
+ * Linux kernel prefix
+ *
+ */
+
+       .section ".note.GNU-stack", "", @progbits
+       .text
+
+       /* Layout of kernel header */
+       .struct 0
+hdr_code0:             .space  4
+hdr_code1:             .space  4
+hdr_text_offset:       .space  8
+hdr_image_size:                .space  8
+hdr_flags:             .space  8
+hdr_version:           .space  4
+hdr_res1:              .space  4
+hdr_res2:              .space  8
+hdr_magic:             .space  8
+hdr_magic2:            .space  4
+hdr_res3:              .space  4
+hdr_end:
+       .org    64
+       .previous
+
+/* Header version */
+#define HDR_VERSION( major, minor ) ( ( (major) << 16 ) | (minor) )
+#define HDR_VERSION_0_2 HDR_VERSION ( 0, 2 )
+
+/* Header flags */
+#define HDR_FL_BIG_ENDIAN 0x00000001
+
+/* Magic numbers */
+#define HDR_MAGIC      "RISCV\0\0\0"
+#define HDR_MAGIC2     "RSC\x05"
+
+       /*
+        * Linux kernel header
+        */
+       .section ".prefix", "ax", @progbits
+
+       /* Executable code / MZ header (for EFI-compatible binaries) */
+       .org    hdr_code0
+       j       _lkrn_start
+
+       /* Image load offset
+        *
+        * Must be set to the size of a single "megapage" (2MB for
+        * 64-bit, 4MB for 32-bit).
+        */
+       .org    hdr_text_offset
+       .dword  _max_align
+
+       /* Image size (including uninitialised-data potions) */
+       .org    hdr_image_size
+       .dword  _memsz
+
+       /* Flags */
+       .org    hdr_flags
+       .dword  0
+
+       /* Version */
+       .org    hdr_version
+       .word   HDR_VERSION_0_2
+
+       /* Magic numbers */
+       .org    hdr_magic
+       .ascii  HDR_MAGIC
+       .org    hdr_magic2
+       .ascii  HDR_MAGIC2
+
+       .org    hdr_end
+
+       /*
+        * Linux kernel entry point
+        */
+       .globl  _lkrn_start
+_lkrn_start:
+       /* Identify temporary page table and stack space
+        *
+        * Linux expects to be placed at the image load offset from
+        * the start of RAM.  Assume that our loaded image is
+        * therefore already writable, and that we can therefore use
+        * the page table and stack within our (not yet zeroed) .bss
+        * section.
+        */
+       la      a2, page_table
+       la      sp, _estack
+
+       /* Install iPXE */
+       call    install
+
+       /* Call main program */
+       call    main
+
+       /* We have no return path, since the Linux kernel does not
+        * define that a valid return address exists.
+        *
+        * Attempt a system reset, since there is nothing else we can
+        * viably do at this point.
+        */
+       j       reset_system
+       .size   _lkrn_start, . - _lkrn_start