Reduce memory footprint by mapping the kernel into memory instead of
reading into allocated memory in the common case (no -dtb $file on the
qemu command line).

Cc: John Snow <[email protected]>
Signed-off-by: Gerd Hoffmann <[email protected]>
---
 hw/i386/x86-common.c | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c
index fa18bf1aeceb..25e141aa8537 100644
--- a/hw/i386/x86-common.c
+++ b/hw/i386/x86-common.c
@@ -911,16 +911,31 @@ void x86_load_linux(X86MachineState *x86ms,
     }
 
     setup  = g_malloc(setup_size);
-    kernel = g_malloc(kernel_size);
     fseek(f, 0, SEEK_SET);
     if (fread(setup, 1, setup_size, f) != setup_size) {
         fprintf(stderr, "fread() failed\n");
         exit(1);
     }
-    fseek(f, 0, SEEK_SET);
-    if (fread(kernel, 1, kernel_size, f) != kernel_size) {
-        fprintf(stderr, "fread() failed\n");
-        exit(1);
+    if (dtb_filename) {
+        /* read kernel into allocated memory, so we can realloc for the dtb */
+        kernel = g_malloc(kernel_size);
+        fseek(f, 0, SEEK_SET);
+        if (fread(kernel, 1, kernel_size, f) != kernel_size) {
+            fprintf(stderr, "fread() failed\n");
+            exit(1);
+        }
+    } else {
+        /* mmap kernel */
+        GMappedFile *mapped_file;
+        GError *gerr = NULL;
+
+        mapped_file = g_mapped_file_new(kernel_filename, false, &gerr);
+        if (!mapped_file) {
+            fprintf(stderr, "qemu: error reading kernel %s: %s\n",
+                    kernel_filename, gerr->message);
+            exit(1);
+        }
+        kernel = (uint8_t *)g_mapped_file_get_contents(mapped_file);
     }
     fclose(f);
 
-- 
2.56.0


Reply via email to