qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] hw/loongarch/boot: Support Linux raw boot image


From: bibo mao
Subject: Re: [PATCH] hw/loongarch/boot: Support Linux raw boot image
Date: Tue, 24 Dec 2024 12:03:32 +0800
User-agent: Mozilla/5.0 (X11; Linux loongarch64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0



On 2024/12/23 上午8:30, Jiaxun Yang wrote:
Many distros are shipping raw kernel images (i.e. vmlinux.efi).

Support booting such image by parsing header as per Linux's
specification [1].

[1]: https://docs.kernel.org/arch/loongarch/booting.html

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
It is based on my previous booting protocol patch
---
  hw/loongarch/boot.c         | 45 +++++++++++++++++++++++++++++++++++++++++++++
  include/hw/loongarch/boot.h | 17 +++++++++++++++++
  2 files changed, 62 insertions(+)

diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 
93847b0eaf8e50ce1a990b91267780e6785e1c2f..5bc889c51fafa9c6d37426b9bee9709c12183927
 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -260,6 +260,43 @@ static uint64_t cpu_loongarch_virt_to_phys(void *opaque, 
uint64_t addr)
      return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
  }
+static int64_t get_linux_image_info(struct loongarch_boot_info *info,
+                                    uint64_t *kernel_entry,
+                                    uint64_t *kernel_low,
+                                    uint64_t *kernel_high)
+{
+    int fd;
+    struct loongarch_linux_hdr hdr;
+    int64_t kernel_size = -1;
+
+    fd = open(info->kernel_filename, O_RDONLY | O_BINARY);
+    if (fd < 0) {
+        return -1;
+    }
+
+    if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
+        close(fd);
+        return -1;
+    }
+
+    if ((le32_to_cpu(hdr.mz_magic) & 0xffff) != MZ_MAGIC ||
+        le32_to_cpu(hdr.linux_pe_magic) != LINUX_PE_MAGIC) {
+        close(fd);
+        return -1;
+    }
+
+    *kernel_entry = le64_to_cpu(hdr.kernel_entry);
+    /* Early kernel versions may have those fields in virtual address */
+    *kernel_entry &= MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
+    *kernel_low = le64_to_cpu(hdr.load_offset);
+    *kernel_low &= MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
+    kernel_size = le64_to_cpu(hdr.kernel_size);
+    *kernel_high = *kernel_low + kernel_size;
+
+    close(fd);
+    return kernel_size;
+}
+
  static int64_t load_kernel_info(struct loongarch_boot_info *info)
  {
      uint64_t kernel_entry, kernel_low, kernel_high;
@@ -270,6 +307,14 @@ static int64_t load_kernel_info(struct loongarch_boot_info 
*info)
                             &kernel_entry, &kernel_low,
                             &kernel_high, NULL, 0,
                             EM_LOONGARCH, 1, 0);
+    if (kernel_size < 0) {
+        kernel_size = get_linux_image_info(info, &kernel_entry,
+                                           &kernel_low, &kernel_high);
+        if (kernel_size >= 0) {
+            kernel_size = load_image_targphys(info->kernel_filename,
+                                              kernel_low, kernel_size);
+        }
Can we read file header file firstly?
If it is ELFMAG, load_elf is called.

If it is EFI_PE_MSDOS_MAGIC, check zimg magic in linux_efi_zboot_header, else loongarch_linux_hdr for plain image if zimg does not match.

Regards
Bibo Mao

+    }
if (kernel_size < 0) {
          error_report("could not load kernel '%s': %s",
diff --git a/include/hw/loongarch/boot.h b/include/hw/loongarch/boot.h
index 
96ec15016a314499acf65c6c47e0c4932aa99d01..5e8bd4dd73bbb27abccfa1fa577df52aed15b6a2
 100644
--- a/include/hw/loongarch/boot.h
+++ b/include/hw/loongarch/boot.h
@@ -8,6 +8,23 @@
  #ifndef HW_LOONGARCH_BOOT_H
  #define HW_LOONGARCH_BOOT_H
+/* Linux Image Format */
+#define LINUX_PE_MAGIC  0x818223cd
+#define MZ_MAGIC        0x5a4d /* "MZ" */
+
+struct loongarch_linux_hdr {
+    uint32_t mz_magic;
+    uint32_t res0;
+    uint64_t kernel_entry;
+    uint64_t kernel_size;
+    uint64_t load_offset;
+    uint64_t res1;
+    uint64_t res2;
+    uint64_t res3;
+    uint32_t linux_pe_magic;
+    uint32_t pe_header_offset;
+} QEMU_PACKED;
+
  /* UEFI 2.10 */
  #define EFI_SYSTEM_TABLE_SIGNATURE       0x5453595320494249
  #define EFI_2_100_SYSTEM_TABLE_REVISION  ((2<<16) | (100))

---
base-commit: c69612063e1844b76ac01e3a781b979548c3585c
change-id: 20241222-la-direct-kernel-boot-c598264710e7

Best regards,





reply via email to

[Prev in Thread] Current Thread [Next in Thread]