All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/2] Use relocator framework for multiboot1
@ 2009-08-03 12:10 Vladimir 'phcoder' Serbinenko
  2009-08-04 20:56 ` Robert Millan
  0 siblings, 1 reply; 4+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-03 12:10 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 269 bytes --]

For now modules aren't in relocated buffer because memory management
is unable to handle realloc with big size efficiently which may cause
module command to fail

-- 
Regards
Vladimir 'phcoder' Serbinenko

Personal git repository: http://repo.or.cz/w/grub2/phcoder.git

[-- Attachment #2: mb_relocator.diff --]
[-- Type: text/plain, Size: 9267 bytes --]

diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h
index 2dd7ec0..bd3c573 100644
--- a/include/grub/i386/multiboot.h
+++ b/include/grub/i386/multiboot.h
@@ -27,16 +27,11 @@ void grub_multiboot2_real_boot (grub_addr_t entry,
 				struct grub_multiboot_info *mbi)
      __attribute__ ((noreturn));
 
-extern grub_addr_t grub_multiboot_payload_orig;
+extern grub_uint32_t grub_multiboot_payload_eip;
+extern char *grub_multiboot_payload_orig;
 extern grub_addr_t grub_multiboot_payload_dest;
 extern grub_size_t grub_multiboot_payload_size;
-extern grub_uint32_t grub_multiboot_payload_entry_offset;
 
-extern grub_uint8_t grub_multiboot_forward_relocator;
-extern grub_uint8_t grub_multiboot_forward_relocator_end;
-extern grub_uint8_t grub_multiboot_backward_relocator;
-extern grub_uint8_t grub_multiboot_backward_relocator_end;
-
-#define RELOCATOR_SIZEOF(x)	(&grub_multiboot_##x##_relocator_end - &grub_multiboot_##x##_relocator)
+#define GRUB_MULTIBOOT_STACK_SIZE 4096
 
 #endif /* ! GRUB_MULTIBOOT_CPU_HEADER */
diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c
index 87ffcae..974395f 100644
--- a/loader/i386/multiboot.c
+++ b/loader/i386/multiboot.c
@@ -48,18 +48,35 @@
 #include <grub/device.h>
 #include <grub/partition.h>
 #endif
+#include <grub/i386/relocator.h>
 
 extern grub_dl_t my_mod;
 static struct grub_multiboot_info *mbi, *mbi_dest;
-static grub_addr_t entry;
 
-static char *playground;
 static grub_size_t code_size;
 
+char *grub_multiboot_payload_orig;
+grub_addr_t grub_multiboot_payload_dest;
+grub_size_t grub_multiboot_payload_size;
+grub_uint32_t grub_multiboot_payload_eip;
+grub_uint32_t grub_multiboot_payload_esp;
+
 static grub_err_t
 grub_multiboot_boot (void)
 {
-  grub_multiboot_real_boot (entry, mbi_dest);
+  struct grub_relocator32_state state =
+    {
+      .eax = MULTIBOOT_MAGIC2,
+      .ebx = PTR_TO_UINT32 (mbi_dest),
+      .ecx = 0,
+      .edx = 0,
+      .eip = grub_multiboot_payload_eip,
+      .esp = grub_multiboot_payload_esp
+    };
+
+  grub_relocator32_boot (grub_multiboot_payload_orig,
+			 grub_multiboot_payload_dest,
+			 state);
 
   /* Not reached.  */
   return GRUB_ERR_NONE;
@@ -248,11 +265,8 @@ grub_multiboot (int argc, char *argv[])
       goto fail;
     }
 
-  if (playground)
-    {
-      grub_free (playground);
-      playground = NULL;
-    }
+  grub_relocator32_free (grub_multiboot_payload_orig);
+  grub_multiboot_payload_orig = NULL;
 
   mmap_length = grub_get_multiboot_mmap_len ();
 
@@ -267,11 +281,13 @@ grub_multiboot (int argc, char *argv[])
 				((void *) ((x) + code_size + cmdline_length))
 #define mbi_addr(x)		((void *) ((x) + code_size + cmdline_length + boot_loader_name_length))
 #define mmap_addr(x)		((void *) ((x) + code_size + cmdline_length + boot_loader_name_length + sizeof (struct grub_multiboot_info)))
+#define stack_addr(x)		((void *) ((x) + code_size + cmdline_length + boot_loader_name_length + sizeof (struct grub_multiboot_info) + mmap_length + GRUB_MULTIBOOT_STACK_SIZE))
 
   grub_multiboot_payload_size = cmdline_length
     /* boot_loader_name_length might need to grow for mbi,etc to be aligned (see below) */
     + boot_loader_name_length + 3
-    + sizeof (struct grub_multiboot_info) + mmap_length;
+    + sizeof (struct grub_multiboot_info) + mmap_length
+    + GRUB_MULTIBOOT_STACK_SIZE;
 
   if (header->flags & MULTIBOOT_AOUT_KLUDGE)
     {
@@ -287,11 +303,12 @@ grub_multiboot (int argc, char *argv[])
       grub_multiboot_payload_dest = header->load_addr;
 
       grub_multiboot_payload_size += code_size;
-      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);
+      grub_multiboot_payload_orig
+	= grub_relocator32_alloc (grub_multiboot_payload_size);
+
+      if (! grub_multiboot_payload_orig)
+	goto fail;
 
       if ((grub_file_seek (file, offset)) == (grub_off_t) - 1)
 	goto fail;
@@ -304,7 +321,7 @@ grub_multiboot (int argc, char *argv[])
 	grub_memset ((void *) (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;
+      grub_multiboot_payload_eip = header->entry_addr;
 
     }
   else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE)
@@ -325,23 +342,6 @@ grub_multiboot (int argc, char *argv[])
   mbi->mmap_addr = (grub_uint32_t) mmap_addr (grub_multiboot_payload_dest);
   mbi->flags |= MULTIBOOT_INFO_MEM_MAP;
 
-  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);
-
   /* Convert from bytes to kilobytes.  */
   mbi->mem_lower = grub_mmap_get_lower () / 1024;
   mbi->mem_upper = grub_mmap_get_upper () / 1024;
@@ -371,6 +371,8 @@ grub_multiboot (int argc, char *argv[])
   if (grub_multiboot_get_bootdev (&mbi->boot_device))
     mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
 
+  grub_multiboot_payload_esp = PTR_TO_UINT32 (stack_addr (grub_multiboot_payload_dest));
+
   grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1);
 
  fail:
diff --git a/loader/i386/multiboot_elfxx.c b/loader/i386/multiboot_elfxx.c
index 77c4711..0b9820d 100644
--- a/loader/i386/multiboot_elfxx.c
+++ b/loader/i386/multiboot_elfxx.c
@@ -32,6 +32,8 @@
 #error "I'm confused"
 #endif
 
+#include <grub/i386/relocator.h>
+
 #define CONCAT(a,b)	CONCAT_(a, b)
 #define CONCAT_(a,b)	a ## b
 
@@ -99,11 +101,12 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
   grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr;
 
   grub_multiboot_payload_size += code_size;
-  playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
-  if (! playground)
-    return grub_errno;
 
-  grub_multiboot_payload_orig = (long) playground + RELOCATOR_SIZEOF(forward);
+  grub_multiboot_payload_orig
+    = grub_relocator32_alloc (grub_multiboot_payload_size);
+
+  if (!grub_multiboot_payload_orig)
+    return grub_errno;
 
   /* Load every loadable segment in memory.  */
   for (i = 0; i < ehdr->e_phnum; i++)
@@ -135,8 +138,7 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
     if (phdr(i)->p_vaddr <= ehdr->e_entry
 	&& phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry)
       {
-	grub_multiboot_payload_entry_offset = (ehdr->e_entry - phdr(i)->p_vaddr)
-	  + (phdr(i)->p_paddr  - phdr(lowest_segment)->p_paddr);
+	grub_multiboot_payload_eip = ehdr->e_entry;
 	break;
       }
 
diff --git a/loader/i386/multiboot_helper.S b/loader/i386/multiboot_helper.S
index d109458..2f9af77 100644
--- a/loader/i386/multiboot_helper.S
+++ b/loader/i386/multiboot_helper.S
@@ -23,81 +23,6 @@
 	.p2align	2	/* force 4-byte alignment */
 
 /*
- * This starts the multiboot kernel.
- */
-
-VARIABLE(grub_multiboot_payload_size)
-	.long	0
-VARIABLE(grub_multiboot_payload_orig)
-	.long	0
-VARIABLE(grub_multiboot_payload_dest)
-	.long	0
-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)
-	/* Add entry offset.  */
-	addl	%edi, %edx
-
-	/* Forward copy.  */
-	cld
-	rep
-	movsb
-
-	jmp	*%edx
-VARIABLE(grub_multiboot_forward_relocator_end)
-
-VARIABLE(grub_multiboot_backward_relocator)
-	/* Add entry offset (before %edi is mangled).  */
-	addl	%edi, %edx
-
-	/* Backward movsb is implicitly off-by-one.  compensate that.  */
-	decl	%esi
-	decl	%edi
-
-	/* Backward copy.  */
-	std
-	addl	%ecx, %esi
-	addl	%ecx, %edi
-	rep
-	movsb
-
-	cld
-	jmp	*%edx
-VARIABLE(grub_multiboot_backward_relocator_end)
-
-FUNCTION(grub_multiboot_real_boot)
-	/* Push the entry address on the stack.  */
-	pushl	%eax
-	/* Move the address of the multiboot information structure to ebx.  */
-	movl	%edx,%ebx
-
-	/* Interrupts should be disabled.  */
-	cli
-
-	/* Where do we copy what from.  */
-	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), %edx
-
-	/* Move the magic value into eax.  */
-	movl	$MULTIBOOT_MAGIC2, %eax
-
-	/* Jump to the relocator.  */
-	popl	%ebp
-	jmp 	*%ebp
-
-/*
  * This starts the multiboot 2 kernel.
  */
 

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/2] Use relocator framework for multiboot1
  2009-08-03 12:10 [PATCH 2/2] Use relocator framework for multiboot1 Vladimir 'phcoder' Serbinenko
@ 2009-08-04 20:56 ` Robert Millan
  2009-08-05 10:20   ` Vladimir 'phcoder' Serbinenko
  0 siblings, 1 reply; 4+ messages in thread
From: Robert Millan @ 2009-08-04 20:56 UTC (permalink / raw)
  To: The development of GRUB 2

On Mon, Aug 03, 2009 at 02:10:18PM +0200, Vladimir 'phcoder' Serbinenko wrote:
> +#define GRUB_MULTIBOOT_STACK_SIZE 4096
> [...]
> +#define stack_addr(x)		((void *) ((x) + code_size + cmdline_length + boot_loader_name_length + sizeof (struct grub_multiboot_info) + mmap_length + GRUB_MULTIBOOT_STACK_SIZE))

What's this stack used for?

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/2] Use relocator framework for multiboot1
  2009-08-04 20:56 ` Robert Millan
