qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 1.1] sparc64: fix initrd loading
@ 2012-05-12 17:30 Blue Swirl
  2012-05-12 18:52 ` Artyom Tarasenko
  0 siblings, 1 reply; 3+ messages in thread
From: Blue Swirl @ 2012-05-12 17:30 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 6944 bytes --]

Initrd load address is too low, it conflicts with kernel load
address:
rom: requested regions overlap (rom phdr #0:
/tmp/vmlinux-debian-6.0.4-sparc64. free=0x0000000000742519,
addr=0x0000000000400000)
rom loading failed

Fix by making the initrd address variable, load initrd after kernel
image. Use 64 bit variables instead of longs or 32 bit types.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 hw/sun4u.c |   56 +++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 33 insertions(+), 23 deletions(-)

diff --git a/hw/sun4u.c b/hw/sun4u.c
index fe33138..517bdb8 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -67,7 +67,6 @@

 #define KERNEL_LOAD_ADDR     0x00404000
 #define CMDLINE_ADDR         0x003ff000
-#define INITRD_LOAD_ADDR     0x00300000
 #define PROM_SIZE_MAX        (4 * 1024 * 1024)
 #define PROM_VADDR           0x000ffd00000ULL
 #define APB_SPECIAL_BASE     0x1fe00000000ULL
@@ -181,14 +180,18 @@ static int sun4u_NVRAM_set_params(M48t59State
*nvram, uint16_t NVRAM_size,

     return 0;
 }
-static unsigned long sun4u_load_kernel(const char *kernel_filename,
-                                       const char *initrd_filename,
-                                       ram_addr_t RAM_size, long *initrd_size)
+
+static uint64_t sun4u_load_kernel(const char *kernel_filename,
+                                  const char *initrd_filename,
+                                  ram_addr_t RAM_size, uint64_t *initrd_size,
+                                  uint64_t *initrd_addr, uint64_t *kernel_addr,
+                                  uint64_t *kernel_entry)
 {
     int linux_boot;
     unsigned int i;
     long kernel_size;
     uint8_t *ptr;
+    uint64_t kernel_top;

     linux_boot = (kernel_filename != NULL);

@@ -201,29 +204,34 @@ static unsigned long sun4u_load_kernel(const
char *kernel_filename,
 #else
         bswap_needed = 0;
 #endif
-        kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
-                               NULL, NULL, 1, ELF_MACHINE, 0);
-        if (kernel_size < 0)
+        kernel_size = load_elf(kernel_filename, NULL, NULL, kernel_entry,
+                               kernel_addr, &kernel_top, 1, ELF_MACHINE, 0);
+        if (kernel_size < 0) {
+            *kernel_addr = KERNEL_LOAD_ADDR;
+            *kernel_entry = KERNEL_LOAD_ADDR;
             kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
                                     RAM_size - KERNEL_LOAD_ADDR, bswap_needed,
                                     TARGET_PAGE_SIZE);
-        if (kernel_size < 0)
+        }
+        if (kernel_size < 0) {
             kernel_size = load_image_targphys(kernel_filename,
                                               KERNEL_LOAD_ADDR,
                                               RAM_size - KERNEL_LOAD_ADDR);
+        }
         if (kernel_size < 0) {
             fprintf(stderr, "qemu: could not load kernel '%s'\n",
                     kernel_filename);
             exit(1);
         }
-
-        /* load initrd */
+        /* load initrd above kernel */
         *initrd_size = 0;
         if (initrd_filename) {
+            *initrd_addr = TARGET_PAGE_ALIGN(kernel_top);
+
             *initrd_size = load_image_targphys(initrd_filename,
-                                               INITRD_LOAD_ADDR,
-                                               RAM_size - INITRD_LOAD_ADDR);
-            if (*initrd_size < 0) {
+                                               *initrd_addr,
+                                               RAM_size - *initrd_addr);
+            if ((int)*initrd_size < 0) {
                 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
                         initrd_filename);
                 exit(1);
@@ -231,9 +239,9 @@ static unsigned long sun4u_load_kernel(const char
*kernel_filename,
         }
         if (*initrd_size > 0) {
             for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
-                ptr = rom_ptr(KERNEL_LOAD_ADDR + i);
+                ptr = rom_ptr(*kernel_addr + i);
                 if (ldl_p(ptr + 8) == 0x48647253) { /* HdrS */
-                    stl_p(ptr + 24, INITRD_LOAD_ADDR +
KERNEL_LOAD_ADDR - 0x4000);
+                    stl_p(ptr + 24, *initrd_addr + *kernel_addr);
                     stl_p(ptr + 28, *initrd_size);
                     break;
                 }
@@ -788,7 +796,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     CPUSPARCState *env;
     M48t59State *nvram;
     unsigned int i;
-    long initrd_size, kernel_size;
+    uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry;
     PCIBus *pci_bus, *pci_bus2, *pci_bus3;
     ISABus *isa_bus;
     qemu_irq *ivec_irqs, *pbm_irqs;
@@ -845,13 +853,15 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     nvram = m48t59_init_isa(isa_bus, 0x0074, NVRAM_SIZE, 59);

     initrd_size = 0;
+    initrd_addr = 0;
     kernel_size = sun4u_load_kernel(kernel_filename, initrd_filename,
-                                    ram_size, &initrd_size);
+                                    ram_size, &initrd_size, &initrd_addr,
+                                    &kernel_addr, &kernel_entry);

     sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", RAM_size, boot_devices,
-                           KERNEL_LOAD_ADDR, kernel_size,
+                           kernel_addr, kernel_size,
                            kernel_cmdline,
-                           INITRD_LOAD_ADDR, initrd_size,
+                           initrd_addr, initrd_size,
                            /* XXX: need an option to load a NVRAM image */
                            0,
                            graphic_width, graphic_height, graphic_depth,
@@ -861,8 +871,8 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
     fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
+    fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_entry);
+    fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
                        strlen(kernel_cmdline) + 1);
@@ -872,8 +882,8 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0);
     }
-    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
+    fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
+    fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
     fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_devices[0]);

     fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width);
-- 
1.7.10

[-- Attachment #2: 0001-sparc64-fix-initrd-loading.patch --]
[-- Type: text/x-patch, Size: 7438 bytes --]

From 2cfb4bf2421020af7d8e6c13596170267ca3d6ae Mon Sep 17 00:00:00 2001
Message-Id: <2cfb4bf2421020af7d8e6c13596170267ca3d6ae.1336843708.git.blauwirbel@gmail.com>
From: Blue Swirl <blauwirbel@gmail.com>
Date: Sat, 12 May 2012 17:20:52 +0000
Subject: [PATCH] sparc64: fix initrd loading

Initrd load address is too low, it conflicts with kernel load
address:
rom: requested regions overlap (rom phdr #0: /tmp/vmlinux-debian-6.0.4-sparc64. free=0x0000000000742519, addr=0x0000000000400000)
rom loading failed

Fix by making the initrd address variable, load initrd after kernel
image. Use 64 bit variables instead of longs or 32 bit types.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 hw/sun4u.c |   58 +++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/hw/sun4u.c b/hw/sun4u.c
index fe33138..739dc62 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -67,7 +67,6 @@
 
 #define KERNEL_LOAD_ADDR     0x00404000
 #define CMDLINE_ADDR         0x003ff000
-#define INITRD_LOAD_ADDR     0x00300000
 #define PROM_SIZE_MAX        (4 * 1024 * 1024)
 #define PROM_VADDR           0x000ffd00000ULL
 #define APB_SPECIAL_BASE     0x1fe00000000ULL
@@ -181,14 +180,18 @@ static int sun4u_NVRAM_set_params(M48t59State *nvram, uint16_t NVRAM_size,
 
     return 0;
 }
-static unsigned long sun4u_load_kernel(const char *kernel_filename,
-                                       const char *initrd_filename,
-                                       ram_addr_t RAM_size, long *initrd_size)
+
+static uint64_t sun4u_load_kernel(const char *kernel_filename,
+                                  const char *initrd_filename,
+                                  ram_addr_t RAM_size, uint64_t *initrd_size,
+                                  uint64_t *initrd_addr, uint64_t *kernel_addr,
+                                  uint64_t *kernel_entry)
 {
     int linux_boot;
     unsigned int i;
     long kernel_size;
     uint8_t *ptr;
+    uint64_t kernel_top;
 
     linux_boot = (kernel_filename != NULL);
 
@@ -201,29 +204,34 @@ static unsigned long sun4u_load_kernel(const char *kernel_filename,
 #else
         bswap_needed = 0;
 #endif
-        kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
-                               NULL, NULL, 1, ELF_MACHINE, 0);
-        if (kernel_size < 0)
+        kernel_size = load_elf(kernel_filename, NULL, NULL, kernel_entry,
+                               kernel_addr, &kernel_top, 1, ELF_MACHINE, 0);
+        if (kernel_size < 0) {
+            *kernel_addr = KERNEL_LOAD_ADDR;
+            *kernel_entry = KERNEL_LOAD_ADDR;
             kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
                                     RAM_size - KERNEL_LOAD_ADDR, bswap_needed,
                                     TARGET_PAGE_SIZE);
-        if (kernel_size < 0)
+        }
+        if (kernel_size < 0) {
             kernel_size = load_image_targphys(kernel_filename,
                                               KERNEL_LOAD_ADDR,
                                               RAM_size - KERNEL_LOAD_ADDR);
+        }
         if (kernel_size < 0) {
             fprintf(stderr, "qemu: could not load kernel '%s'\n",
                     kernel_filename);
             exit(1);
         }
-
-        /* load initrd */
+        /* load initrd above kernel */
         *initrd_size = 0;
         if (initrd_filename) {
+            *initrd_addr = TARGET_PAGE_ALIGN(kernel_top);
+
             *initrd_size = load_image_targphys(initrd_filename,
-                                               INITRD_LOAD_ADDR,
-                                               RAM_size - INITRD_LOAD_ADDR);
-            if (*initrd_size < 0) {
+                                               *initrd_addr,
+                                               RAM_size - *initrd_addr);
+            if ((int)*initrd_size < 0) {
                 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
                         initrd_filename);
                 exit(1);
@@ -231,9 +239,9 @@ static unsigned long sun4u_load_kernel(const char *kernel_filename,
         }
         if (*initrd_size > 0) {
             for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
-                ptr = rom_ptr(KERNEL_LOAD_ADDR + i);
+                ptr = rom_ptr(*kernel_addr + i);
                 if (ldl_p(ptr + 8) == 0x48647253) { /* HdrS */
-                    stl_p(ptr + 24, INITRD_LOAD_ADDR + KERNEL_LOAD_ADDR - 0x4000);
+                    stl_p(ptr + 24, *initrd_addr + *kernel_addr);
                     stl_p(ptr + 28, *initrd_size);
                     break;
                 }
@@ -788,7 +796,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     CPUSPARCState *env;
     M48t59State *nvram;
     unsigned int i;
-    long initrd_size, kernel_size;
+    uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry;
     PCIBus *pci_bus, *pci_bus2, *pci_bus3;
     ISABus *isa_bus;
     qemu_irq *ivec_irqs, *pbm_irqs;
@@ -845,13 +853,17 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     nvram = m48t59_init_isa(isa_bus, 0x0074, NVRAM_SIZE, 59);
 
     initrd_size = 0;
+    initrd_addr = 0;
     kernel_size = sun4u_load_kernel(kernel_filename, initrd_filename,
-                                    ram_size, &initrd_size);
+                                    ram_size, &initrd_size, &initrd_addr,
+                                    &kernel_addr, &kernel_entry);
 
+    fprintf(stderr, "kernel addr %"PRIx64" size %"PRIx64" entry %"PRIx64" initrd addr %"PRIx64" size %"PRIx64"\n",
+            kernel_addr, kernel_size, kernel_entry, initrd_addr, initrd_size);
     sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", RAM_size, boot_devices,
-                           KERNEL_LOAD_ADDR, kernel_size,
+                           kernel_addr, kernel_size,
                            kernel_cmdline,
-                           INITRD_LOAD_ADDR, initrd_size,
+                           initrd_addr, initrd_size,
                            /* XXX: need an option to load a NVRAM image */
                            0,
                            graphic_width, graphic_height, graphic_depth,
@@ -861,8 +873,8 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
     fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
+    fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_entry);
+    fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
     if (kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
                        strlen(kernel_cmdline) + 1);
@@ -872,8 +884,8 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0);
     }
-    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
-    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
+    fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
+    fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
     fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_devices[0]);
 
     fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width);
-- 
1.7.2.5


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [PATCH 1.1] sparc64: fix initrd loading
  2012-05-12 17:30 [Qemu-devel] [PATCH 1.1] sparc64: fix initrd loading Blue Swirl
@ 2012-05-12 18:52 ` Artyom Tarasenko
  2012-05-19 19:00   ` Blue Swirl
  0 siblings, 1 reply; 3+ messages in thread
From: Artyom Tarasenko @ 2012-05-12 18:52 UTC (permalink / raw)
  To: Blue Swirl; +Cc: qemu-devel

This was an annoying bug, thanks for fixing it!

Tested-by: Artyom Tarasenko <atar4qemu@gmail.com>

On Sat, May 12, 2012 at 7:30 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
> Initrd load address is too low, it conflicts with kernel load
> address:
> rom: requested regions overlap (rom phdr #0:
> /tmp/vmlinux-debian-6.0.4-sparc64. free=0x0000000000742519,
> addr=0x0000000000400000)
> rom loading failed
>
> Fix by making the initrd address variable, load initrd after kernel
> image. Use 64 bit variables instead of longs or 32 bit types.
>
> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
> ---
>  hw/sun4u.c |   56 +++++++++++++++++++++++++++++++++-----------------------
>  1 file changed, 33 insertions(+), 23 deletions(-)
>
> diff --git a/hw/sun4u.c b/hw/sun4u.c
> index fe33138..517bdb8 100644
> --- a/hw/sun4u.c
> +++ b/hw/sun4u.c
> @@ -67,7 +67,6 @@
>
>  #define KERNEL_LOAD_ADDR     0x00404000
>  #define CMDLINE_ADDR         0x003ff000
> -#define INITRD_LOAD_ADDR     0x00300000
>  #define PROM_SIZE_MAX        (4 * 1024 * 1024)
>  #define PROM_VADDR           0x000ffd00000ULL
>  #define APB_SPECIAL_BASE     0x1fe00000000ULL
> @@ -181,14 +180,18 @@ static int sun4u_NVRAM_set_params(M48t59State
> *nvram, uint16_t NVRAM_size,
>
>     return 0;
>  }
> -static unsigned long sun4u_load_kernel(const char *kernel_filename,
> -                                       const char *initrd_filename,
> -                                       ram_addr_t RAM_size, long *initrd_size)
> +
> +static uint64_t sun4u_load_kernel(const char *kernel_filename,
> +                                  const char *initrd_filename,
> +                                  ram_addr_t RAM_size, uint64_t *initrd_size,
> +                                  uint64_t *initrd_addr, uint64_t *kernel_addr,
> +                                  uint64_t *kernel_entry)
>  {
>     int linux_boot;
>     unsigned int i;
>     long kernel_size;
>     uint8_t *ptr;
> +    uint64_t kernel_top;
>
>     linux_boot = (kernel_filename != NULL);
>
> @@ -201,29 +204,34 @@ static unsigned long sun4u_load_kernel(const
> char *kernel_filename,
>  #else
>         bswap_needed = 0;
>  #endif
> -        kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
> -                               NULL, NULL, 1, ELF_MACHINE, 0);
> -        if (kernel_size < 0)
> +        kernel_size = load_elf(kernel_filename, NULL, NULL, kernel_entry,
> +                               kernel_addr, &kernel_top, 1, ELF_MACHINE, 0);
> +        if (kernel_size < 0) {
> +            *kernel_addr = KERNEL_LOAD_ADDR;
> +            *kernel_entry = KERNEL_LOAD_ADDR;
>             kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
>                                     RAM_size - KERNEL_LOAD_ADDR, bswap_needed,
>                                     TARGET_PAGE_SIZE);
> -        if (kernel_size < 0)
> +        }
> +        if (kernel_size < 0) {
>             kernel_size = load_image_targphys(kernel_filename,
>                                               KERNEL_LOAD_ADDR,
>                                               RAM_size - KERNEL_LOAD_ADDR);
> +        }
>         if (kernel_size < 0) {
>             fprintf(stderr, "qemu: could not load kernel '%s'\n",
>                     kernel_filename);
>             exit(1);
>         }
> -
> -        /* load initrd */
> +        /* load initrd above kernel */
>         *initrd_size = 0;
>         if (initrd_filename) {
> +            *initrd_addr = TARGET_PAGE_ALIGN(kernel_top);
> +
>             *initrd_size = load_image_targphys(initrd_filename,
> -                                               INITRD_LOAD_ADDR,
> -                                               RAM_size - INITRD_LOAD_ADDR);
> -            if (*initrd_size < 0) {
> +                                               *initrd_addr,
> +                                               RAM_size - *initrd_addr);
> +            if ((int)*initrd_size < 0) {
>                 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
>                         initrd_filename);
>                 exit(1);
> @@ -231,9 +239,9 @@ static unsigned long sun4u_load_kernel(const char
> *kernel_filename,
>         }
>         if (*initrd_size > 0) {
>             for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
> -                ptr = rom_ptr(KERNEL_LOAD_ADDR + i);
> +                ptr = rom_ptr(*kernel_addr + i);
>                 if (ldl_p(ptr + 8) == 0x48647253) { /* HdrS */
> -                    stl_p(ptr + 24, INITRD_LOAD_ADDR +
> KERNEL_LOAD_ADDR - 0x4000);
> +                    stl_p(ptr + 24, *initrd_addr + *kernel_addr);
>                     stl_p(ptr + 28, *initrd_size);
>                     break;
>                 }
> @@ -788,7 +796,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
>     CPUSPARCState *env;
>     M48t59State *nvram;
>     unsigned int i;
> -    long initrd_size, kernel_size;
> +    uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry;
>     PCIBus *pci_bus, *pci_bus2, *pci_bus3;
>     ISABus *isa_bus;
>     qemu_irq *ivec_irqs, *pbm_irqs;
> @@ -845,13 +853,15 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
>     nvram = m48t59_init_isa(isa_bus, 0x0074, NVRAM_SIZE, 59);
>
>     initrd_size = 0;
> +    initrd_addr = 0;
>     kernel_size = sun4u_load_kernel(kernel_filename, initrd_filename,
> -                                    ram_size, &initrd_size);
> +                                    ram_size, &initrd_size, &initrd_addr,
> +                                    &kernel_addr, &kernel_entry);
>
>     sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", RAM_size, boot_devices,
> -                           KERNEL_LOAD_ADDR, kernel_size,
> +                           kernel_addr, kernel_size,
>                            kernel_cmdline,
> -                           INITRD_LOAD_ADDR, initrd_size,
> +                           initrd_addr, initrd_size,
>                            /* XXX: need an option to load a NVRAM image */
>                            0,
>                            graphic_width, graphic_height, graphic_depth,
> @@ -861,8 +871,8 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
>     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
>     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
>     fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
> -    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
> -    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
> +    fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_entry);
> +    fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
>     if (kernel_cmdline) {
>         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
>                        strlen(kernel_cmdline) + 1);
> @@ -872,8 +882,8 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
>     } else {
>         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0);
>     }
> -    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
> -    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
> +    fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
> +    fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
>     fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_devices[0]);
>
>     fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width);
> --
> 1.7.10



-- 
Regards,
Artyom Tarasenko

solaris/sparc under qemu blog: http://tyom.blogspot.com/search/label/qemu

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [PATCH 1.1] sparc64: fix initrd loading
  2012-05-12 18:52 ` Artyom Tarasenko
