WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ppc-devel

[XenPPC] [rfc][patch] dom0 elf32 loading to load a zImage

To: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Subject: [XenPPC] [rfc][patch] dom0 elf32 loading to load a zImage
From: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
Date: Tue, 27 Jun 2006 15:25:45 -0400
Delivery-date: Tue, 27 Jun 2006 12:25:28 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ppc-devel-request@lists.xensource.com?subject=help>
List-id: Xen PPC development <xen-ppc-devel.lists.xensource.com>
List-post: <mailto:xen-ppc-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-ppc-devel-bounces@xxxxxxxxxxxxxxxxxxx
WANRNING: This is a total insomnia hack!

It has concerned me for quite some time that we will need to boot dom0
with a a ramdisk, and our current boot loading mechanisms do not
easily support it.  One solution could be a zImage.

I think someone outside of IBM was making noises about a generic elf
loader but I figured until that happens the following patch will do.

It loads and runs a 64 vmlinux or a 32 bit zImage and runs it.

BTW: uncompressing kernel under mambo is way faster

It requires a single line change in common code.
xen/arch/ppc/elf32.c is dubious but easier then the necessary
makefile majik.

Comments welcome.

-JX


diff -r d6a49aaee312 xen/arch/ppc/Makefile
--- a/xen/arch/ppc/Makefile     Mon Jun 26 16:08:27 2006 -0500
+++ b/xen/arch/ppc/Makefile     Tue Jun 27 15:19:09 2006 -0400
@@ -41,6 +41,8 @@ obj-$(builtin_dom0) += dom0.o
 obj-$(builtin_dom0) += dom0.o
 
 obj-y += firmware_image.o
+
+obj-y += elf32.o
 
 CFLAGS += -Wundef -Wpointer-arith
 CFLAGS += -Wmissing-prototypes -Wmissing-declarations -Wpacked
diff -r d6a49aaee312 xen/arch/ppc/domain_build.c
--- a/xen/arch/ppc/domain_build.c       Mon Jun 26 16:08:27 2006 -0500
+++ b/xen/arch/ppc/domain_build.c       Tue Jun 27 15:19:09 2006 -0400
@@ -30,8 +30,10 @@
 #include <asm/papr.h>
 #include "oftree.h"
 
+extern int parseelfimage_32(struct domain_setup_info *dsi);
+extern int loadelfimage_32(struct domain_setup_info *dsi);
+
 /* opt_dom0_mem: memory allocated to domain 0. */
-
 static unsigned int opt_dom0_mem;
 static void parse_dom0_mem(char *s)
 {
@@ -46,23 +48,16 @@ custom_param("dom0_mem", parse_dom0_mem)
 
 int elf_sanity_check(Elf_Ehdr *ehdr)
 {
-#if !defined(ELFSIZE)
-#error "Must pick a default ELFSIZE"
-#endif
-
     if (IS_ELF(*ehdr))
-#if ELFSIZE == 32
-        if (ehdr->e_ident[EI_CLASS] == ELFCLASS32
-            && ehdr->e_machine == EM_PPC)
-#elif ELFSIZE == 64
-        if (ehdr->e_ident[EI_CLASS] == ELFCLASS64
-             && ehdr->e_machine == EM_PPC64)
-#else
-#error "unknown ELFSIZE"
-#endif
+        /* we are happy with either */
+        if ((ehdr->e_ident[EI_CLASS] == ELFCLASS32
+             && ehdr->e_machine == EM_PPC)
+            || (ehdr->e_ident[EI_CLASS] == ELFCLASS64
+                && ehdr->e_machine == EM_PPC64)) {
             if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB
-                 && ehdr->e_type == ET_EXEC)
+                && ehdr->e_type == ET_EXEC)
                 return 1;
+        }
     printk("DOM0 image is not a Xen-compatible Elf image.\n");
     return 0;
 }
@@ -70,24 +65,20 @@ int elf_sanity_check(Elf_Ehdr *ehdr)
 /* adapted from common/elf.c */
 #define RM_MASK(a,l) ((a) & ((1UL << (l)) - 1))
 
