summary refs log tree commit diff stats
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)
downloadfocaccia-qemu-02307a678c3cb366d089ef8d90f6acb9663b98ce.tar.gz
focaccia-qemu-02307a678c3cb366d089ef8d90f6acb9663b98ce.zip
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 9feed17db3..a5135fe542 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;
 }