@ 2009-08-05 10:20   ` Vladimir 'phcoder' Serbinenko
  2009-08-07 11:12     ` Robert Millan
  0 siblings, 1 reply; 4+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2009-08-05 10:20 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, Aug 4, 2009 at 10:56 PM, Robert Millan<rmh@aybabtu.com> wrote:
> On Mon, Aug 03, 2009 at 02:10:18PM +0200, Vladimir 'phcoder' Serbinenko wrote:
>> +#define GRUB_MULTIBOOT_STACK_SIZE 4096
>> [...]
>> +#define stack_addr(x)                ((void *) ((x) + code_size + cmdline_length + boot_loader_name_length + sizeof (struct grub_multiboot_info) + mmap_length + GRUB_MULTIBOOT_STACK_SIZE))
>
> What's this stack used for?
Only to set %esp to something that can be used by OS for small things
before they setup their own stack. By multiboot specification OS is
required to setup its stack itself but I suppose many OSes may have
done a mistake of having few push'es before real stack setup
>
> --
> Robert Millan
>
>  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
>  how) you may access your data; but nobody's threatening your freedom: we
>  still allow you to remove your data and not access it at all."
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>



-- 
Regards
Vladimir 'phcoder' Serbinenko

Personal git repository: http://repo.or.cz/w/grub2/phcoder.git



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/2] Use relocator framework for multiboot1
  2009-08-05 10:20   ` Vladimir 'phcoder' Serbinenko
@ 2009-08-07 11:12     ` Robert Millan
  0 siblings, 0 replies; 4+ messages in thread
