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: Jiaxun Yang
Subject: Re: [PATCH] hw/loongarch/boot: Support Linux raw boot image
Date: Tue, 24 Dec 2024 02:31:54 +0000


在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.

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,
>>>>
>>

-- 
- Jiaxun



reply via email to

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