@ 2012-05-19 19:00   ` Blue Swirl
  0 siblings, 0 replies; 3+ messages in thread
From: Blue Swirl @ 2012-05-19 19:00 UTC (permalink / raw)
  To: Artyom Tarasenko; +Cc: qemu-devel

On Sat, May 12, 2012 at 6:52 PM, Artyom Tarasenko <atar4qemu@gmail.com> wrote:
> This was an annoying bug, thanks for fixing it!
>
> Tested-by: Artyom Tarasenko <atar4qemu@gmail.com>

Applied.

>
> On Sat, May 12, 2012 at 7:30 PM, Blue Swirl <blauwirbel@gmail.com> wrote:
>> Initrd load address is too low, it conflicts with kernel load
>> address:
>> rom: requested regions overlap (rom phdr #0:
>> /tmp/vmlinux-debian-6.0.4-sparc64. free=0x0000000000742519,
>> addr=0x0000000000400000)
>> rom loading failed
>>
>> Fix by making the initrd address variable, load initrd after kernel
>> image. Use 64 bit variables instead of longs or 32 bit types.
>>
>> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
>> ---
>>  hw/sun4u.c |   56 +++++++++++++++++++++++++++++++++-----------------------
>>  1 file changed, 33 insertions(+), 23 deletions(-)
>>
>> diff --git a/hw/sun4u.c b/hw/sun4u.c
>> index fe33138..517bdb8 100644
>> --- a/hw/sun4u.c
>> +++ b/hw/sun4u.c
>> @@ -67,7 +67,6 @@
>>
>>  #define KERNEL_LOAD_ADDR     0x00404000
>>  #define CMDLINE_ADDR         0x003ff000
>> -#define INITRD_LOAD_ADDR     0x00300000
>>  #define PROM_SIZE_MAX        (4 * 1024 * 1024)
>>  #define PROM_VADDR           0x000ffd00000ULL
>>  #define APB_SPECIAL_BASE     0x1fe00000000ULL
>> @@ -181,14 +180,18 @@ static int sun4u_NVRAM_set_params(M48t59State
>> *nvram, uint16_t NVRAM_size,
>>
>>     return 0;
>>  }
>> -static unsigned long sun4u_load_kernel(const char *kernel_filename,
>> -                                       const char *initrd_filename,
>> -                                       ram_addr_t RAM_size, long *initrd_size)
>> +
>> +static uint64_t sun4u_load_kernel(const char *kernel_filename,
>> +                                  const char *initrd_filename,
>> +                                  ram_addr_t RAM_size, uint64_t *initrd_size,
>> +                                  uint64_t *initrd_addr, uint64_t *kernel_addr,
>> +                                  uint64_t *kernel_entry)
>>  {
>>     int linux_boot;
>>     unsigned int i;
>>     long kernel_size;
>>     uint8_t *ptr;
>> +    uint64_t kernel_top;
>>
>>     linux_boot = (kernel_filename != NULL);
>>
>> @@ -201,29 +204,34 @@ static unsigned long sun4u_load_kernel(const
>> char *kernel_filename,
>>  #else
>>         bswap_needed = 0;
>>  #endif
>> -        kernel_size = load_elf(kernel_filename, NULL, NULL, NULL,
>> -                               NULL, NULL, 1, ELF_MACHINE, 0);
>> -        if (kernel_size < 0)
>> +        kernel_size = load_elf(kernel_filename, NULL, NULL, kernel_entry,
>> +                               kernel_addr, &kernel_top, 1, ELF_MACHINE, 0);
>> +        if (kernel_size < 0) {
>> +            *kernel_addr = KERNEL_LOAD_ADDR;
>> +            *kernel_entry = KERNEL_LOAD_ADDR;
>>             kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
>>                                     RAM_size - KERNEL_LOAD_ADDR, bswap_needed,
>>                                     TARGET_PAGE_SIZE);
>> -        if (kernel_size < 0)
>> +        }
>> +        if (kernel_size < 0) {
>>             kernel_size = load_image_targphys(kernel_filename,
>>                                               KERNEL_LOAD_ADDR,
>>                                               RAM_size - KERNEL_LOAD_ADDR);
>> +        }
>>         if (kernel_size < 0) {
>>             fprintf(stderr, "qemu: could not load kernel '%s'\n",
>>                     kernel_filename);
>>             exit(1);
>>         }
>> -
>> -        /* load initrd */
>> +        /* load initrd above kernel */
>>         *initrd_size = 0;
>>         if (initrd_filename) {
>> +            *initrd_addr = TARGET_PAGE_ALIGN(kernel_top);
>> +
>>             *initrd_size = load_image_targphys(initrd_filename,
>> -                                               INITRD_LOAD_ADDR,
>> -                                               RAM_size - INITRD_LOAD_ADDR);
>> -            if (*initrd_size < 0) {
>> +                                               *initrd_addr,
>> +                                               RAM_size - *initrd_addr);
>> +            if ((int)*initrd_size < 0) {
>>                 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
>>                         initrd_filename);
>>                 exit(1);
>> @@ -231,9 +239,9 @@ static unsigned long sun4u_load_kernel(const char
>> *kernel_filename,
>>         }
>>         if (*initrd_size > 0) {
>>             for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
>> -                ptr = rom_ptr(KERNEL_LOAD_ADDR + i);
>> +                ptr = rom_ptr(*kernel_addr + i);
>>                 if (ldl_p(ptr + 8) == 0x48647253) { /* HdrS */
>> -                    stl_p(ptr + 24, INITRD_LOAD_ADDR +
>> KERNEL_LOAD_ADDR - 0x4000);
>> +                    stl_p(ptr + 24, *initrd_addr + *kernel_addr);
>>                     stl_p(ptr + 28, *initrd_size);
>>                     break;
>>                 }
>> @@ -788,7 +796,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
>>     CPUSPARCState *env;
>>     M48t59State *nvram;
>>     unsigned int i;
>> -    long initrd_size, kernel_size;
>> +    uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry;
>>     PCIBus *pci_bus, *pci_bus2, *pci_bus3;
>>     ISABus *isa_bus;
>>     qemu_irq *ivec_irqs, *pbm_irqs;
>> @@ -845,13 +853,15 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
>>     nvram = m48t59_init_isa(isa_bus, 0x0074, NVRAM_SIZE, 59);
>>
>>     initrd_size = 0;
>> +    initrd_addr = 0;
>>     kernel_size = sun4u_load_kernel(kernel_filename, initrd_filename,
>> -                                    ram_size, &initrd_size);
>> +                                    ram_size, &initrd_size, &initrd_addr,
>> +                                    &kernel_addr, &kernel_entry);
>>
>>     sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", RAM_size, boot_devices,
>> -                           KERNEL_LOAD_ADDR, kernel_size,
>> +                           kernel_addr, kernel_size,
>>                            kernel_cmdline,
>> -                           INITRD_LOAD_ADDR, initrd_size,
>> +                           initrd_addr, initrd_size,
>>                            /* XXX: need an option to load a NVRAM image */
>>                            0,
>>                            graphic_width, graphic_height, graphic_depth,
>> @@ -861,8 +871,8 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
>>     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
>>     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
>>     fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
>> -    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, KERNEL_LOAD_ADDR);
>> -    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
>> +    fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_entry);
>> +    fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
>>     if (kernel_cmdline) {
>>         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
>>                        strlen(kernel_cmdline) + 1);
>> @@ -872,8 +882,8 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
>>     } else {
>>         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0);
>>     }
>> -    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, INITRD_LOAD_ADDR);
>> -    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
>> +    fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
>> +    fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
>>     fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_devices[0]);
>>
>>     fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width);
>> --
>> 1.7.10
>
>
>
> --
> Regards,
> Artyom Tarasenko
>
> solaris/sparc under qemu blog: http://tyom.blogspot.com/search/label/qemu

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-05-19 19:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-12 17:30 [Qemu-devel] [PATCH 1.1] sparc64: fix initrd loading Blue Swirl
2012-05-12 18:52 ` Artyom Tarasenko
2012-05-19 19:00   ` Blue Swirl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).