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 11:06:14 +0800
User-agent: Mozilla/5.0 (X11; Linux loongarch64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0



On 2024/12/24 上午10:31, Jiaxun Yang wrote:


在2024年12月24日十二月 上午1:25,bibo mao写道:
On 2024/12/24 上午9:15, Jiaxun Yang wrote:


在2024年12月24日十二月 上午12:56,bibo mao写道:
Sorry, I do not know the background.
Now kernel image with EFI format can boot if uefi bios is provided.

What is this patch to do?  is it to direct boot kernel with EFI format
without UEFI bios parameter?

Yes, it’s now capable for booting vmlinux.efi without BIOS, as well as raw 
kernel built without EFI STUB.
   Is efi boottime service used by vmlinux.efi? such as
handle_protocol/allocate_pages etc.

Short answer: no.

To explain, we are jumping directly to kernel’s
entry instead of EFISTUB entry.

So it basically it works in the same manner as ELF booting, kernel won’t call 
EFI service if non-EFI booting environment is detected via a0 argument.
That is wonderful,  please add this in the note.

Regards
Bibo Mao


Thanks

Regards
Bibo Mao

Thanks


Regards
Bibo Mao

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);
+        }
+    }
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]