by 46 bytes but improves compatibility and maintainability.
* grub-core/Makefile.core.def (lzma_decompress): New image.
(kernel): Add i386_pc_ldflags.
* grub-core/kern/i386/pc/startup.S: Move intial part to ..
* grub-core/boot/i386/pc/startup_raw.S: ... here. Pass pointers
to real_to_prot, prot_to_real and device info.
* include/grub/offsets.h: Renamed decompressor offsets.
* util/grub-mkimage.c (grub_compression_t): New cmpression lzma.
(image_target_desc): Remove raw_size and rename decompressor fields.
(compress_kernel): Handle lzma.
(generate_image): Handle decompressors on i386-pc.
+2011-11-12 Vladimir Serbinenko <phcoder@gmail.com>
+
+ Use decompressors framework on i386-pc. It increases core size
+ by 46 bytes but improves compatibility and maintainability.
+
+ * grub-core/Makefile.core.def (lzma_decompress): New image.
+ (kernel): Add i386_pc_ldflags.
+ * grub-core/kern/i386/pc/startup.S: Move intial part to ..
+ * grub-core/boot/i386/pc/startup_raw.S: ... here. Pass pointers
+ to real_to_prot, prot_to_real and device info.
+ * include/grub/offsets.h: Renamed decompressor offsets.
+ * util/grub-mkimage.c (grub_compression_t): New cmpression lzma.
+ (image_target_desc): Remove raw_size and rename decompressor fields.
+ (compress_kernel): Handle lzma.
+ (generate_image): Handle decompressors on i386-pc.
+
2011-11-12 Vladimir Serbinenko <phcoder@gmail.com>
* configure.ac: Add -fno-asynchronous-unwind-tables.
ia64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment';
i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
- i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200';
+ i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x9000';
i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)';
i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200';
enable = mips;
};
+image = {
+ name = lzma_decompress;
+ i386_pc = boot/i386/pc/startup_raw.S;
+
+ objcopyflags = '-O binary';
+ ldflags = '-Wl,-Ttext,0x8200';
+ enable = i386_pc;
+};
+
image = {
name = fwstart;
mips_loongson = boot/mips/loongson/fwstart.S;
1:
- movl %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx
-#if GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4 < 0x200
- addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx
-#else
- addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4)), %ecx
-#endif
+ movl %ss:(DATA_ADDR + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE), %ecx
+ addl $((0x9000 - 0x8200) - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4)), %ecx
2:
call LOCAL(move_memory)
--- /dev/null
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009,2011 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <grub/symbol.h>
+#include <grub/offsets.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/memory.h>
+#include <grub/machine/kernel.h>
+
+#define ABS(x) ((x) - LOCAL (base) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200)
+
+ .file "startup_raw.S"
+
+ .text
+
+ /* Tell GAS to generate 16-bit instructions so that this code works
+ in real mode. */
+ .code16
+
+ .globl start, _start
+start:
+_start:
+LOCAL (base):
+ /*
+ * Guarantee that "main" is loaded at 0x0:0x8200.
+ */
+#ifdef __APPLE__
+ ljmp $0, $(ABS(LOCAL (codestart)) - 0x10000)
+#else
+ ljmp $0, $ABS(LOCAL (codestart))
+#endif
+
+ /*
+ * This is a special data area.
+ */
+
+ . = _start + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE
+LOCAL(compressed_size):
+ .long 0
+ . = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE
+LOCAL(uncompressed_size):
+ .long 0
+
+ . = _start + GRUB_KERNEL_I386_PC_INSTALL_DOS_PART
+LOCAL(dos_part):
+ .long 0xFFFFFFFF
+ . = _start + GRUB_KERNEL_I386_PC_INSTALL_BSD_PART
+LOCAL(bsd_part):
+ .long 0xFFFFFFFF
+
+ . = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY
+reed_solomon_redundancy:
+ .long 0
+
+/*
+ * This is the area for all of the special variables.
+ */
+
+LOCAL(boot_drive):
+ .byte 0
+
+/* the real mode code continues... */
+LOCAL (codestart):
+ cli /* we're not safe here! */
+
+ /* set up %ds, %ss, and %es */
+ xorw %ax, %ax
+ movw %ax, %ds
+ movw %ax, %ss
+ movw %ax, %es
+
+ /* set up the real mode/BIOS stack */
+ movl $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp
+ movl %ebp, %esp
+
+ sti /* we're safe again */
+
+ /* save the boot drive */
+ ADDR32 movb %dl, LOCAL(boot_drive)
+
+ /* reset disk system (%ah = 0) */
+ int $0x13
+
+ /* transition to protected mode */
+ DATA32 call real_to_prot
+
+ /* The ".code32" directive takes GAS out of 16-bit mode. */
+ .code32
+
+ incl %eax
+ call grub_gate_a20
+
+ movl LOCAL(compressed_size), %edx
+ addl $(LOCAL(decompressor_end) - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx
+ movl reed_solomon_redundancy, %ecx
+ leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax
+ call EXT_C (grub_reed_solomon_recover)
+ jmp post_reed_solomon
+
+#include <rs_decoder.S>
+
+ .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, %eax
+ shrl $8, %eax
+ xorl %ebx, %ebx
+ cmpb $0xFF, %ah
+ je 1f
+ movb %ah, %bl
+ movl %ebx, LOCAL(dos_part)
+1:
+ cmpb $0xFF, %al
+ je 2f
+ movb %al, %bl
+ movl %ebx, LOCAL(bsd_part)
+2:
+ shrl $24, %edx
+ movb %dl, LOCAL(boot_drive)
+ movb $0xFF, %dh
+ movl $GRUB_MEMORY_MACHINE_PROT_STACK, %esp
+ /* 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
+ call _LzmaDecodeA
+ /* _LzmaDecodeA clears DF, so no need to run cld */
+ popl %esi
+#endif
+
+ movb LOCAL(boot_drive), %dl
+ movl LOCAL(dos_part), %eax
+ movl LOCAL(bsd_part), %ebx
+ movl $prot_to_real, %edi
+ movl $real_to_prot, %ecx
+ jmp *%esi
+
+#include "../../../kern/i386/realmode.S"
+
+/*
+ * grub_gate_a20(int on)
+ *
+ * Gate address-line 20 for high memory.
+ *
+ * This routine is probably overconservative in what it does, but so what?
+ *
+ * It also eats any keystrokes in the keyboard buffer. :-(
+ */
+
+grub_gate_a20:
+ movl %eax, %edx
+
+gate_a20_test_current_state:
+ /* first of all, test if already in a good state */
+ call gate_a20_check_state
+ cmpb %al, %dl
+ jnz gate_a20_try_bios
+ ret
+
+gate_a20_try_bios:
+ /* second, try a BIOS call */
+ pushl %ebp
+ call prot_to_real
+
+ .code16
+ movw $0x2400, %ax
+ testb %dl, %dl
+ jz 1f
+ incw %ax
+1: int $0x15
+
+ DATA32 call real_to_prot
+ .code32
+
+ popl %ebp
+ call gate_a20_check_state
+ cmpb %al, %dl
+ jnz gate_a20_try_system_control_port_a
+ ret
+
+gate_a20_try_system_control_port_a:
+ /*
+ * In macbook, the keyboard test would hang the machine, so we move
+ * this forward.
+ */
+ /* fourth, try the system control port A */
+ inb $0x92
+ andb $(~0x03), %al
+ testb %dl, %dl
+ jz 6f
+ orb $0x02, %al
+6: outb $0x92
+
+ /* When turning off Gate A20, do not check the state strictly,
+ because a failure is not fatal usually, and Gate A20 is always
+ on some modern machines. */
+ testb %dl, %dl
+ jz 7f
+ call gate_a20_check_state
+ cmpb %al, %dl
+ jnz gate_a20_try_keyboard_controller
+7: ret
+
+gate_a20_flush_keyboard_buffer:
+ inb $0x64
+ andb $0x02, %al
+ jnz gate_a20_flush_keyboard_buffer
+2:
+ inb $0x64
+ andb $0x01, %al
+ jz 3f
+ inb $0x60
+ jmp 2b
+3:
+ ret
+
+gate_a20_try_keyboard_controller:
+ /* third, try the keyboard controller */
+ call gate_a20_flush_keyboard_buffer
+
+ movb $0xd1, %al
+ outb $0x64
+4:
+ inb $0x64
+ andb $0x02, %al
+ jnz 4b
+
+ movb $0xdd, %al
+ testb %dl, %dl
+ jz 5f
+ orb $0x02, %al
+5: outb $0x60
+ call gate_a20_flush_keyboard_buffer
+
+ /* output a dummy command (USB keyboard hack) */
+ movb $0xff, %al
+ outb $0x64
+ call gate_a20_flush_keyboard_buffer
+
+ call gate_a20_check_state
+ cmpb %al, %dl
+ /* everything failed, so restart from the beginning */
+ jnz gate_a20_try_bios
+ ret
+
+gate_a20_check_state:
+ /* iterate the checking for a while */
+ movl $100, %ecx
+1:
+ call 3f
+ cmpb %al, %dl
+ jz 2f
+ loop 1b
+2:
+ ret
+3:
+ pushl %ebx
+ pushl %ecx
+ xorl %eax, %eax
+ /* compare the byte at 0x8000 with that at 0x108000 */
+ movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %ebx
+ pushl %ebx
+ /* save the original byte in CL */
+ movb (%ebx), %cl
+ /* store the value at 0x108000 in AL */
+ addl $0x100000, %ebx
+ movb (%ebx), %al
+ /* try to set one less value at 0x8000 */
+ popl %ebx
+ movb %al, %ch
+ decb %ch
+ movb %ch, (%ebx)
+ /* serialize */
+ outb %al, $0x80
+ outb %al, $0x80
+ /* obtain the value at 0x108000 in CH */
+ pushl %ebx
+ addl $0x100000, %ebx
+ movb (%ebx), %ch
+ /* this result is 1 if A20 is on or 0 if it is off */
+ subb %ch, %al
+ xorb $1, %al
+ /* restore the original */
+ popl %ebx
+ movb %cl, (%ebx)
+ popl %ecx
+ popl %ebx
+ ret
+
+#ifdef ENABLE_LZMA
+#include "lzma_decode.S"
+#endif
+
+ .p2align 2
+
+LOCAL(decompressor_end):
bal codestart
nop
base:
- . = _start + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE
+ . = _start + GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE
compressed_size:
.long 0
- . = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_SIZE
+ . = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE
uncompressed_size:
.long 0
- . = _start + GRUB_KERNEL_MACHINE_UNCOMPRESSED_ADDR
+ . = _start + GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_ADDR
uncompressed_addr:
.long 0
codestart:
movl 24(%edx), %esi
movl 28(%edx), %edx
- call prot_to_real
+ PROT_TO_REAL
.code16
pushf
cli
movw %ax, LOCAL(bios_register_es)
popf
- DATA32 call real_to_prot
+ REAL_TO_PROT
.code32
popl %eax
int grub_lower_mem;
#endif
- grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR
- + ((_edata - _start) - GRUB_KERNEL_MACHINE_RAW_SIZE);
+ grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - _start);
/* Initialize the console as early as possible. */
grub_console_init ();
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+ * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009,2011 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include <config.h>
#include <grub/symbol.h>
-#include <grub/machine/boot.h>
-#include <grub/machine/memory.h>
-#include <grub/machine/console.h>
-#include <grub/cpu/linux.h>
-#include <grub/machine/kernel.h>
-#include <grub/term.h>
#include <multiboot.h>
-#include <multiboot2.h>
-
-#define ABS(x) ((x) - LOCAL (base) + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200)
.file "startup.S"
.text
- /* Tell GAS to generate 16-bit instructions so that this code works
- in real mode. */
- .code16
-
.globl start, _start
start:
_start:
-LOCAL (base):
- /*
- * Guarantee that "main" is loaded at 0x0:0x8200.
- */
-#ifdef __APPLE__
- ljmp $0, $(ABS(LOCAL (codestart)) - 0x10000)
-#else
- ljmp $0, $ABS(LOCAL (codestart))
-#endif
-
- /*
- * This is a special data area.
- */
-
- . = _start + GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE
-VARIABLE(grub_total_module_size)
- .long 0
- . = _start + GRUB_KERNEL_I386_PC_COMPRESSED_SIZE
-VARIABLE(grub_compressed_size)
- .long 0
- . = _start + GRUB_KERNEL_I386_PC_INSTALL_DOS_PART
-VARIABLE(grub_install_dos_part)
- .long 0xFFFFFFFF
- . = _start + GRUB_KERNEL_I386_PC_INSTALL_BSD_PART
-VARIABLE(grub_install_bsd_part)
- .long 0xFFFFFFFF
- . = _start + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY
-reed_solomon_redundancy:
- .long 0
-
-#ifdef APPLE_CC
-bss_start:
- .long 0
-bss_end:
- .long 0
-#endif
-/*
- * This is the area for all of the special variables.
- */
-
-VARIABLE(grub_boot_drive)
- .byte 0
-
-/* the real mode code continues... */
-LOCAL (codestart):
- cli /* we're not safe here! */
-
- /* set up %ds, %ss, and %es */
- xorw %ax, %ax
- movw %ax, %ds
- movw %ax, %ss
- movw %ax, %es
-
- /* set up the real mode/BIOS stack */
- movl $GRUB_MEMORY_MACHINE_REAL_STACK, %ebp
- movl %ebp, %esp
-
- sti /* we're safe again */
-
- /* save the boot drive */
- ADDR32 movb %dl, EXT_C(grub_boot_drive)
-
- /* reset disk system (%ah = 0) */
- int $0x13
-
- /* transition to protected mode */
- DATA32 call real_to_prot
-
- /* The ".code32" directive takes GAS out of 16-bit mode. */
- .code32
-
- incl %eax
- call grub_gate_a20
-
- movl EXT_C(grub_compressed_size), %edx
- addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART), %edx
- movl reed_solomon_redundancy, %ecx
- leal _start + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART, %eax
- call EXT_C (grub_reed_solomon_recover)
- jmp post_reed_solomon
-
-#include <rs_decoder.S>
-
- .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 $(GRUB_KERNEL_MACHINE_RAW_SIZE + 0x200), %ecx
- addl EXT_C(grub_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, %eax
- shrl $8, %eax
- xorl %ebx, %ebx
- cmpb $0xFF, %ah
- je 1f
- movb %ah, %bl
- movl %ebx, EXT_C(grub_install_dos_part)
-1:
- cmpb $0xFF, %al
- je 2f
- movb %al, %bl
- movl %ebx, EXT_C(grub_install_bsd_part)
-2:
- shrl $24, %edx
- movb $0xFF, %dh
- /* enter the usual booting */
- call prot_to_real
- jmp LOCAL (codestart)
-
-post_reed_solomon:
-
-#ifdef ENABLE_LZMA
- movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %edi
- movl $(_start + GRUB_KERNEL_MACHINE_RAW_SIZE), %esi
- pushl %edi
- pushl %esi
- movl $(BSS_START_SYMBOL - _start), %ecx
- addl EXT_C(grub_total_module_size), %ecx
- subl $GRUB_KERNEL_MACHINE_RAW_SIZE, %ecx
- pushl %ecx
- leal (%edi, %ecx), %ebx
- call _LzmaDecodeA
- /* _LzmaDecodeA clears DF, so no need to run cld */
- popl %ecx
- popl %edi
- popl %esi
-#endif
+ movl %ecx, (LOCAL(real_to_prot_addr) - _start) (%esi)
+ movl %edi, (LOCAL(prot_to_real_addr) - _start) (%esi)
/* copy back the decompressed part (except the modules) */
- subl EXT_C(grub_total_module_size), %ecx
+ movl $(_edata - _start), %ecx
+ movl $(_start), %edi
rep
movsb
+ movl $LOCAL (cont), %esi
+ jmp *%esi
+LOCAL(cont):
+
#if 0
/* copy modules before cleaning out the bss */
movl EXT_C(grub_total_module_size), %ecx
movsb
#endif
-#ifdef APPLE_CC
- /* clean out the bss */
- bss_start_abs = ABS (bss_start)
- bss_end_abs = ABS (bss_end)
-
- movl bss_start_abs, %edi
+ movl %eax, %esi
- /* compute the bss length */
- movl bss_end_abs, %ecx
- subl %edi, %ecx
-#else
/* clean out the bss */
movl $BSS_START_SYMBOL, %edi
/* compute the bss length */
movl $END_SYMBOL, %ecx
subl %edi, %ecx
-#endif
/* clean out */
xorl %eax, %eax
rep
stosb
+ movl %esi, EXT_C(grub_install_dos_part)
+ movb %dl, EXT_C(grub_boot_drive)
+ movl %ebx, EXT_C(grub_install_bsd_part)
+
/*
* Call the start of main body of C code.
*/
call EXT_C(grub_main)
-#include "../realmode.S"
-
-/*
- * grub_gate_a20(int on)
- *
- * Gate address-line 20 for high memory.
- *
- * This routine is probably overconservative in what it does, but so what?
- *
- * It also eats any keystrokes in the keyboard buffer. :-(
- */
-
-grub_gate_a20:
- movl %eax, %edx
-
-gate_a20_test_current_state:
- /* first of all, test if already in a good state */
- call gate_a20_check_state
- cmpb %al, %dl
- jnz gate_a20_try_bios
- ret
-
-gate_a20_try_bios:
- /* second, try a BIOS call */
- pushl %ebp
- call prot_to_real
-
- .code16
- movw $0x2400, %ax
- testb %dl, %dl
- jz 1f
- incw %ax
-1: int $0x15
-
- DATA32 call real_to_prot
- .code32
-
- popl %ebp
- call gate_a20_check_state
- cmpb %al, %dl
- jnz gate_a20_try_system_control_port_a
- ret
-
-gate_a20_try_system_control_port_a:
- /*
- * In macbook, the keyboard test would hang the machine, so we move
- * this forward.
- */
- /* fourth, try the system control port A */
- inb $0x92
- andb $(~0x03), %al
- testb %dl, %dl
- jz 6f
- orb $0x02, %al
-6: outb $0x92
-
- /* When turning off Gate A20, do not check the state strictly,
- because a failure is not fatal usually, and Gate A20 is always
- on some modern machines. */
- testb %dl, %dl
- jz 7f
- call gate_a20_check_state
- cmpb %al, %dl
- jnz gate_a20_try_keyboard_controller
-7: ret
-
-gate_a20_flush_keyboard_buffer:
- inb $0x64
- andb $0x02, %al
- jnz gate_a20_flush_keyboard_buffer
-2:
- inb $0x64
- andb $0x01, %al
- jz 3f
- inb $0x60
- jmp 2b
-3:
- ret
-
-gate_a20_try_keyboard_controller:
- /* third, try the keyboard controller */
- call gate_a20_flush_keyboard_buffer
-
- movb $0xd1, %al
- outb $0x64
-4:
- inb $0x64
- andb $0x02, %al
- jnz 4b
-
- movb $0xdd, %al
- testb %dl, %dl
- jz 5f
- orb $0x02, %al
-5: outb $0x60
- call gate_a20_flush_keyboard_buffer
-
- /* output a dummy command (USB keyboard hack) */
- movb $0xff, %al
- outb $0x64
- call gate_a20_flush_keyboard_buffer
-
- call gate_a20_check_state
- cmpb %al, %dl
- /* everything failed, so restart from the beginning */
- jnz gate_a20_try_bios
- ret
-
-gate_a20_check_state:
- /* iterate the checking for a while */
- movl $100, %ecx
-1:
- call 3f
- cmpb %al, %dl
- jz 2f
- loop 1b
-2:
- ret
-3:
- pushl %ebx
- pushl %ecx
- xorl %eax, %eax
- /* compare the byte at 0x8000 with that at 0x108000 */
- movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %ebx
- pushl %ebx
- /* save the original byte in CL */
- movb (%ebx), %cl
- /* store the value at 0x108000 in AL */
- addl $0x100000, %ebx
- movb (%ebx), %al
- /* try to set one less value at 0x8000 */
- popl %ebx
- movb %al, %ch
- decb %ch
- movb %ch, (%ebx)
- /* serialize */
- outb %al, $0x80
- outb %al, $0x80
- /* obtain the value at 0x108000 in CH */
- pushl %ebx
- addl $0x100000, %ebx
- movb (%ebx), %ch
- /* this result is 1 if A20 is on or 0 if it is off */
- subb %ch, %al
- xorb $1, %al
- /* restore the original */
- popl %ebx
- movb %cl, (%ebx)
- popl %ecx
- popl %ebx
- ret
+LOCAL(real_to_prot_addr):
+ .long 0
+LOCAL(prot_to_real_addr):
+ .long 0
-#ifdef ENABLE_LZMA
-#include "lzma_decode.S"
-#endif
+ .macro PROT_TO_REAL
+ movl LOCAL(prot_to_real_addr), %eax
+ call *%eax
+ .endm
-/*
- * The code beyond this point is compressed. Assert that the uncompressed
- * code fits GRUB_KERNEL_MACHINE_RAW_SIZE.
- */
- . = _start + GRUB_KERNEL_MACHINE_RAW_SIZE
+ .macro REAL_TO_PROT
+ movl LOCAL(real_to_prot_addr), %eax
+ DATA32 call *%ax
+ .endm
/*
* grub_exit()
* Exit the system.
*/
FUNCTION(grub_exit)
- call prot_to_real
+ PROT_TO_REAL
.code16
/* Tell the BIOS a boot failure. If this does not work, reboot. */
int $0x18
shll $16, %edx
addl %eax, %edx
- call prot_to_real
+ PROT_TO_REAL
.code16
pushl %ebx
addw $10, %sp
movw %ax, %cx
- DATA32 call real_to_prot
+ REAL_TO_PROT
.code32
movzwl %cx, %eax
ret
#include "../int.S"
+
+ .bss
+VARIABLE(grub_boot_drive)
+ .byte 0
+VARIABLE(grub_install_dos_part)
+ .long 0xFFFFFFFF
+VARIABLE(grub_install_bsd_part)
+ .long 0xFFFFFFFF
protstack:
.long GRUB_MEMORY_MACHINE_PROT_STACK
+ .macro PROT_TO_REAL
+ call prot_to_real
+ .endm
+
+ .macro REAL_TO_PROT
+ DATA32 call real_to_prot
+ .endm
+
/*
* This is the Global Descriptor Table
*
/* return on the old (or initialized) stack! */
ret
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2009,2010 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/i386/pc/memory.h>
prot_to_real:
/* just in case, set GDT */
#ifndef OFFSETS_HEADER
#define OFFSETS_HEADER 1
-/* The offset of GRUB_TOTAL_MODULE_SIZE. */
-#define GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE 0x8
+/* The offset of GRUB_COMPRESSED_SIZE. */
+#define GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE 0x08
/* The offset of GRUB_COMPRESSED_SIZE. */
-#define GRUB_KERNEL_I386_PC_COMPRESSED_SIZE 0x0c
+#define GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE 0x0c
/* The offset of GRUB_INSTALL_DOS_PART. */
#define GRUB_KERNEL_I386_PC_INSTALL_DOS_PART 0x10
/* Offset of reed_solomon_redundancy. */
#define GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY 0x18
-/* The size of the first region which won't be compressed. */
-#define GRUB_KERNEL_I386_PC_RAW_SIZE 0xc70
-
#define GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART 0x6e0
/* The segment where the kernel is loaded. */
#define GRUB_BOOT_I386_PC_KERNEL_SEG 0x800
-#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x8200
+#define GRUB_KERNEL_I386_PC_LINK_ADDR 0x9000
/* The upper memory area (starting at 640 kiB). */
#define GRUB_MEMORY_I386_PC_UPPER 0xa0000
#define GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE 12
#define GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS 0x4400
-#define GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE 0
#define GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR 0x4400
#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4
#define GRUB_BOOT_MACHINE_KERNEL_SEG GRUB_OFFSETS_CONCAT (GRUB_BOOT_, GRUB_MACHINE, _KERNEL_SEG)
#define GRUB_MEMORY_MACHINE_UPPER GRUB_OFFSETS_CONCAT (GRUB_MEMORY_, GRUB_MACHINE, _UPPER)
-#define GRUB_KERNEL_MACHINE_RAW_SIZE GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _RAW_SIZE)
#define GRUB_KERNEL_MACHINE_INSTALL_BSD_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _INSTALL_BSD_PART)
#define GRUB_KERNEL_MACHINE_INSTALL_DOS_PART GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _INSTALL_DOS_PART)
#define GRUB_MACHINE_LINK_ADDR GRUB_OFFSETS_CONCAT (GRUB_KERNEL_, GRUB_MACHINE, _LINK_ADDR)
+
+#define GRUB_DECOMPRESSOR_MACHINE_COMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _COMPRESSED_SIZE)
+#define GRUB_DECOMPRESSOR_MACHINE_UNCOMPRESSED_SIZE GRUB_OFFSETS_CONCAT (GRUB_DECOMPRESSOR_, GRUB_MACHINE, _UNCOMPRESSED_SIZE)
#endif
#ifndef ASM_FILE
#define TARGET_NO_FIELD 0xffffffff
typedef enum {
- COMPRESSION_AUTO, COMPRESSION_NONE, COMPRESSION_XZ
+ COMPRESSION_AUTO, COMPRESSION_NONE, COMPRESSION_XZ, COMPRESSION_LZMA
} grub_compression_t;
struct image_target_desc
enum
{
PLATFORM_FLAGS_NONE = 0,
- PLATFORM_FLAGS_LZMA = 1,
PLATFORM_FLAGS_DECOMPRESSORS = 2,
PLATFORM_FLAGS_MODULES_BEFORE_KERNEL = 4,
} flags;
- unsigned raw_size;
unsigned total_module_size;
- unsigned compressed_size;
+ unsigned decompressor_compressed_size;
+ unsigned decompressor_uncompressed_size;
+ unsigned decompressor_uncompressed_addr;
unsigned link_align;
grub_uint16_t elf_target;
unsigned section_align;
.bigendian = 0,
.id = IMAGE_COREBOOT,
.flags = PLATFORM_FLAGS_NONE,
- .raw_size = 0,
.total_module_size = TARGET_NO_FIELD,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.bigendian = 0,
.id = IMAGE_COREBOOT,
.flags = PLATFORM_FLAGS_NONE,
- .raw_size = 0,
.total_module_size = TARGET_NO_FIELD,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.voidp_sizeof = 4,
.bigendian = 0,
.id = IMAGE_I386_PC,
- .flags = PLATFORM_FLAGS_LZMA,
- .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE,
- .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE,
- .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE,
+ .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART,
.voidp_sizeof = 4,
.bigendian = 0,
.id = IMAGE_I386_PC_PXE,
- .flags = PLATFORM_FLAGS_LZMA,
- .raw_size = GRUB_KERNEL_I386_PC_RAW_SIZE,
- .total_module_size = GRUB_KERNEL_I386_PC_TOTAL_MODULE_SIZE,
- .compressed_size = GRUB_KERNEL_I386_PC_COMPRESSED_SIZE,
+ .flags = PLATFORM_FLAGS_DECOMPRESSORS,
+ .total_module_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = GRUB_KERNEL_I386_PC_INSTALL_DOS_PART,
.bigendian = 0,
.id = IMAGE_EFI,
.flags = PLATFORM_FLAGS_NONE,
- .raw_size = 0,
.total_module_size = TARGET_NO_FIELD,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
.section_align = GRUB_PE32_SECTION_ALIGNMENT,
.vaddr_offset = ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE
+ GRUB_PE32_SIGNATURE_SIZE
.bigendian = 0,
.id = IMAGE_I386_IEEE1275,
.flags = PLATFORM_FLAGS_NONE,
- .raw_size = 0,
.total_module_size = TARGET_NO_FIELD,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.bigendian = 0,
.id = IMAGE_QEMU,
.flags = PLATFORM_FLAGS_NONE,
- .raw_size = 0,
.total_module_size = TARGET_NO_FIELD,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.bigendian = 0,
.id = IMAGE_EFI,
.flags = PLATFORM_FLAGS_NONE,
- .raw_size = 0,
.total_module_size = TARGET_NO_FIELD,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
.section_align = GRUB_PE32_SECTION_ALIGNMENT,
.vaddr_offset = EFI64_HEADER_SIZE,
.install_dos_part = TARGET_NO_FIELD,
.bigendian = 0,
.id = IMAGE_YEELOONG_FLASH,
.flags = PLATFORM_FLAGS_DECOMPRESSORS,
- .raw_size = 0,
.total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.bigendian = 0,
.id = IMAGE_FULOONG2F_FLASH,
.flags = PLATFORM_FLAGS_DECOMPRESSORS,
- .raw_size = 0,
.total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.bigendian = 0,
.id = IMAGE_LOONGSON_ELF,
.flags = PLATFORM_FLAGS_DECOMPRESSORS,
- .raw_size = 0,
.total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.bigendian = 1,
.id = IMAGE_PPC,
.flags = PLATFORM_FLAGS_NONE,
- .raw_size = 0,
.total_module_size = TARGET_NO_FIELD,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.bigendian = 1,
.id = IMAGE_SPARC64_RAW,
.flags = PLATFORM_FLAGS_NONE,
- .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE,
.total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.bigendian = 1,
.id = IMAGE_SPARC64_AOUT,
.flags = PLATFORM_FLAGS_NONE,
- .raw_size = GRUB_KERNEL_SPARC64_IEEE1275_RAW_SIZE,
.total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.bigendian = 0,
.id = IMAGE_EFI,
.flags = PLATFORM_FLAGS_NONE,
- .raw_size = 0,
.total_module_size = TARGET_NO_FIELD,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_size = TARGET_NO_FIELD,
+ .decompressor_uncompressed_addr = TARGET_NO_FIELD,
.section_align = GRUB_PE32_SECTION_ALIGNMENT,
.vaddr_offset = EFI64_HEADER_SIZE,
.install_dos_part = TARGET_NO_FIELD,
.id = IMAGE_MIPS_ARC,
.flags = (PLATFORM_FLAGS_DECOMPRESSORS
| PLATFORM_FLAGS_MODULES_BEFORE_KERNEL),
- .raw_size = 0,
.total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.bigendian = 0,
.id = IMAGE_LOONGSON_ELF,
.flags = PLATFORM_FLAGS_DECOMPRESSORS,
- .raw_size = 0,
.total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.bigendian = 1,
.id = IMAGE_QEMU_MIPS_FLASH,
.flags = PLATFORM_FLAGS_DECOMPRESSORS,
- .raw_size = 0,
.total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.bigendian = 0,
.id = IMAGE_QEMU_MIPS_FLASH,
.flags = PLATFORM_FLAGS_DECOMPRESSORS,
- .raw_size = 0,
.total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
.bigendian = 1,
.id = IMAGE_LOONGSON_ELF,
.flags = PLATFORM_FLAGS_DECOMPRESSORS,
- .raw_size = 0,
.total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE,
- .compressed_size = TARGET_NO_FIELD,
+ .decompressor_compressed_size = GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE,
+ .decompressor_uncompressed_size = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE,
+ .decompressor_uncompressed_addr = GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR,
.section_align = 1,
.vaddr_offset = 0,
.install_dos_part = TARGET_NO_FIELD,
static void
compress_kernel_lzma (char *kernel_img, size_t kernel_size,
- char **core_img, size_t *core_size, size_t raw_size)
+ char **core_img, size_t *core_size)
{
CLzmaEncProps props;
unsigned char out_props[5];
props.pb = 2;
props.numThreads = 1;
- if (kernel_size < raw_size)
- grub_util_error (_("the core image is too small"));
-
*core_img = xmalloc (kernel_size);
- memcpy (*core_img, kernel_img, raw_size);
- *core_size = kernel_size - raw_size;
- if (LzmaEncode ((unsigned char *) *core_img + raw_size, core_size,
- (unsigned char *) kernel_img + raw_size,
- kernel_size - raw_size,
+ *core_size = kernel_size;
+ if (LzmaEncode ((unsigned char *) *core_img, core_size,
+ (unsigned char *) kernel_img,
+ kernel_size,
&props, out_props, &out_props_size,
0, NULL, &g_Alloc, &g_Alloc) != SZ_OK)
grub_util_error (_("cannot compress the kernel image"));
-
- *core_size += raw_size;
}
#ifdef HAVE_LIBLZMA
static void
compress_kernel_xz (char *kernel_img, size_t kernel_size,
- char **core_img, size_t *core_size, size_t raw_size)
+ char **core_img, size_t *core_size)
{
lzma_stream strm = LZMA_STREAM_INIT;
lzma_ret xzret;
{ .id = LZMA_VLI_UNKNOWN, .options = NULL}
};
- if (kernel_size < raw_size)
- grub_util_error (_("the core image is too small"));
-
xzret = lzma_stream_encoder (&strm, fltrs, LZMA_CHECK_NONE);
if (xzret != LZMA_OK)
grub_util_error (_("cannot compress the kernel image"));
*core_img = xmalloc (kernel_size);
- memcpy (*core_img, kernel_img, raw_size);
- *core_size = kernel_size - raw_size;
- strm.next_in = (unsigned char *) kernel_img + raw_size;
- strm.avail_in = kernel_size - raw_size;
- strm.next_out = (unsigned char *) *core_img + raw_size;
+ *core_size = kernel_size;
+ strm.next_in = (unsigned char *) kernel_img;
+ strm.avail_in = kernel_size;
+ strm.next_out = (unsigned char *) *core_img;
strm.avail_out = *core_size;
while (1)
}
*core_size -= strm.avail_out;
-
- *core_size += raw_size;
}
#endif
size_t kernel_size, char **core_img, size_t *core_size,
grub_compression_t comp)
{
- if (image_target->flags & PLATFORM_FLAGS_LZMA)
- {
- compress_kernel_lzma (kernel_img, kernel_size, core_img,
- core_size, image_target->raw_size);
- return;
- }
+ if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
+ && (comp == COMPRESSION_LZMA))
+ {
+ compress_kernel_lzma (kernel_img, kernel_size, core_img,
+ core_size);
+ return;
+ }
#ifdef HAVE_LIBLZMA
if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS
&& (comp == COMPRESSION_XZ))
{
compress_kernel_xz (kernel_img, kernel_size, core_img,
- core_size, image_target->raw_size);
+ core_size);
return;
}
#endif
if (comp == COMPRESSION_AUTO)
comp = image_target->default_compression;
+ if (image_target->id == IMAGE_I386_PC
+ || image_target->id == IMAGE_I386_PC_PXE)
+ comp = COMPRESSION_LZMA;
+
path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
kernel_path = grub_util_get_path (dir, "kernel.img");
&core_img, &core_size, comp);
free (kernel_img);
- if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
- kernel_img = core_img + total_module_size;
- else
- kernel_img = core_img;
-
grub_util_info ("the core size is 0x%x", core_size);
if (!(image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
&& image_target->total_module_size != TARGET_NO_FIELD)
- *((grub_uint32_t *) (kernel_img + image_target->total_module_size))
+ *((grub_uint32_t *) (core_img + image_target->total_module_size))
= grub_host_to_target32 (total_module_size);
- if (image_target->compressed_size != TARGET_NO_FIELD)
- *((grub_uint32_t *) (kernel_img + image_target->compressed_size))
- = grub_host_to_target32 (core_size - image_target->raw_size);
-
- /* If we included a drive in our prefix, let GRUB know it doesn't have to
- prepend the drive told by BIOS. */
- if (image_target->install_dos_part != TARGET_NO_FIELD
- && image_target->install_bsd_part != TARGET_NO_FIELD && prefix[0] == '(')
- {
- *((grub_int32_t *) (kernel_img + image_target->install_dos_part))
- = grub_host_to_target32 (-2);
- *((grub_int32_t *) (kernel_img + image_target->install_bsd_part))
- = grub_host_to_target32 (-2);
- }
if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
{
case COMPRESSION_XZ:
name = "xz_decompress.img";
break;
+ case COMPRESSION_LZMA:
+ name = "lzma_decompress.img";
+ break;
case COMPRESSION_NONE:
name = "none_decompress.img";
break;
decompress_size = grub_util_get_image_size (decompress_path);
decompress_img = grub_util_read_image (decompress_path);
- *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_COMPRESSED_SIZE))
- = grub_host_to_target32 (core_size);
+ if ((image_target->id == IMAGE_I386_PC
+ || image_target->id == IMAGE_I386_PC_PXE)
+ && decompress_size > GRUB_KERNEL_I386_PC_LINK_ADDR - 0x8200)
+ grub_util_error (_("Decompressor is too big"));
- *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_SIZE))
- = grub_host_to_target32 (kernel_size + total_module_size);
+ if (image_target->decompressor_compressed_size != TARGET_NO_FIELD)
+ *((grub_uint32_t *) (decompress_img
+ + image_target->decompressor_compressed_size))
+ = grub_host_to_target32 (core_size);
- if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
- *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR))
- = grub_host_to_target_addr (image_target->link_addr - total_module_size);
- else
- *((grub_uint32_t *) (decompress_img + GRUB_KERNEL_MIPS_LOONGSON_UNCOMPRESSED_ADDR))
- = grub_host_to_target_addr (image_target->link_addr);
+ if (image_target->decompressor_uncompressed_size != TARGET_NO_FIELD)
+ *((grub_uint32_t *) (decompress_img
+ + image_target->decompressor_uncompressed_size))
+ = grub_host_to_target32 (kernel_size + total_module_size);
+ if (image_target->decompressor_uncompressed_addr != TARGET_NO_FIELD)
+ {
+ if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
+ *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr))
+ = grub_host_to_target_addr (image_target->link_addr - total_module_size);
+ else
+ *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr))
+ = grub_host_to_target_addr (image_target->link_addr);
+ }
full_size = core_size + decompress_size;
full_img = xmalloc (full_size);
core_size = full_size;
}
+ /* If we included a drive in our prefix, let GRUB know it doesn't have to
+ prepend the drive told by BIOS. */
+ if (image_target->install_dos_part != TARGET_NO_FIELD
+ && image_target->install_bsd_part != TARGET_NO_FIELD && prefix[0] == '(')
+ {
+ *((grub_int32_t *) (core_img + image_target->install_dos_part))
+ = grub_host_to_target32 (-2);
+ *((grub_int32_t *) (core_img + image_target->install_bsd_part))
+ = grub_host_to_target32 (-2);
+ }
+
switch (image_target->id)
{
case IMAGE_I386_PC:
rom_img = xmalloc (rom_size);
memset (rom_img, 0, rom_size);
- *((grub_int32_t *) (kernel_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR))
+ *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR))
= grub_host_to_target32 ((grub_uint32_t) -rom_size);
memcpy (rom_img, core_img, core_size);