Patchwork [RFC,v4,1/3] use image_file_reset to reload initrd image

login
register
mail settings
Submitter Olivia Yin
Date Nov. 14, 2012, 1:28 p.m.
Message ID <1352899732-1197-2-git-send-email-hong-hua.yin@freescale.com>
Download mbox | patch
Permalink /patch/198918/
State New
Headers show

Comments

Olivia Yin - Nov. 14, 2012, 1:28 p.m.
Signed-off-by: Olivia Yin <hong-hua.yin@freescale.com>
---
 hw/loader.c |   39 +++++++++++++++++++++++++++++++++++++++
 hw/loader.h |    7 +++++++
 2 files changed, 46 insertions(+), 0 deletions(-)
Stuart Yoder - Nov. 15, 2012, 7:52 p.m.
>  /* read()-like version */
>  ssize_t read_targphys(const char *name,
>                        int fd, hwaddr dst_addr, size_t nbytes)
> @@ -113,6 +146,12 @@ int load_image_targphys(const char *filename,
>      }
>      if (size > 0) {
>          rom_add_file_fixed(filename, addr, -1);
> +        ImageFile *image;
> +        image = g_malloc0(sizeof(*image));
> +        image->name = g_strdup(filename);
> +        image->addr = addr;
> +
> +        qemu_register_reset(image_file_reset, image);

You need to remove the call to rom_add_file_fixed(), no?

Stuart
Yin Olivia-R63875 - Nov. 16, 2012, 5:50 a.m.
Hi Stuart,

I want to keep the Memory Region of rom which will be inserted to the queue roms.
And then we can use "info roms" command to check the rom information.

ROM images must be loaded at startup, so rom_add_* functions could be called only
one time before all the reset handlers.

Exactly all the memory malloced to rom->data will be free when rom_reset() no matter
it is rom (rom->isrom = 1) or ram (rom->isrom =0).
@@ -708,11 +739,8 @@ static void rom_reset(void *unused)
             continue;
         }
         cpu_physical_memory_write_rom(rom->addr, rom->data, rom->romsize);
-        if (rom->isrom) {
-            /* rom needs to be written only once */
-            g_free(rom->data);
-            rom->data = NULL;
-        }
+        g_free(rom->data);
+        rom->data = NULL;
     }
 }

For example, to load initrd image, both reset handlers (rom_reset() and image_file_reset() 
will write the image into the same physical address. So it will not malloc more memory.
	cpu_physical_memory_write_rom(rom->addr, rom->data, rom->romsize);
	cpu_physical_memory_write(image->addr, (uint8_t *)content, size);

The uImage is another case, I'll explain in the reply of patch 2/3.

Best Regards,
Olivia

> -----Original Message-----
> From: Stuart Yoder [mailto:b08248@gmail.com]
> Sent: Friday, November 16, 2012 3:52 AM
> To: Yin Olivia-R63875
> Cc: qemu-devel@nongnu.org; qemu-ppc@nongnu.org
> Subject: Re: [Qemu-devel] [RFC PATCH v4 1/3] use image_file_reset to
> reload initrd image
> 
> >  /* read()-like version */
> >  ssize_t read_targphys(const char *name,
> >                        int fd, hwaddr dst_addr, size_t nbytes) @@
> > -113,6 +146,12 @@ int load_image_targphys(const char *filename,
> >      }
> >      if (size > 0) {
> >          rom_add_file_fixed(filename, addr, -1);
> > +        ImageFile *image;
> > +        image = g_malloc0(sizeof(*image));
> > +        image->name = g_strdup(filename);
> > +        image->addr = addr;
> > +
> > +        qemu_register_reset(image_file_reset, image);
> 
> You need to remove the call to rom_add_file_fixed(), no?
> 
> Stuart

Patch

diff --git a/hw/loader.c b/hw/loader.c
index ba01ca6..a8a0a09 100644
--- a/hw/loader.c
+++ b/hw/loader.c
@@ -86,6 +86,39 @@  int load_image(const char *filename, uint8_t *addr)
     return size;
 }
 
+static void image_file_reset(void *opaque)
+{
+    ImageFile *image = opaque;
+    GError *err = NULL;
+    gboolean res;
+    gchar *content;
+    gsize size;
+
+    if(image->dir) {
+        const char *basename;
+        char fw_file_name[56];
+
+        basename = strrchr(image->name, '/');
+        if (basename) {
+            basename++;
+        } else {
+            basename = image->name;
+        }
+        snprintf(fw_file_name, sizeof(fw_file_name), "%s/%s", image->dir,
+                 basename);
+        image->name = g_strdup(fw_file_name);
+    }
+
+    res = g_file_get_contents(image->name, &content, &size, &err);
+    if (res == FALSE) {
+       error_report("failed to read image file: %s\n", image->name);
+       g_error_free(err);
+    } else {
+       cpu_physical_memory_write(image->addr, (uint8_t *)content, size);
+       g_free(content);
+    }
+}
+
 /* read()-like version */
 ssize_t read_targphys(const char *name,
                       int fd, hwaddr dst_addr, size_t nbytes)
@@ -113,6 +146,12 @@  int load_image_targphys(const char *filename,
     }
     if (size > 0) {
         rom_add_file_fixed(filename, addr, -1);
+        ImageFile *image;
+        image = g_malloc0(sizeof(*image));
+        image->name = g_strdup(filename);
+        image->addr = addr;
+ 
+        qemu_register_reset(image_file_reset, image);
     }
     return size;
 }
diff --git a/hw/loader.h b/hw/loader.h
index 26480ad..d021629 100644
--- a/hw/loader.h
+++ b/hw/loader.h
@@ -1,6 +1,13 @@ 
 #ifndef LOADER_H
 #define LOADER_H
 
+typedef struct ImageFile ImageFile;
+struct ImageFile {
+    char *name;
+    char *dir;
+    hwaddr addr;
+};
+
 /* loader.c */
 int get_image_size(const char *filename);
 int load_image(const char *filename, uint8_t *addr); /* deprecated */