commit-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[1802] 2008-08-12 Robert Millan <address@hidden>


From: Robert Millan
Subject: [1802] 2008-08-12 Robert Millan <address@hidden>
Date: Tue, 12 Aug 2008 15:40:26 +0000

Revision: 1802
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=1802
Author:   robertmh
Date:     2008-08-12 15:40:26 +0000 (Tue, 12 Aug 2008)

Log Message:
-----------
2008-08-12  Robert Millan  <address@hidden>

        * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Move part
        of the relocation code from here ...
        (grub_multiboot): ... to here.
        (forward_relocator, backward_relocator): Move from here ...
        * kern/i386/loader.S (grub_multiboot_forward_relocator)
        (grub_multiboot_backward_relocator): ... to here.
        (grub_multiboot_real_boot): Use %edx for entry offset.  Put Multiboot
        magic in %eax.  Use %ebp for jumping (so %edx is not trashed).
        * include/grub/i386/loader.h (grub_multiboot_forward_relocator)
        (grub_multiboot_forward_relocator_end)
        (grub_multiboot_backward_relocator)
        (grub_multiboot_backward_relocator_end): New variables.

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/include/grub/i386/loader.h
    trunk/grub2/kern/i386/loader.S
    trunk/grub2/loader/i386/pc/multiboot.c

Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog       2008-08-12 13:58:29 UTC (rev 1801)
+++ trunk/grub2/ChangeLog       2008-08-12 15:40:26 UTC (rev 1802)
@@ -1,3 +1,18 @@
+2008-08-12  Robert Millan  <address@hidden>
+
+       * loader/i386/pc/multiboot.c (grub_multiboot_load_elf32): Move part
+       of the relocation code from here ...
+       (grub_multiboot): ... to here.
+       (forward_relocator, backward_relocator): Move from here ...
+       * kern/i386/loader.S (grub_multiboot_forward_relocator)
+       (grub_multiboot_backward_relocator): ... to here.
+       (grub_multiboot_real_boot): Use %edx for entry offset.  Put Multiboot
+       magic in %eax.  Use %ebp for jumping (so %edx is not trashed).
+       * include/grub/i386/loader.h (grub_multiboot_forward_relocator)
+       (grub_multiboot_forward_relocator_end)
+       (grub_multiboot_backward_relocator)
+       (grub_multiboot_backward_relocator_end): New variables.
+
 2008-08-12  Bean  <address@hidden>
 
        * disk/raid.c (grub_raid_read): Fix a bug in raid0 code.

Modified: trunk/grub2/include/grub/i386/loader.h
===================================================================
--- trunk/grub2/include/grub/i386/loader.h      2008-08-12 13:58:29 UTC (rev 
1801)
+++ trunk/grub2/include/grub/i386/loader.h      2008-08-12 15:40:26 UTC (rev 
1802)
@@ -53,4 +53,11 @@
 void grub_rescue_cmd_linux (int argc, char *argv[]);
 void grub_rescue_cmd_initrd (int argc, char *argv[]);
 
+extern grub_uint8_t EXPORT_VAR(grub_multiboot_forward_relocator);
+extern grub_uint8_t EXPORT_VAR(grub_multiboot_forward_relocator_end);
+extern grub_uint8_t EXPORT_VAR(grub_multiboot_backward_relocator);
+extern grub_uint8_t EXPORT_VAR(grub_multiboot_backward_relocator_end);
+
+#define RELOCATOR_SIZEOF(x)    (&grub_multiboot_##x##_relocator_end - 
&grub_multiboot_##x##_relocator)
+
 #endif /* ! GRUB_LOADER_CPU_HEADER */

Modified: trunk/grub2/kern/i386/loader.S
===================================================================
--- trunk/grub2/kern/i386/loader.S      2008-08-12 13:58:29 UTC (rev 1801)
+++ trunk/grub2/kern/i386/loader.S      2008-08-12 15:40:26 UTC (rev 1802)
@@ -132,6 +132,36 @@
 VARIABLE(grub_multiboot_payload_entry_offset)
        .long   0
 
