summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--grub-core/boot/i386/pc/lnxboot.S18
-rw-r--r--grub-core/boot/i386/pc/startup_raw.S159
-rw-r--r--include/grub/offsets.h3
-rw-r--r--util/grub-setup.c12
5 files changed, 118 insertions, 89 deletions
diff --git a/ChangeLog b/ChangeLog
index 0c97dd314..d0c959ae3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
2012-01-24 Vladimir Serbinenko <phcoder@gmail.com>
+ Eliminate fixed limit on reed solomon decoder length.
+
+ * grub-core/boot/i386/pc/lnxboot.S: Scan for multiboot signature
+ rather than hardcoding the address.
+ * grub-core/boot/i386/pc/startup_raw.S: Add new data field
+ no_reed_solomon_length.
+ Move gate_a20 to no-reed-solomon part.
+ Don't force a particular size of no reed-solomon part.
+ * include/grub/offsets.h (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART):
+ Removed.
+ (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH): New define.
+ * util/grub-setup.c (setup): Read no_rs_length from the image itself.
+
+2012-01-24 Vladimir Serbinenko <phcoder@gmail.com>
+
* grub-core/commands/wildcard.c (match_files): Handle filenames
without explicit device.
(wildcard_expand): Don't add explicit device if not already present.
diff --git a/grub-core/boot/i386/pc/lnxboot.S b/grub-core/boot/i386/pc/lnxboot.S
index 4fe0df139..9a516c694 100644
--- a/grub-core/boot/i386/pc/lnxboot.S
+++ b/grub-core/boot/i386/pc/lnxboot.S
@@ -177,20 +177,21 @@ real_code_2:
pushw %es
popw %ds
-#if GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4 < 0x200
- movl $0x200, %ecx
- addl %ecx, %esi
-#else
- movl $(GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4), %ecx
+ movl $0x1000, %ecx
addl $0x200, %esi
-#endif
movl $DATA_ADDR, %edi
call LOCAL(move_memory)
/* Check for multiboot signature. */
- cmpl $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART)
+ movl $DATA_ADDR, %edi
+3:
+ movl %ss:(%edi), %eax
+ cmpl $MULTIBOOT_HEADER_MAGIC, %eax
jz 1f
+ addl $4, %edi
+ cmpl $(DATA_ADDR + 0x1000), %edi
+ jne 3b
movl (ramdisk_image - start), %esi
movl (ramdisk_size - start), %ecx
@@ -199,8 +200,9 @@ real_code_2:
1:
+ movl $(DATA_ADDR + 0x1000), %edi
movl %ss:(DATA_ADDR + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE), %ecx
- addl $((0x9000 - 0x8200) - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4)), %ecx
+ addl $(0x9000 - 0x8200), %ecx
2:
call LOCAL(move_memory)
diff --git a/grub-core/boot/i386/pc/startup_raw.S b/grub-core/boot/i386/pc/startup_raw.S
index 0e6794f56..56f1ba957 100644
--- a/grub-core/boot/i386/pc/startup_raw.S
+++ b/grub-core/boot/i386/pc/startup_raw.S
@@ -60,6 +60,8 @@ LOCAL(uncompressed_size):
. = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY
reed_solomon_redundancy:
.long 0
+ . = _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH
+ .short (LOCAL(reed_solomon_part) - _start)
/*
* This is the area for all of the special variables.
@@ -103,9 +105,9 @@ LOCAL (codestart):
call grub_gate_a20
movl LOCAL(compressed_size), %edx
- addl $(LOCAL(decompressor_end) - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART - _start), %edx
+ addl $(LOCAL(decompressor_end) - LOCAL(reed_solomon_part)), %edx
movl reed_solomon_redundancy, %ecx
- leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax
+ leal LOCAL(reed_solomon_part), %eax
cld
call EXT_C (grub_reed_solomon_recover)
jmp post_reed_solomon
@@ -116,82 +118,6 @@ LOCAL (codestart):
.text
- . = _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART
-/*
- * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself).
- * This uses the a.out kludge to load raw binary to the area starting at 1MB,
- * and relocates itself after loaded.
- */
- .p2align 2 /* force 4-byte alignment */
-multiboot_header:
- /* magic */
- .long 0x1BADB002
- /* flags */
- .long (1 << 16)
- /* checksum */
- .long -0x1BADB002 - (1 << 16)
- /* header addr */
- .long multiboot_header - _start + 0x100000 + 0x200
- /* load addr */
- .long 0x100000
- /* load end addr */
- .long 0
- /* bss end addr */
- .long 0
- /* entry addr */
- .long multiboot_entry - _start + 0x100000 + 0x200
-
-multiboot_entry:
- .code32
- /* obtain the boot device */
- movl 12(%ebx), %edx
-
- movl $GRUB_MEMORY_MACHINE_PROT_STACK, %ebp
- movl %ebp, %esp
-
- /* relocate the code */
- movl $(LOCAL(decompressor_end) + 0x200), %ecx
- addl LOCAL(compressed_size) - _start + 0x100000 + 0x200, %ecx
- movl $0x100000, %esi
- movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %edi
- cld
- rep
- movsb
- /* jump to the real address */
- movl $multiboot_trampoline, %eax
- jmp *%eax
-
-multiboot_trampoline:
- /* fill the boot information */
- movl %edx, LOCAL(boot_dev)
- shrl $24, %edx
- /* enter the usual booting */
- call prot_to_real
- .code16
- jmp LOCAL (codestart)
- .code32
-
-post_reed_solomon:
-
-#ifdef ENABLE_LZMA
- movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi
- movl $LOCAL(decompressor_end), %esi
- pushl %edi
- movl LOCAL (uncompressed_size), %ecx
- leal (%edi, %ecx), %ebx
- /* Don't remove this push: it's an argument. */
- push %ecx
- call _LzmaDecodeA
- pop %ecx
- /* _LzmaDecodeA clears DF, so no need to run cld */
- popl %esi
-#endif
-
- movl LOCAL(boot_dev), %edx
- movl $prot_to_real, %edi
- movl $real_to_prot, %ecx
- jmp *%esi
-
/*
* grub_gate_a20(int on)
*
@@ -342,6 +268,83 @@ gate_a20_check_state:
popl %ebx
ret
+LOCAL(reed_solomon_part):
+
+/*
+ * Support for booting GRUB from a Multiboot boot loader (e.g. GRUB itself).
+ * This uses the a.out kludge to load raw binary to the area starting at 1MB,
+ * and relocates itself after loaded.
+ */
+ .p2align 2 /* force 4-byte alignment */
+multiboot_header:
+ /* magic */
+ .long 0x1BADB002
+ /* flags */
+ .long (1 << 16)
+ /* checksum */
+ .long -0x1BADB002 - (1 << 16)
+ /* header addr */
+ .long multiboot_header - _start + 0x100000 + 0x200
+ /* load addr */
+ .long 0x100000
+ /* load end addr */
+ .long 0
+ /* bss end addr */
+ .long 0
+ /* entry addr */
+ .long multiboot_entry - _start + 0x100000 + 0x200
+
+multiboot_entry:
+ .code32
+ /* obtain the boot device */
+ movl 12(%ebx), %edx
+
+ movl $GRUB_MEMORY_MACHINE_PROT_STACK, %ebp
+ movl %ebp, %esp
+
+ /* relocate the code */
+ movl $(LOCAL(decompressor_end) + 0x200), %ecx
+ addl LOCAL(compressed_size) - _start + 0x100000 + 0x200, %ecx
+ movl $0x100000, %esi
+ movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %edi
+ cld
+ rep
+ movsb
+ /* jump to the real address */
+ movl $multiboot_trampoline, %eax
+ jmp *%eax
+
+multiboot_trampoline:
+ /* fill the boot information */
+ movl %edx, LOCAL(boot_dev)
+ shrl $24, %edx
+ /* enter the usual booting */
+ call prot_to_real
+ .code16
+ jmp LOCAL (codestart)
+ .code32
+
+post_reed_solomon:
+
+#ifdef ENABLE_LZMA
+ movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi
+ movl $LOCAL(decompressor_end), %esi
+ pushl %edi
+ movl LOCAL (uncompressed_size), %ecx
+ leal (%edi, %ecx), %ebx
+ /* Don't remove this push: it's an argument. */
+ push %ecx
+ call _LzmaDecodeA
+ pop %ecx
+ /* _LzmaDecodeA clears DF, so no need to run cld */
+ popl %esi
+#endif
+
+ movl LOCAL(boot_dev), %edx
+ movl $prot_to_real, %edi
+ movl $real_to_prot, %ecx
+ jmp *%esi
+
#ifdef ENABLE_LZMA
#include "lzma_decode.S"
#endif
diff --git a/include/grub/offsets.h b/include/grub/offsets.h
index 75a46e128..21aea5cd6 100644
--- a/include/grub/offsets.h
+++ b/include/grub/offsets.h
@@ -28,7 +28,8 @@
/* Offset of reed_solomon_redundancy. */
#define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x10
-#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x7e0
+/* Offset of field holding no reed solomon length. */
+#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH 0x14
/* The segment where the kernel is loaded. */
#define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800
diff --git a/util/grub-setup.c b/util/grub-setup.c
index 8965143c5..9618d1a5d 100644
--- a/util/grub-setup.c
+++ b/util/grub-setup.c
@@ -444,14 +444,22 @@ setup (const char *dir,
+ GRUB_DISK_SECTOR_SIZE
- sizeof (*block));
+ grub_size_t no_rs_length;
*(grub_uint32_t *) (core_img + GRUB_DISK_SECTOR_SIZE
+ GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY)
= grub_host_to_target32 (nsec * GRUB_DISK_SECTOR_SIZE - core_size);
+ no_rs_length = grub_target_to_host16
+ (*(grub_uint16_t *) (core_img
+ + GRUB_DISK_SECTOR_SIZE
+ + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH));
+
+ if (no_rs_length == 0xffff)
+ grub_util_error ("core.img version mismatch");
void *tmp = xmalloc (core_size);
grub_memcpy (tmp, core_img, core_size);
- grub_reed_solomon_add_redundancy (core_img + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + GRUB_DISK_SECTOR_SIZE,
- core_size - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART - GRUB_DISK_SECTOR_SIZE,
+ grub_reed_solomon_add_redundancy (core_img + no_rs_length + GRUB_DISK_SECTOR_SIZE,
+ core_size - no_rs_length - GRUB_DISK_SECTOR_SIZE,
nsec * GRUB_DISK_SECTOR_SIZE
- core_size);
assert (grub_memcmp (tmp, core_img, core_size) == 0);