-static inline int is_loadable_phdr(Elf_Phdr *phdr)
-{
-    return ((phdr->p_type == PT_LOAD) &&
-            ((phdr->p_flags & (PF_W|PF_X)) != 0));
-}
-
-static int rm_loadelfimage(struct domain_setup_info *dsi, ulong rma)
+static int rm_loadelfimage_64(struct domain_setup_info *dsi, ulong rma)
 {
     char *elfbase = (char *)dsi->image_addr;
-    Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr;
-    Elf_Phdr *phdr;
+    Elf64_Ehdr *ehdr = (Elf64_Ehdr *)dsi->image_addr;
+    Elf64_Phdr *phdr;
     int h;
   
     for (h = 0; h < ehdr->e_phnum; h++ ) 
     {
-        phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
-        if (!is_loadable_phdr(phdr))
+        phdr = (Elf64_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
+        if (!((phdr->p_type == PT_LOAD) &&
+             ((phdr->p_flags & (PF_W|PF_X)) != 0)))
             continue;
+
         if (phdr->p_filesz != 0)
             memcpy((char *)(rma + RM_MASK(phdr->p_paddr, 42)),
                    elfbase + phdr->p_offset, 
@@ -118,6 +109,10 @@ int construct_dom0(struct domain *d,
     ulong rma = d->arch.rma_base;
     start_info_t *si;
     ulong eomem;
+    int am64 = 1;
+    ulong msr;
+    ulong pc;
+    ulong r2;
 
     /* Sanity! */
     BUG_ON(d->domain_id != 0);
@@ -129,8 +124,11 @@ int construct_dom0(struct domain *d,
     dsi.image_addr = image_start;
     dsi.image_len  = image_len;
 
-    if ((rc = parseelfimage(&dsi)) != 0)
-        return rc;
+    if ((rc = parseelfimage(&dsi)) != 0) {
+        if ((rc = parseelfimage_32(&dsi)) != 0)
+            return rc;
+        am64 = 0;
+    }
 
     /* elf contains virtual addresses that can have the upper bits
      * masked while running in real mode, so we do the masking as well
@@ -186,10 +184,6 @@ int construct_dom0(struct domain *d,
     /* copy relative to Xen */
     dst += rma;
 
-
-    extern int firmware_image_start[0];
-    extern int firmware_image_size[0];
-
     ASSERT((dst - rma) + (ulong)firmware_image_size < eomem);
     printk("loading OFH: 0x%lx, RMA: 0x%lx\n", dst, dst - rma);
     memcpy((void *)dst, firmware_image_start, (ulong)firmware_image_size);
@@ -208,27 +202,58 @@ int construct_dom0(struct domain *d,
     memcpy((void *)dst, (void *)oftree, oftree_len);
 
     dst = ALIGN_UP(dst + oftree_len, PAGE_SIZE);
-    printk("loading Dom0: 0x%lx, in RMA:0x%lx\n", dst, dst - rma);
-    rm_loadelfimage(&dsi, dst);
-
-    ulong kbase = dst;
-
-    /* move dst to end of bss */
-    dst = ALIGN_UP(dsi.v_kernend + dst, PAGE_SIZE);
-    if ( initrd_len > 0 ) {
-        ASSERT( (dst - rma) + image_len < eomem );
-
-        printk("loading initrd: 0x%lx, 0x%lx\n", dst, initrd_len);
-        memcpy((void *)dst, (void *)initrd_start, initrd_len);
-
-        si->mod_start = dst - rma;
-        si->mod_len = image_len;
-
-        dst = ALIGN_UP(dst + initrd_len, PAGE_SIZE);
+
+    if (am64) {
+        ulong kbase;
+        ulong *fdesc;
+
+        printk("loading 64-bit Dom0: 0x%lx, in RMA:0x%lx\n", dst, dst - rma);
+        rm_loadelfimage_64(&dsi, dst);
+
+        kbase = dst;
+        /* move dst to end of bss */
+        dst = ALIGN_UP(dsi.v_kernend + dst, PAGE_SIZE);
+
+        if ( initrd_len > 0 ) {
+            ASSERT( (dst - rma) + image_len < eomem );
+
+            printk("loading initrd: 0x%lx, 0x%lx\n", dst, initrd_len);
+            memcpy((void *)dst, (void *)initrd_start, initrd_len);
+
+            si->mod_start = dst - rma;
+            si->mod_len = image_len;
+
+            dst = ALIGN_UP(dst + initrd_len, PAGE_SIZE);
+        } else {
+            printk("no initrd\n");
+            si->mod_start = 0;
+            si->mod_len = 0;
+        }
+        /* it may be a function descriptor */
+        fdesc = (ulong *)(dsi.v_kernstart + dsi.v_kernentry + kbase);
+
+        if (fdesc[2] == 0
+            && ((fdesc[0] >= dsi.v_kernstart)
+                && (fdesc[0] < dsi.v_kernend)) /* text entry is in range */
+            && ((fdesc[1] >= dsi.v_kernstart)  /* toc can be > image */
+                && (fdesc[1] < (dsi.v_kernend + (0x7fff * sizeof (ulong)))))) {
+            /* it is almost certainly a function descriptor */
+            pc = RM_MASK(fdesc[0], 42) + kbase - rma;
+            r2 = RM_MASK(fdesc[1], 42) + kbase - rma;
+        } else {
+            pc = ((ulong)fdesc) - rma;
+            r2 = 0;
+        }
+        msr = MSR_SF;
     } else {
-        printk("no initrd\n");
-        si->mod_start = 0;
-        si->mod_len = 0;
+        printk("loading 32-bit Dom0: 0x%lx, in RMA:0x%lx\n",
+               dsi.v_kernstart + rma, dsi.v_kernstart);
+        dsi.v_start = rma;
+        loadelfimage_32(&dsi);
+
+        pc = dsi.v_kernentry;
+        r2 = 0;
+        msr = 0;
     }
 
     v->arch.ctxt.gprs[3] = si->mod_start;
@@ -238,26 +263,7 @@ int construct_dom0(struct domain *d,
     if ( cmdline != NULL )
         strncpy((char *)si->cmd_line, cmdline, sizeof(si->cmd_line)-1);
 
-    /* set up the MSR how we like it */
-    v->arch.ctxt.msr = MSR_SF;
-
-    ulong *fdesc = (ulong *)(dsi.v_kernstart + dsi.v_kernentry + kbase);
-    ulong pc;
-    ulong r2;
-
-    if (fdesc[2] == 0  /* could be a true function descriptor */
-        && ((fdesc[0] >= dsi.v_kernstart)
-            && (fdesc[0] < dsi.v_kernend)) /* text entry is in range */
-        && ((fdesc[1] >= dsi.v_kernstart)  /* toc can be greater than image */
-            && (fdesc[1] < (dsi.v_kernend + (0x7fff * sizeof (ulong)))))) {
-        /* it is almost certainly a function descriptor */
-        pc = RM_MASK(fdesc[0], 42) + kbase - rma;
-        r2 = RM_MASK(fdesc[1], 42) + kbase - rma;
-    } else {
-        pc = ((ulong)fdesc) - rma;
-        r2 = 0;
-    }
-
+    v->arch.ctxt.msr = msr;
     v->arch.ctxt.pc = pc;
     v->arch.ctxt.gprs[2] = r2;
 
diff -r d6a49aaee312 xen/arch/ppc/oftree.h
--- a/xen/arch/ppc/oftree.h     Mon Jun 26 16:08:27 2006 -0500
+++ b/xen/arch/ppc/oftree.h     Tue Jun 27 15:19:09 2006 -0400
@@ -27,4 +27,7 @@ extern int ofd_dom0_fixup(
 extern int ofd_dom0_fixup(
     struct domain *d, ulong oftree, start_info_t *si, ulong dst);
 
+extern int firmware_image_start[0];
+extern int firmware_image_size[0];
+
 #endif  /* #ifndef _OFTREE_H */
diff -r d6a49aaee312 xen/common/elf.c
--- a/xen/common/elf.c  Mon Jun 26 16:08:27 2006 -0500
+++ b/xen/common/elf.c  Tue Jun 27 15:19:09 2006 -0400
@@ -23,7 +23,7 @@ int parseelfimage(struct domain_setup_in
     Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr;
     Elf_Phdr *phdr;
     Elf_Shdr *shdr;
-    unsigned long kernstart = ~0UL, kernend=0UL, vaddr, virt_base, elf_pa_off;
+    Elf_Addr kernstart = -1, kernend = 0, vaddr, virt_base, elf_pa_off;
     char *shstrtab, *guestinfo=NULL, *p;
     char *elfbase = (char *)dsi->image_addr;
     int h, virt_base_defined, elf_pa_off_defined;
diff -r d6a49aaee312 xen/include/asm-ppc/config.h
--- a/xen/include/asm-ppc/config.h      Mon Jun 26 16:08:27 2006 -0500
+++ b/xen/include/asm-ppc/config.h      Tue Jun 27 15:19:09 2006 -0400
@@ -52,7 +52,9 @@ extern char __bss_start[];
 #define CONFIG_PCI 1
 #define NR_CPUS 1
 
+#ifndef ELFSIZE
 #define ELFSIZE 64
+#endif
 
 #define asmlinkage
 
diff -r d6a49aaee312 xen/arch/ppc/elf32.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/ppc/elf32.c      Tue Jun 27 15:19:09 2006 -0400
@@ -0,0 +1,5 @@
+#define parseelfimage parseelfimage_32
+#define loadelfimage loadelfimage_32
+#define ELFSIZE 32
+#include "../../common/elf.c"
+

_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [XenPPC] [rfc][patch] dom0 elf32 loading to load a zImage, Jimi Xenidis <=