+/*
+ * The relocators below understand the following parameters:
+ * ecx:        Size of the block to be copied.
+ * esi:        Where to copy from (always lowest address, even if we're 
relocating
+ *      backwards).
+ * edi:        Where to copy to (likewise).
+ * edx:        Offset of the entry point (relative to the beginning of the 
block).
+ */
+VARIABLE(grub_multiboot_forward_relocator)
+       cld
+       addl    %edi, %edx
+       rep
+       movsb
+       jmp     *%edx
+VARIABLE(grub_multiboot_forward_relocator_end)
+
+VARIABLE(grub_multiboot_backward_relocator)
+       std
+       addl    %ecx, %esi
+       addl    %ecx, %edi
+       /* backward movsb is implicitly off-by-one.  compensate that. */
+       incl    %ecx
+       rep
+       movsb
+       /* same problem again. */
+       incl    %edi
+       addl    %edi, %edx
+       jmp     *%edx
+VARIABLE(grub_multiboot_backward_relocator_end)
+
 FUNCTION(grub_multiboot_real_boot)
        /* Push the entry address on the stack.  */
        pushl   %eax
@@ -149,11 +179,14 @@
        movl    EXT_C(grub_multiboot_payload_size), %ecx
        movl    EXT_C(grub_multiboot_payload_orig), %esi
        movl    EXT_C(grub_multiboot_payload_dest), %edi
-       movl    EXT_C(grub_multiboot_payload_entry_offset), %eax
-                       
+       movl    EXT_C(grub_multiboot_payload_entry_offset), %edx
+
+       /* Move the magic value into eax.  */
+       movl    $MULTIBOOT_MAGIC2, %eax
+                               
        /* Jump to the relocator.  */
-       popl    %edx
-       jmp     *%edx
+       popl    %ebp
+       jmp     *%ebp
        
 /*
  * This starts the multiboot 2 kernel.

Modified: trunk/grub2/loader/i386/pc/multiboot.c
===================================================================
--- trunk/grub2/loader/i386/pc/multiboot.c      2008-08-12 13:58:29 UTC (rev 
1801)
+++ trunk/grub2/loader/i386/pc/multiboot.c      2008-08-12 15:40:26 UTC (rev 
1802)
@@ -52,31 +52,6 @@
 
 static char *playground = NULL;
 
-static grub_uint8_t forward_relocator[] =
-{
-  0xfc,                                /* cld */
-  0x89, 0xf2,                  /* movl %esi, %edx */
-  0xf3, 0xa4,                  /* rep movsb */
-  0x01, 0xc2,                  /* addl %eax, %edx */
-  0xb8, 0x02, 0xb0, 0xad, 0x2b,        /* movl $MULTIBOOT_MAGIC2, %eax */
-  0xff, 0xe2,                  /* jmp *%edx */
-};
-
-static grub_uint8_t backward_relocator[] =
-{
-  0xfd,                                /* std */
-  0x01, 0xce,                  /* addl %ecx, %esi */
-  0x01, 0xcf,                  /* addl %ecx, %edi */
-                               /* backward movsb is implicitly off-by-one.  
compensate that. */
-  0x41,                                /* incl %ecx */
-  0xf3, 0xa4,                  /* rep movsb */
-                               /* same problem again. */
-  0x47,                                /* incl %edi */
-  0x01, 0xc7,                  /* addl %eax, %edi */
-  0xb8, 0x02, 0xb0, 0xad, 0x2b,        /* movl $MULTIBOOT_MAGIC2, %eax */
-  0xff, 0xe7,                  /* jmp *%edi */
-};
-
 static grub_err_t
 grub_multiboot_boot (void)
 {
@@ -155,17 +130,12 @@
   grub_multiboot_payload_size = (phdr(highest_segment)->p_paddr + 
phdr(highest_segment)->p_memsz) - phdr(lowest_segment)->p_paddr;
   grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr;
 
-  if (playground)
-    grub_free (playground);
-  playground = grub_malloc (sizeof (forward_relocator) + 
grub_multiboot_payload_size + sizeof (backward_relocator));
+  playground = grub_malloc (RELOCATOR_SIZEOF(forward) + 
grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
   if (! playground)
     return grub_errno;
 
-  grub_multiboot_payload_orig = (long) playground + sizeof (forward_relocator);
+  grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward);
 
-  grub_memmove (playground, forward_relocator, sizeof (forward_relocator));
-  grub_memmove ((char *) (grub_multiboot_payload_orig + 
grub_multiboot_payload_size), backward_relocator, sizeof (backward_relocator));
-
   /* Load every loadable segment in memory.  */
   for (i = 0; i < ehdr->e_phnum; i++)
     {
@@ -196,16 +166,6 @@
 
 #undef phdr
 
-  if (grub_multiboot_payload_dest >= grub_multiboot_payload_orig)
-    entry = (grub_addr_t) playground;
-  else
-    entry = (grub_addr_t) grub_multiboot_payload_orig + 
grub_multiboot_payload_size;
-
-  grub_dprintf ("multiboot_loader", "dest=%p, size=0x%x, entry_offset=0x%x\n",
-               (void *) grub_multiboot_payload_dest,
-               grub_multiboot_payload_size,
-               grub_multiboot_payload_entry_offset);
-
   return grub_errno;
 }
 
@@ -413,24 +373,66 @@
       goto fail;
     }
 
