* [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).