rpms/xen/devel xen-hvm-kernel-boot-nonrelocatable.patch, 1.1.2.1, 1.1.2.2 xen.spec, 1.194.2.11, 1.194.2.12

Daniel P. Berrange (berrange) fedora-extras-commits at redhat.com
Wed Dec 19 05:00:45 UTC 2007


Author: berrange

Update of /cvs/pkgs/rpms/xen/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv25479

Modified Files:
      Tag: private-berrange-xen-unstable
	xen-hvm-kernel-boot-nonrelocatable.patch xen.spec 
Log Message:
Non-relocatable kernels actually boot.

xen-hvm-kernel-boot-nonrelocatable.patch:

Index: xen-hvm-kernel-boot-nonrelocatable.patch
===================================================================
RCS file: /cvs/pkgs/rpms/xen/devel/Attic/xen-hvm-kernel-boot-nonrelocatable.patch,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- xen-hvm-kernel-boot-nonrelocatable.patch	18 Dec 2007 17:14:31 -0000	1.1.2.1
+++ xen-hvm-kernel-boot-nonrelocatable.patch	19 Dec 2007 05:00:41 -0000	1.1.2.2
@@ -1,81 +1,97 @@
-diff -r f5607a660419 tools/ioemu/hw/pc.c
---- a/tools/ioemu/hw/pc.c	Mon Nov 05 09:20:52 2007 -0500
-+++ b/tools/ioemu/hw/pc.c	Mon Nov 05 09:28:17 2007 -0500
-@@ -418,6 +418,73 @@ static void generate_bootsect(uint32_t g
+--- xen-unstable-16606.orig/tools/ioemu/hw/pc.c	2007-12-18 14:15:17.000000000 -0500
++++ xen-unstable-16606/tools/ioemu/hw/pc.c	2007-12-18 23:53:56.000000000 -0500
+@@ -417,6 +417,90 @@ static void generate_bootsect(uint32_t g
+     bdrv_set_boot_sector(bs_table[0], bootsect, sizeof(bootsect));
  }
  
- 
 +/*
-+ * We have a non-relocatable kernel loaded at some address like src=0x200000
-+ * which is cnt=1234567 bytes in length
-+ * 
-+ * Before we run this kernel though, we need to move it to dst=0x100000
-+ *
-+ * So we put the following snippet of asm at addr=0x200000+kernel_size
-+ * which basically does memmove(0x10000, 0x20000, cnt). code32_start in
-+ * the realmode header is set to addr=0x20000+kenrel_size, so that it runs 
-+ * our little helper. The last thing our helper does is jump to the final
-+ * address 0x10000
-+ *
-+ * Except this code below rarely works. We're overwriting something important
-+ * somewhere or getting some register setup wrong. Who knows. The general
-+ * idea seems to work - we sometimes partially boot at least. Mere matter of
-+ * fixing the bugs.....
++ * Evil helper for non-relocatable kernels
++ *
++ * So it works out like this:
++ *
++ *  0x100000  - Xen HVM firmware lives here. Kernel wants to boot here
++ *
++ * You can't both live there and HVM firmware is needed first, thus
++ * our plan is
++ *
++ *  0x200000              - kernel is loaded here by QEMU
++ *  0x200000+kernel_size  - helper code is put here by QEMU
++ *
++ * code32_switch in kernel header is set to point at out helper
++ * code at 0x200000+kernel_size
++ *
++ * Our helper basically does memmove(0x100000,0x200000,kernel_size)
++ * and then jmps to  0x1000000.
++ *
++ * So we've overwritten the HVM firmware (which was no longer
++ * needed) and the non-relocatable kernel can happily boot
++ * at its usual address.
++ *
++ * Simple, eh ?
++ *
++ * Well the assembler needed to do this is fairly short:
++ *
++ *  # Load segments
++ *    cld                         
++ *    cli                         
++ *    movl $0x18,%eax
++ *    mov %ax,%ds                 
++ *    mov %ax,%es                 
++ *    mov %ax,%fs                 
++ *    mov %ax,%gs                 
++ *    mov %ax,%ss                 
++ *
++ *  # Move the kernel into position
++ *    xor    %edx,%edx            
++ *_doloop:                        
++ *    movzbl 0x600000(%edx),%eax  
++ *    mov    %al,0x100000(%edx)   
++ *    add    $0x1,%edx            
++ *    cmp    $0x500000,%edx       
++ *    jne    _doloop              
++ *
++ *  # start kernel
++ *    xorl %ebx,%ebx              
++ *    mov    $0x100000,%ecx       
++ *    jmp    *%ecx                
++ *
 + */
-+static void setup_relocator(target_phys_addr_t addr, size_t dst, size_t src, size_t cnt)
++static void setup_relocator(target_phys_addr_t addr, target_phys_addr_t src, target_phys_addr_t dst, size_t len)
 +{
-+  target_phys_addr_t stack = addr + 0x500;
-+#define buf buf2
-+  uint8_t buf1[] = {
-+    /* 0: */  0xfa,  /* cli     */
-+    /* 1: */  0xfc,  /* cld     */
-+    /* 2: */  0x8c, 0xc8,  /* movl   %cs,%eax */
-+    /* 4: */  0x8e, 0xd8,  /* movl   %eax,%ds */
-+    /* 6: */  0x8e, 0xc0,  /* movl   %eax,%es */
-+    /* 8: */  0x8b, 0x35, (src&0xff),((src>>8)&0xff),((src>>16)&0xff),((src>>24)&0xff),  /*  movl   $src,%esi */
-+    /* e: */  0x8b, 0x3d, (dst&0xff),((dst>>8)&0xff),((dst>>16)&0xff),((dst>>24)&0xff),  /*  movl  $dst,%edi */
-+    /* 14: */  0x8b, 0x0d, (cnt&0xff),((cnt>>8)&0xff),((cnt>>16)&0xff),((cnt>>24)&0xff),  /*  movl  $cnt,%eci */
-+    /* 1a: */  0xf3, 0xa4,  /* rep movsb %ds:(%esi),%es:(%edi) */
-+    /* 1c: */  0xe8,(dst&0xff),((dst>>8)&0xff),((dst>>16)&0xff),((dst>>24)&0xff),  /* call $dst */
-+  };
-+  uint8_t buf2[] = {
-+    0xfa,
-+
-+    0xbc, (stack&0xff),((stack>>8)&0xff),((stack>>16)&0xff),((stack>>24)&0xff),  /*  mov  $stack,%esp */
-+    /* 0: */  0x55,  /* push   %ebp */
-+    /* 1: */  0x89, 0xe5,  /* mov    %esp,%ebp */
-+    /* 3: */  0x83, 0xec, 0x18,  /* sub    $0x18,%esp */
-+    /* 6: */   0xc7, 0x45, 0xfc, (src&0xff),((src>>8)&0xff),((src>>16)&0xff),((src>>24)&0xff),  /*  movl   $0x12345678,0xfffffffc(%ebp) */
-+    /* d: */   0xc7, 0x45, 0xf8, (dst&0xff),((dst>>8)&0xff),((dst>>16)&0xff),((dst>>24)&0xff),  /*  movl   $0xabcdef12,0xfffffff8(%ebp) */
-+    /* 14: */   0xc7, 0x45, 0xf4, (cnt&0xff),((cnt>>8)&0xff),((cnt>>16)&0xff),((cnt>>24)&0xff),  /*  movl   $0xa1b2c3d4,0xfffffff4(%ebp) */
-+    /* 1b: */  0xc7, 0x45, 0xfc, 0x00, 0x00, 0x00, 0x00,  /* movl   $0x0,0xfffffffc(%ebp) */
-+    /* 22: */  0xeb, 0x1d,  /* jmp    41 <relocate+0x41> */
-+    /* 24: */  0x8b, 0x45, 0xf4,  /* mov    0xfffffff4(%ebp),%eax */
-+    /* 27: */  0x89, 0xc2,  /* mov    %eax,%edx */
-+    /* 29: */  0x8b, 0x45, 0xfc,  /* mov    0xfffffffc(%ebp),%eax */
-+    /* 2c: */  0x8d, 0x0c, 0x02,  /* lea    (%edx,%eax,1),%ecx */
-+    /* 2f: */  0x8b, 0x45, 0xf8,  /* mov    0xfffffff8(%ebp),%eax */
-+    /* 32: */  0x89, 0xc2,  /* mov    %eax,%edx */
-+    /* 34: */  0x8b, 0x45, 0xfc,  /* mov    0xfffffffc(%ebp),%eax */
-+    /* 37: */  0x8d, 0x04, 0x02,  /* lea    (%edx,%eax,1),%eax */
-+    /* 3a: */  0x8a, 0x00,  /* mov    (%eax),%al */
-+    /* 3c: */  0x88, 0x01,  /* mov    %al,(%ecx) */
-+    /* 3e: */  0xff, 0x45, 0xfc,  /* incl   0xfffffffc(%ebp) */
-+    /* 41: */  0x8b, 0x45, 0xf0,  /* mov    0xfffffff0(%ebp),%eax */
-+    /* 44: */  0x39, 0x45, 0xfc,  /* cmp    %eax,0xfffffffc(%ebp) */
-+    /* 49: */  0x8b, 0x45, 0xf4,  /* mov    0xfffffff4(%ebp),%eax */
-+    /* 4c: */  0xff, 0xd0,  /* call   *%eax */
++  /* Now this assembler corresponds to follow machine code, with our args from QEMU spliced in :-) */
++  unsigned char buf[] = {
++    /* Load segments */
++    0xfc,                         /* cld               */
++    0xfa,                         /* cli               */ 
++    0xb8, 0x18, 0x00, 0x00, 0x00, /* mov    $0x18,%eax */
++    0x8e, 0xd8,                   /* mov    %eax,%ds   */
++    0x8e, 0xc0,                   /* mov    %eax,%es   */
++    0x8e, 0xe0,                   /* mov    %eax,%fs   */
++    0x8e, 0xe8,                   /* mov    %eax,%gs   */
++    0x8e, 0xd0,                   /* mov    %eax,%ss   */
++    0x31, 0xd2,                   /* xor    %edx,%edx  */
++  
++    /* Move the kernel into position */
++    0x0f, 0xb6, 0x82, (src&0xff), ((src>>8)&0xff), ((src>>16)&0xff), ((src>>24)&0xff), /*   movzbl $src(%edx),%eax */
++    0x88, 0x82, (dst&0xff), ((dst>>8)&0xff), ((dst>>16)&0xff), ((dst>>24)&0xff),       /*   mov    %al,$dst(%edx)  */
++    0x83, 0xc2, 0x01,                                                                  /*   add    $0x1,%edx       */
++    0x81, 0xfa, (len&0xff), ((len>>8)&0xff), ((len>>16)&0xff), ((len>>24)&0xff),       /*   cmp    $len,%edx       */
++    0x75, 0xe8,                                                                        /*   jne    13 <_doloop>    */
 +
++    /* Start kernel */
++    0x31, 0xdb,                                                                        /*   xor    %ebx,%ebx       */
++    0xb9, (dst&0xff), ((dst>>8)&0xff), ((dst>>16)&0xff), ((dst>>24)&0xff),             /*   mov    $dst,%ecx  */
++    0xff, 0xe1,                                                                        /*   jmp    *%ecx           */
 +  };
-+  fprintf(stderr, "Setting up %#zx byte helper at %#zx to move %#zx bytes from %#zx to %#zx\n", sizeof(buf), addr, cnt, src, dst);
 +  cpu_physical_memory_rw(addr, buf, sizeof(buf), 1);
++  fprintf(stderr, "qemu: helper at 0x%x of size %d bytes, to move kernel of %d bytes from 0x%x to 0x%x\n",
++	  (int)addr, (int)sizeof(buf), (int)len, (int)src, (int)dst);
 +}
 +
-+
+ 
  static long get_file_size(FILE *f)
  {
-     long where, size;
-@@ -597,8 +664,16 @@ static void load_linux(const char *kerne
+@@ -597,8 +681,15 @@ static void load_linux(const char *kerne
  	    stl_p(header+0x214, reloc_prot_addr);
  	    fprintf(stderr, "qemu: kernel is relocatable\n");
  	} else {
@@ -87,10 +103,9 @@
 +	     * It moves kernel from reloc_prot_addr to prot_addr and
 +	     * then jumps to prot_addr. Yes this is sick.
 +	     */
-+	    setup_relocator(reloc_prot_addr+kernel_size, prot_addr, reloc_prot_addr, kernel_size);
-+	    stl_p(header+0x214, reloc_prot_addr+kernel_size);
-+	    fprintf(stderr, "qemu: kernel needs helper at %#zx to relocate from %#zx to %#zx\n", 
-+		    reloc_prot_addr+kernel_size, reloc_prot_addr, prot_addr);
++	    fprintf(stderr, "qemu: kernel is NOT relocatable\n");
++	    stl_p(header+0x214, reloc_prot_addr + kernel_size);
++	    setup_relocator(reloc_prot_addr + kernel_size, reloc_prot_addr, prot_addr, kernel_size);
  	}
      }
  


Index: xen.spec
===================================================================
RCS file: /cvs/pkgs/rpms/xen/devel/xen.spec,v
retrieving revision 1.194.2.11
retrieving revision 1.194.2.12
diff -u -r1.194.2.11 -r1.194.2.12
--- xen.spec	18 Dec 2007 17:14:31 -0000	1.194.2.11
+++ xen.spec	19 Dec 2007 05:00:41 -0000	1.194.2.12
@@ -14,7 +14,7 @@
 
 # The version that the dev tree will become when released
 %define base_version 3.2.0
-%define base_release 8
+%define base_release 10
 
 # The changeset synced to
 %define changeset 16606




More information about the fedora-extras-commits mailing list