diff options
author | Song Gao <gaosong@loongson.cn> | 2024-04-26 17:15:36 +0800 |
---|---|---|
committer | Song Gao <gaosong@loongson.cn> | 2024-04-29 10:25:56 +0800 |
commit | 02307a678c3cb366d089ef8d90f6acb9663b98ce (patch) | |
tree | 38eef0224faef4e48f6abe300bed19b846f8fcb8 | |
parent | d771ca1c10ab146eae676dd6a6975a8f7cf84d65 (diff) | |
download | qemu-02307a678c3cb366d089ef8d90f6acb9663b98ce.zip qemu-02307a678c3cb366d089ef8d90f6acb9663b98ce.tar.gz qemu-02307a678c3cb366d089ef8d90f6acb9663b98ce.tar.bz2 |
hw/loongarch: Add load initrd
we load initrd ramdisk after kernel_high address
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Message-Id: <20240426091551.2397867-3-gaosong@loongson.cn>
-rw-r--r-- | hw/loongarch/boot.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 9feed17..a5135fe 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -22,7 +22,8 @@ static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr) static int64_t load_kernel_info(struct loongarch_boot_info *info) { - uint64_t kernel_entry, kernel_low, kernel_high; + uint64_t kernel_entry, kernel_low, kernel_high, initrd_size; + ram_addr_t initrd_offset; ssize_t kernel_size; kernel_size = load_elf(info->kernel_filename, NULL, @@ -37,6 +38,31 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info) load_elf_strerror(kernel_size)); exit(1); } + + if (info->initrd_filename) { + initrd_size = get_image_size(info->initrd_filename); + if (initrd_size > 0) { + initrd_offset = ROUND_UP(kernel_high + 4 * kernel_size, 64 * KiB); + + if (initrd_offset + initrd_size > info->ram_size) { + error_report("memory too small for initial ram disk '%s'", + info->initrd_filename); + exit(1); + } + + initrd_size = load_image_targphys(info->initrd_filename, initrd_offset, + info->ram_size - initrd_offset); + } + + if (initrd_size == (target_ulong)-1) { + error_report("could not load initial ram disk '%s'", + info->initrd_filename); + exit(1); + } + } else { + initrd_size = 0; + } + return kernel_entry; } |