aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSong Gao <gaosong@loongson.cn>2024-04-26 17:15:36 +0800
committerSong Gao <gaosong@loongson.cn>2024-04-29 10:25:56 +0800
commit02307a678c3cb366d089ef8d90f6acb9663b98ce (patch)
tree38eef0224faef4e48f6abe300bed19b846f8fcb8
parentd771ca1c10ab146eae676dd6a6975a8f7cf84d65 (diff)
downloadqemu-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.c28
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;
}