+  if (playground)
+    {
+      grub_free (playground);
+      playground = NULL;
+    }
+
   if (header->flags & MULTIBOOT_AOUT_KLUDGE)
     {
-      int ofs;
+      int offset = ((char *) header - buffer -
+                   (header->header_addr - header->load_addr));
+      int load_size = ((header->load_end_addr == 0) ? file->size - offset :
+                      header->load_end_addr - header->load_addr);
 
-      ofs = (char *) header - buffer -
-            (header->header_addr - header->load_addr);
-      if ((grub_aout_load (file, ofs, header->load_addr,
-                           ((header->load_end_addr == 0) ? 0 :
-                            header->load_end_addr - header->load_addr),
-                           header->bss_end_addr))
-          !=GRUB_ERR_NONE)
-        goto fail;
+      if (header->bss_end_addr)
+       grub_multiboot_payload_size = (header->bss_end_addr - 
header->load_addr);
+      else
+       grub_multiboot_payload_size = load_size;
+      grub_multiboot_payload_dest = header->load_addr;
 
-      entry = header->entry_addr;
+      playground = grub_malloc (RELOCATOR_SIZEOF(forward) + 
grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
+      if (! playground)
+       goto fail;
+
+      grub_multiboot_payload_orig = (long) playground + 
RELOCATOR_SIZEOF(forward);
+
+      if ((grub_file_seek (file, offset)) == (grub_off_t) - 1)
+       goto fail;
+
+      grub_file_read (file, grub_multiboot_payload_orig, load_size);
+      if (grub_errno)
+       goto fail;
+      
+      if (header->bss_end_addr)
+       grub_memset (grub_multiboot_payload_orig + load_size, 0,
+                    header->bss_end_addr - header->load_addr - load_size);
+      
+      grub_multiboot_payload_entry_offset = header->entry_addr - 
header->load_addr;
+
     }
   else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE)
     goto fail;
 
+      
+  if (grub_multiboot_payload_dest >= grub_multiboot_payload_orig)
+    {
+      grub_memmove (playground, &grub_multiboot_forward_relocator, 
RELOCATOR_SIZEOF(forward));
+      entry = (grub_addr_t) playground;
+    }
+  else
+    {
+      grub_memmove ((char *) (grub_multiboot_payload_orig + 
grub_multiboot_payload_size),
+                   &grub_multiboot_backward_relocator, 
RELOCATOR_SIZEOF(backward));
+      entry = (grub_addr_t) grub_multiboot_payload_orig + 
grub_multiboot_payload_size;
+    }
+  
+  grub_dprintf ("multiboot_loader", "dest=%p, size=0x%x, entry_offset=0x%x\n",
+               (void *) grub_multiboot_payload_dest,
+               grub_multiboot_payload_size,
+               grub_multiboot_payload_entry_offset);
+
   mbi = grub_malloc (sizeof (struct grub_multiboot_info));
   if (! mbi)
     goto fail;






reply via email to

[Prev in Thread] Current Thread [Next in Thread]