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.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-01-24 14:39:29 +01:00
parent f8a9ab1245
commit 2e13ede59e
5 changed files with 118 additions and 89 deletions

View file

@ -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> 2012-01-24 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/commands/wildcard.c (match_files): Handle filenames * grub-core/commands/wildcard.c (match_files): Handle filenames

View file

@ -177,20 +177,21 @@ real_code_2:
pushw %es pushw %es
popw %ds popw %ds
#if GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4 < 0x200 movl $0x1000, %ecx
movl $0x200, %ecx
addl %ecx, %esi
#else
movl $(GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4), %ecx
addl $0x200, %esi addl $0x200, %esi
#endif
movl $DATA_ADDR, %edi movl $DATA_ADDR, %edi
call LOCAL(move_memory) call LOCAL(move_memory)
/* Check for multiboot signature. */ /* 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 jz 1f
addl $4, %edi
cmpl $(DATA_ADDR + 0x1000), %edi
jne 3b
movl (ramdisk_image - start), %esi movl (ramdisk_image - start), %esi
movl (ramdisk_size - start), %ecx movl (ramdisk_size - start), %ecx
@ -199,8 +200,9 @@ real_code_2:
1: 1:
movl $(DATA_ADDR + 0x1000), %edi
movl %ss:(DATA_ADDR + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE), %ecx 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: 2:
call LOCAL(move_memory) call LOCAL(move_memory)

View file

@ -60,6 +60,8 @@ LOCAL(uncompressed_size):
. = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY . = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY
reed_solomon_redundancy: reed_solomon_redundancy:
.long 0 .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. * This is the area for all of the special variables.
@ -103,9 +105,9 @@ LOCAL (codestart):
call grub_gate_a20 call grub_gate_a20
movl LOCAL(compressed_size), %edx 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 movl reed_solomon_redundancy, %ecx
leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax leal LOCAL(reed_solomon_part), %eax
cld cld
call EXT_C (grub_reed_solomon_recover) call EXT_C (grub_reed_solomon_recover)
jmp post_reed_solomon jmp post_reed_solomon
@ -116,82 +118,6 @@ LOCAL (codestart):
.text .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) * grub_gate_a20(int on)
* *
@ -342,6 +268,83 @@ gate_a20_check_state:
popl %ebx popl %ebx
ret 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 #ifdef ENABLE_LZMA
#include "lzma_decode.S" #include "lzma_decode.S"
#endif #endif

View file

@ -28,7 +28,8 @@
/* Offset of reed_solomon_redundancy. */ /* Offset of reed_solomon_redundancy. */
#define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x10 #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. */ /* The segment where the kernel is loaded. */
#define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800 #define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800

View file

@ -444,14 +444,22 @@ setup (const char *dir,
+ GRUB_DISK_SECTOR_SIZE + GRUB_DISK_SECTOR_SIZE
- sizeof (*block)); - sizeof (*block));
grub_size_t no_rs_length;
*(grub_uint32_t *) (core_img + GRUB_DISK_SECTOR_SIZE *(grub_uint32_t *) (core_img + GRUB_DISK_SECTOR_SIZE
+ GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY) + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY)
= grub_host_to_target32 (nsec * GRUB_DISK_SECTOR_SIZE - core_size); = 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); void *tmp = xmalloc (core_size);
grub_memcpy (tmp, core_img, 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, grub_reed_solomon_add_redundancy (core_img + no_rs_length + GRUB_DISK_SECTOR_SIZE,
core_size - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART - GRUB_DISK_SECTOR_SIZE, core_size - no_rs_length - GRUB_DISK_SECTOR_SIZE,
nsec * GRUB_DISK_SECTOR_SIZE nsec * GRUB_DISK_SECTOR_SIZE
- core_size); - core_size);
assert (grub_memcmp (tmp, core_img, core_size) == 0); assert (grub_memcmp (tmp, core_img, core_size) == 0);