Patchwork s390: Rework kernel loading: supports elf and newer kernels

login
register
mail settings
Submitter Christian Borntraeger
Date Dec. 30, 2011, 9:10 a.m.
Message ID <1325236226-2949-1-git-send-email-borntraeger@de.ibm.com>
Download mbox | patch
Permalink /patch/133622/
State New
Headers show

Comments

Christian Borntraeger - Dec. 30, 2011, 9:10 a.m.
This reworks the image loading on s390.

Newer kernels will not always have a 0dd0 (basr 13,0) at address 0x10000.
We must not rely on specific code at certain  addresses. This check was
introduced to warn users that tried to load vmlinux, since ELF loading
was not supported. Lets wire that up. If elf loading fails, we assume
that this is a standard kernel image and load that via load_image_targphys.
This patch also changes all other users of load_image to
load_image_targphys to be consistent. (the elf loader registers the kernel
as rom).

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
 hw/s390-virtio.c |   30 ++++++++++++++++++------------
 1 files changed, 18 insertions(+), 12 deletions(-)
Alexander Graf - Jan. 9, 2012, 1:25 p.m.
On 30.12.2011, at 10:10, Christian Borntraeger wrote:

> This reworks the image loading on s390.
> 
> Newer kernels will not always have a 0dd0 (basr 13,0) at address 0x10000.
> We must not rely on specific code at certain  addresses. This check was
> introduced to warn users that tried to load vmlinux, since ELF loading
> was not supported. Lets wire that up. If elf loading fails, we assume
> that this is a standard kernel image and load that via load_image_targphys.
> This patch also changes all other users of load_image to
> load_image_targphys to be consistent. (the elf loader registers the kernel
> as rom).
> 
> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>

Thanks, applied to s390-next.


Alex

Patch

diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 61b67e8..c17e7f8 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -223,13 +223,17 @@  static void s390_init(ram_addr_t my_ram_size,
     s390_add_running_cpu(env);
 
     if (kernel_filename) {
-        kernel_size = load_image(kernel_filename, qemu_get_ram_ptr(0));
 
-        if (lduw_be_phys(KERN_IMAGE_START) != 0x0dd0) {
-            fprintf(stderr, "Specified image is not an s390 boot image\n");
-            exit(1);
+        kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, NULL,
+                               NULL, 1, ELF_MACHINE, 0);
+        if (kernel_size == -1UL) {
+            kernel_size = load_image_targphys(kernel_filename, 0, ram_size);
         }
-
+        /*
+         * we can not rely on the ELF entry point, since up to 3.2 this
+         * value was 0x800 (the SALIPL loader) and it wont work. For
+         * all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine.
+         */
         env->psw.addr = KERN_IMAGE_START;
         env->psw.mask = 0x0000000180000000ULL;
     } else {
@@ -242,7 +246,7 @@  static void s390_init(ram_addr_t my_ram_size,
         }
 
         bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-        bios_size = load_image(bios_filename, qemu_get_ram_ptr(ZIPL_LOAD_ADDR));
+        bios_size = load_image_targphys(bios_filename, ZIPL_LOAD_ADDR, 4096);
         g_free(bios_filename);
 
         if ((long)bios_size < 0) {
@@ -262,15 +266,17 @@  static void s390_init(ram_addr_t my_ram_size,
         while (kernel_size + 0x100000 > initrd_offset) {
             initrd_offset += 0x100000;
         }
-        initrd_size = load_image(initrd_filename, qemu_get_ram_ptr(initrd_offset));
-
-        stq_be_phys(INITRD_PARM_START, initrd_offset);
-        stq_be_phys(INITRD_PARM_SIZE, initrd_size);
+        initrd_size = load_image_targphys(initrd_filename, initrd_offset,
+                                          ram_size - initrd_offset);
+        /* we have to overwrite values in the kernel image, which are "rom" */
+        memcpy(rom_ptr(INITRD_PARM_START), &initrd_offset, 8);
+        memcpy(rom_ptr(INITRD_PARM_SIZE), &initrd_size, 8);
     }
 
     if (kernel_cmdline) {
-        cpu_physical_memory_write(KERN_PARM_AREA, kernel_cmdline,
-                                  strlen(kernel_cmdline) + 1);
+        /* we have to overwrite values in the kernel image, which are "rom" */
+        memcpy(rom_ptr(KERN_PARM_AREA), kernel_cmdline,
+               strlen(kernel_cmdline) + 1);
     }
 
     /* Create VirtIO network adapters */