From: Robert Millan @ 2009-08-07 11:12 UTC (permalink / raw)
  To: The development of GRUB 2

On Wed, Aug 05, 2009 at 12:20:35PM +0200, Vladimir 'phcoder' Serbinenko wrote:
> On Tue, Aug 4, 2009 at 10:56 PM, Robert Millan<rmh@aybabtu.com> wrote:
> > On Mon, Aug 03, 2009 at 02:10:18PM +0200, Vladimir 'phcoder' Serbinenko wrote:
> >> +#define GRUB_MULTIBOOT_STACK_SIZE 4096
> >> [...]
> >> +#define stack_addr(x)                ((void *) ((x) + code_size + cmdline_length + boot_loader_name_length + sizeof (struct grub_multiboot_info) + mmap_length + GRUB_MULTIBOOT_STACK_SIZE))
> >
> > What's this stack used for?
> Only to set %esp to something that can be used by OS for small things
> before they setup their own stack. By multiboot specification OS is
> required to setup its stack itself but I suppose many OSes may have
> done a mistake of having few push'es before real stack setup

Did you find code that has this problem?

Note it's much simpler for them to solve it on their side by allocating a
stack in their BSS.

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2009-08-07 11:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-03 12:10 [PATCH 2/2] Use relocator framework for multiboot1 Vladimir 'phcoder' Serbinenko
2009-08-04 20:56 ` Robert Millan
2009-08-05 10:20   ` Vladimir 'phcoder' Serbinenko
2009-08-07 11:12     ` Robert Millan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.