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
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)
. = _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.
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
.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)
*
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
+ 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);