]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Eliminate fixed limit on reed solomon decoder length.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 24 Jan 2012 13:39:29 +0000 (14:39 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 24 Jan 2012 13:39:29 +0000 (14:39 +0100)
* 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.

ChangeLog
grub-core/boot/i386/pc/lnxboot.S
grub-core/boot/i386/pc/startup_raw.S
include/grub/offsets.h
util/grub-setup.c

index 0c97dd3143e45fe6d321c1e870d3266236ab71d1..d0c959ae35e096a90b020f9755c12232ceb0686d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+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
index 4fe0df139ee5d9d4dfc622fa718f384ceeefcd9f..9a516c69496c646e814ae945d1712c7207495cdc 100644 (file)
@@ -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)
index 0e6794f568a80dc99c548caa4780fc5e6b69c140..56f1ba957b0ec2cd044e8fd4a7e33ef15d3c3ae4 100644 (file)
@@ -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
index 75a46e1283ad80d5bb77de83dd5a92007a7037af..21aea5cd634f023ccdd7622a7ff8bbd7a7a5cc28 100644 (file)
@@ -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
index 8965143c5ac71025047178db1c08e805b5bf276d..9618d1a5d269cddb7fa80bf25b694e247718be73 100644 (file)
@@ -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);