[Top][All Lists]
[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;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [1802] 2008-08-12 Robert Millan <address@hidden>,
Robert Millan <=