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.
This commit is contained in:
parent
e9d3421c05
commit
60240b8bc1
12 changed files with 601 additions and 486 deletions
|
@ -47,7 +47,7 @@ FUNCTION(grub_bios_interrupt)
|
|||
movl 24(%edx), %esi
|
||||
movl 28(%edx), %edx
|
||||
|
||||
call prot_to_real
|
||||
PROT_TO_REAL
|
||||
.code16
|
||||
pushf
|
||||
cli
|
||||
|
@ -98,7 +98,7 @@ intno:
|
|||
movw %ax, LOCAL(bios_register_es)
|
||||
|
||||
popf
|
||||
DATA32 call real_to_prot
|
||||
REAL_TO_PROT
|
||||
.code32
|
||||
|
||||
popl %eax
|
||||
|
|
|
@ -156,8 +156,7 @@ grub_machine_init (void)
|
|||
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 ();
|
||||
|
|
|
@ -1,614 +0,0 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 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/>.
|
||||
*/
|
||||
|
||||
#define FIXED_PROPS
|
||||
|
||||
#define LZMA_BASE_SIZE 1846
|
||||
#define LZMA_LIT_SIZE 768
|
||||
|
||||
#define LZMA_PROPERTIES_SIZE 5
|
||||
|
||||
#define kNumTopBits 24
|
||||
#define kTopValue (1 << kNumTopBits)
|
||||
|
||||
#define kNumBitModelTotalBits 11
|
||||
#define kBitModelTotal (1 << kNumBitModelTotalBits)
|
||||
#define kNumMoveBits 5
|
||||
|
||||
|
||||
#define kNumPosBitsMax 4
|
||||
#define kNumPosStatesMax (1 << kNumPosBitsMax)
|
||||
|
||||
#define kLenNumLowBits 3
|
||||
#define kLenNumLowSymbols (1 << kLenNumLowBits)
|
||||
#define kLenNumMidBits 3
|
||||
#define kLenNumMidSymbols (1 << kLenNumMidBits)
|
||||
#define kLenNumHighBits 8
|
||||
#define kLenNumHighSymbols (1 << kLenNumHighBits)
|
||||
|
||||
#define LenChoice 0
|
||||
#define LenChoice2 (LenChoice + 1)
|
||||
#define LenLow (LenChoice2 + 1)
|
||||
#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
|
||||
#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
|
||||
#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
|
||||
|
||||
|
||||
#define kNumStates 12
|
||||
#define kNumLitStates 7
|
||||
|
||||
#define kStartPosModelIndex 4
|
||||
#define kEndPosModelIndex 14
|
||||
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
|
||||
|
||||
#define kNumPosSlotBits 6
|
||||
#define kNumLenToPosStates 4
|
||||
|
||||
#define kNumAlignBits 4
|
||||
#define kAlignTableSize (1 << kNumAlignBits)
|
||||
|
||||
#define kMatchMinLen 2
|
||||
|
||||
#define IsMatch 0
|
||||
#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
|
||||
#define IsRepG0 (IsRep + kNumStates)
|
||||
#define IsRepG1 (IsRepG0 + kNumStates)
|
||||
#define IsRepG2 (IsRepG1 + kNumStates)
|
||||
#define IsRep0Long (IsRepG2 + kNumStates)
|
||||
#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
|
||||
#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
|
||||
#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
|
||||
#define LenCoder (Align + kAlignTableSize)
|
||||
#define RepLenCoder (LenCoder + kNumLenProbs)
|
||||
#define Literal (RepLenCoder + kNumLenProbs)
|
||||
|
||||
#define out_size 8(%ebp)
|
||||
|
||||
#define now_pos -4(%ebp)
|
||||
#define prev_byte -8(%ebp)
|
||||
#define range -12(%ebp)
|
||||
#define code -16(%ebp)
|
||||
#define state -20(%ebp)
|
||||
#define rep0 -24(%ebp)
|
||||
#define rep1 -28(%ebp)
|
||||
#define rep2 -32(%ebp)
|
||||
#define rep3 -36(%ebp)
|
||||
|
||||
#ifdef FIXED_PROPS
|
||||
|
||||
#define FIXED_LC 3
|
||||
#define FIXED_LP 0
|
||||
#define FIXED_PB 2
|
||||
|
||||
#define POS_STATE_MASK ((1 << (FIXED_PB)) - 1)
|
||||
#define LIT_POS_MASK ((1 << (FIXED_LP)) - 1)
|
||||
|
||||
#define LOCAL_SIZE 36
|
||||
|
||||
#else
|
||||
|
||||
#define lc (%ebx)
|
||||
#define lp 4(%ebx)
|
||||
#define pb 8(%ebx)
|
||||
#define probs 12(%ebx)
|
||||
|
||||
#define pos_state_mask -40(%ebp)
|
||||
#define lit_pos_mask -44(%ebp)
|
||||
|
||||
#define LOCAL_SIZE 44
|
||||
|
||||
#endif
|
||||
|
||||
RangeDecoderBitDecode:
|
||||
#ifdef FIXED_PROPS
|
||||
leal (%ebx, %eax, 4), %eax
|
||||
#else
|
||||
shll $2, %eax
|
||||
addl probs, %eax
|
||||
#endif
|
||||
|
||||
movl %eax, %ecx
|
||||
movl (%ecx), %eax
|
||||
|
||||
movl range, %edx
|
||||
shrl $kNumBitModelTotalBits, %edx
|
||||
mull %edx
|
||||
|
||||
cmpl code, %eax
|
||||
jbe 1f
|
||||
|
||||
movl %eax, range
|
||||
movl $kBitModelTotal, %edx
|
||||
subl (%ecx), %edx
|
||||
shrl $kNumMoveBits, %edx
|
||||
addl %edx, (%ecx)
|
||||
clc
|
||||
3:
|
||||
pushf
|
||||
cmpl $kTopValue, range
|
||||
jnc 2f
|
||||
shll $8, code
|
||||
lodsb
|
||||
movb %al, code
|
||||
shll $8, range
|
||||
2:
|
||||
popf
|
||||
ret
|
||||
1:
|
||||
subl %eax, range
|
||||
subl %eax, code
|
||||
movl (%ecx), %edx
|
||||
shrl $kNumMoveBits, %edx
|
||||
subl %edx, (%ecx)
|
||||
stc
|
||||
jmp 3b
|
||||
|
||||
RangeDecoderBitTreeDecode:
|
||||
RangeDecoderReverseBitTreeDecode:
|
||||
movzbl %cl, %ecx
|
||||
xorl %edx, %edx
|
||||
pushl %edx
|
||||
incl %edx
|
||||
pushl %edx
|
||||
|
||||
1:
|
||||
pushl %eax
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
|
||||
addl %edx, %eax
|
||||
call RangeDecoderBitDecode
|
||||
|
||||
popl %edx
|
||||
popl %ecx
|
||||
|
||||
jnc 2f
|
||||
movl 4(%esp), %eax
|
||||
orl %eax, 8(%esp)
|
||||
stc
|
||||
|
||||
2:
|
||||
adcl %edx, %edx
|
||||
popl %eax
|
||||
|
||||
shll $1, (%esp)
|
||||
loop 1b
|
||||
|
||||
popl %ecx
|
||||
subl %ecx, %edx /* RangeDecoderBitTreeDecode */
|
||||
popl %ecx /* RangeDecoderReverseBitTreeDecode */
|
||||
ret
|
||||
|
||||
LzmaLenDecode:
|
||||
pushl %eax
|
||||
addl $LenChoice, %eax
|
||||
call RangeDecoderBitDecode
|
||||
popl %eax
|
||||
jc 1f
|
||||
pushl $0
|
||||
movb $kLenNumLowBits, %cl
|
||||
addl $LenLow, %eax
|
||||
2:
|
||||
movl 12(%esp), %edx
|
||||
shll %cl, %edx
|
||||
addl %edx, %eax
|
||||
3:
|
||||
|
||||
call RangeDecoderBitTreeDecode
|
||||
popl %eax
|
||||
addl %eax, %edx
|
||||
ret
|
||||
|
||||
1:
|
||||
pushl %eax
|
||||
addl $LenChoice2, %eax
|
||||
call RangeDecoderBitDecode
|
||||
popl %eax
|
||||
jc 1f
|
||||
pushl $kLenNumLowSymbols
|
||||
movb $kLenNumMidBits, %cl
|
||||
addl $LenMid, %eax
|
||||
jmp 2b
|
||||
|
||||
1:
|
||||
pushl $(kLenNumLowSymbols + kLenNumMidSymbols)
|
||||
addl $LenHigh, %eax
|
||||
movb $kLenNumHighBits, %cl
|
||||
jmp 3b
|
||||
|
||||
WriteByte:
|
||||
movb %al, prev_byte
|
||||
stosb
|
||||
incl now_pos
|
||||
ret
|
||||
|
||||
/*
|
||||
* int LzmaDecode(CLzmaDecoderState *vs,
|
||||
* const unsigned char *inStream,
|
||||
* unsigned char *outStream,
|
||||
* SizeT outSize);
|
||||
*/
|
||||
|
||||
_LzmaDecodeA:
|
||||
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
subl $LOCAL_SIZE, %esp
|
||||
|
||||
#ifndef ASM_FILE
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
pushl %ebx
|
||||
|
||||
movl %eax, %ebx
|
||||
movl %edx, %esi
|
||||
pushl %ecx
|
||||
#else
|
||||
pushl %edi
|
||||
#endif
|
||||
|
||||
cld
|
||||
|
||||
#ifdef FIXED_PROPS
|
||||
movl %ebx, %edi
|
||||
movl $(Literal + (LZMA_LIT_SIZE << (FIXED_LC + FIXED_LP))), %ecx
|
||||
#else
|
||||
movl $LZMA_LIT_SIZE, %eax
|
||||
movb lc, %cl
|
||||
addb lp, %cl
|
||||
shll %cl, %eax
|
||||
addl $Literal, %eax
|
||||
movl %eax, %ecx
|
||||
movl probs, %edi
|
||||
#endif
|
||||
|
||||
movl $(kBitModelTotal >> 1), %eax
|
||||
|
||||
rep
|
||||
stosl
|
||||
|
||||
popl %edi
|
||||
|
||||
xorl %eax, %eax
|
||||
movl %eax, now_pos
|
||||
movl %eax, prev_byte
|
||||
movl %eax, state
|
||||
|
||||
incl %eax
|
||||
movl %eax, rep0
|
||||
movl %eax, rep1
|
||||
movl %eax, rep2
|
||||
movl %eax, rep3
|
||||
|
||||
#ifndef FIXED_PROPS
|
||||
movl %eax, %edx
|
||||
movb pb, %cl
|
||||
shll %cl, %edx
|
||||
decl %edx
|
||||
movl %edx, pos_state_mask
|
||||
|
||||
movl %eax, %edx
|
||||
movb lp, %cl
|
||||
shll %cl, %edx
|
||||
decl %edx
|
||||
movl %edx, lit_pos_mask;
|
||||
#endif
|
||||
|
||||
/* RangeDecoderInit */
|
||||
negl %eax
|
||||
movl %eax, range
|
||||
|
||||
incl %eax
|
||||
movb $5, %cl
|
||||
|
||||
1:
|
||||
shll $8, %eax
|
||||
lodsb
|
||||
loop 1b
|
||||
|
||||
movl %eax, code
|
||||
|
||||
lzma_decode_loop:
|
||||
movl now_pos, %eax
|
||||
cmpl out_size, %eax
|
||||
|
||||
jb 1f
|
||||
|
||||
#ifndef ASM_FILE
|
||||
xorl %eax, %eax
|
||||
|
||||
popl %ebx
|
||||
popl %edi
|
||||
popl %esi
|
||||
#endif
|
||||
|
||||
movl %ebp, %esp
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
1:
|
||||
#ifdef FIXED_PROPS
|
||||
andl $POS_STATE_MASK, %eax
|
||||
#else
|
||||
andl pos_state_mask, %eax
|
||||
#endif
|
||||
pushl %eax /* posState */
|
||||
movl state, %edx
|
||||
shll $kNumPosBitsMax, %edx
|
||||
addl %edx, %eax
|
||||
pushl %eax /* (state << kNumPosBitsMax) + posState */
|
||||
|
||||
call RangeDecoderBitDecode
|
||||
jc 1f
|
||||
|
||||
movl now_pos, %eax
|
||||
|
||||
#ifdef FIXED_PROPS
|
||||
andl $LIT_POS_MASK, %eax
|
||||
shll $FIXED_LC, %eax
|
||||
movl prev_byte, %edx
|
||||
shrl $(8 - FIXED_LC), %edx
|
||||
#else
|
||||
andl lit_pos_mask, %eax
|
||||
movb lc, %cl
|
||||
shll %cl, %eax
|
||||
negb %cl
|
||||
addb $8, %cl
|
||||
movl prev_byte, %edx
|
||||
shrl %cl, %edx
|
||||
#endif
|
||||
|
||||
addl %edx, %eax
|
||||
movl $LZMA_LIT_SIZE, %edx
|
||||
mull %edx
|
||||
addl $Literal, %eax
|
||||
pushl %eax
|
||||
|
||||
incl %edx /* edx = 1 */
|
||||
|
||||
movl rep0, %eax
|
||||
negl %eax
|
||||
pushl (%edi, %eax) /* matchByte */
|
||||
|
||||
cmpb $kNumLitStates, state
|
||||
jb 5f
|
||||
|
||||
/* LzmaLiteralDecodeMatch */
|
||||
|
||||
3:
|
||||
cmpl $0x100, %edx
|
||||
jae 4f
|
||||
|
||||
xorl %eax, %eax
|
||||
shlb $1, (%esp)
|
||||
adcl %eax, %eax
|
||||
|
||||
pushl %eax
|
||||
pushl %edx
|
||||
|
||||
shll $8, %eax
|
||||
leal 0x100(%edx, %eax), %eax
|
||||
addl 12(%esp), %eax
|
||||
call RangeDecoderBitDecode
|
||||
|
||||
setc %al
|
||||
popl %edx
|
||||
adcl %edx, %edx
|
||||
|
||||
popl %ecx
|
||||
cmpb %cl, %al
|
||||
jz 3b
|
||||
|
||||
5:
|
||||
|
||||
/* LzmaLiteralDecode */
|
||||
|
||||
cmpl $0x100, %edx
|
||||
jae 4f
|
||||
|
||||
pushl %edx
|
||||
movl %edx, %eax
|
||||
addl 8(%esp), %eax
|
||||
call RangeDecoderBitDecode
|
||||
popl %edx
|
||||
adcl %edx, %edx
|
||||
jmp 5b
|
||||
|
||||
4:
|
||||
addl $16, %esp
|
||||
|
||||
movb %dl, %al
|
||||
call WriteByte
|
||||
|
||||
movb state, %al
|
||||
cmpb $4, %al
|
||||
jae 2f
|
||||
xorb %al, %al
|
||||
jmp 3f
|
||||
2:
|
||||
subb $3, %al
|
||||
cmpb $7, %al
|
||||
jb 3f
|
||||
subb $3, %al
|
||||
3:
|
||||
movb %al, state
|
||||
jmp lzma_decode_loop
|
||||
|
||||
1:
|
||||
movl state, %eax
|
||||
addl $IsRep, %eax
|
||||
call RangeDecoderBitDecode
|
||||
jnc 1f
|
||||
|
||||
movl state, %eax
|
||||
addl $IsRepG0, %eax
|
||||
call RangeDecoderBitDecode
|
||||
jc 10f
|
||||
|
||||
movl (%esp), %eax
|
||||
addl $IsRep0Long, %eax
|
||||
call RangeDecoderBitDecode
|
||||
jc 20f
|
||||
|
||||
cmpb $7, state
|
||||
movb $9, state
|
||||
jb 100f
|
||||
addb $2, state
|
||||
100:
|
||||
|
||||
movl $1, %ecx
|
||||
|
||||
3:
|
||||
movl rep0, %edx
|
||||
negl %edx
|
||||
|
||||
4:
|
||||
movb (%edi, %edx), %al
|
||||
call WriteByte
|
||||
loop 4b
|
||||
|
||||
popl %eax
|
||||
popl %eax
|
||||
jmp lzma_decode_loop
|
||||
|
||||
10:
|
||||
movl state, %eax
|
||||
addl $IsRepG1, %eax
|
||||
call RangeDecoderBitDecode
|
||||
movl rep1, %edx
|
||||
jnc 100f
|
||||
|
||||
movl state, %eax
|
||||
addl $IsRepG2, %eax
|
||||
call RangeDecoderBitDecode
|
||||
movl rep2, %edx
|
||||
jnc 1000f
|
||||
movl rep2, %edx
|
||||
xchgl rep3, %edx
|
||||
1000:
|
||||
pushl rep1
|
||||
popl rep2
|
||||
100:
|
||||
xchg rep0, %edx
|
||||
movl %edx, rep1
|
||||
20:
|
||||
|
||||
movl $RepLenCoder, %eax
|
||||
call LzmaLenDecode
|
||||
|
||||
cmpb $7, state
|
||||
movb $8, state
|
||||
jb 100f
|
||||
addb $3, state
|
||||
100:
|
||||
jmp 2f
|
||||
|
||||
1:
|
||||
movl rep0, %eax
|
||||
xchgl rep1, %eax
|
||||
xchgl rep2, %eax
|
||||
movl %eax, rep3
|
||||
|
||||
cmpb $7, state
|
||||
movb $7, state
|
||||
jb 10f
|
||||
addb $3, state
|
||||
10:
|
||||
|
||||
movl $LenCoder, %eax
|
||||
call LzmaLenDecode
|
||||
pushl %edx
|
||||
|
||||
movl $(kNumLenToPosStates - 1), %eax
|
||||
cmpl %eax, %edx
|
||||
jbe 100f
|
||||
movl %eax, %edx
|
||||
100:
|
||||
movb $kNumPosSlotBits, %cl
|
||||
shll %cl, %edx
|
||||
leal PosSlot(%edx), %eax
|
||||
call RangeDecoderBitTreeDecode
|
||||
|
||||
movl %edx, rep0
|
||||
cmpl $kStartPosModelIndex, %edx
|
||||
jb 100f
|
||||
|
||||
movl %edx, %ecx
|
||||
shrl $1, %ecx
|
||||
decl %ecx
|
||||
|
||||
movzbl %dl, %eax
|
||||
andb $1, %al
|
||||
orb $2, %al
|
||||
shll %cl, %eax
|
||||
movl %eax, rep0
|
||||
|
||||
cmpl $kEndPosModelIndex, %edx
|
||||
jae 200f
|
||||
movl rep0, %eax
|
||||
addl $(SpecPos - 1), %eax
|
||||
subl %edx, %eax
|
||||
jmp 300f
|
||||
200:
|
||||
|
||||
subb $kNumAlignBits, %cl
|
||||
|
||||
/* RangeDecoderDecodeDirectBits */
|
||||
xorl %edx, %edx
|
||||
|
||||
1000:
|
||||
shrl $1, range
|
||||
shll $1, %edx
|
||||
|
||||
movl range, %eax
|
||||
cmpl %eax, code
|
||||
jb 2000f
|
||||
subl %eax, code
|
||||
orb $1, %dl
|
||||
2000:
|
||||
|
||||
cmpl $kTopValue, %eax
|
||||
jae 3000f
|
||||
shll $8, range
|
||||
shll $8, code
|
||||
lodsb
|
||||
movb %al, code
|
||||
|
||||
3000:
|
||||
loop 1000b
|
||||
|
||||
movb $kNumAlignBits, %cl
|
||||
shll %cl, %edx
|
||||
addl %edx, rep0
|
||||
|
||||
movl $Align, %eax
|
||||
|
||||
300:
|
||||
call RangeDecoderReverseBitTreeDecode
|
||||
addl %ecx, rep0
|
||||
|
||||
100:
|
||||
incl rep0
|
||||
popl %edx
|
||||
|
||||
2:
|
||||
|
||||
addl $kMatchMinLen, %edx
|
||||
movl %edx, %ecx
|
||||
|
||||
jmp 3b
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* 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
|
||||
|
@ -43,203 +43,30 @@
|
|||
|
||||
#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
|
||||
|
@ -255,24 +82,14 @@ post_reed_solomon:
|
|||
movsb
|
||||
#endif
|
||||
|
||||
#ifdef APPLE_CC
|
||||
/* clean out the bss */
|
||||
bss_start_abs = ABS (bss_start)
|
||||
bss_end_abs = ABS (bss_end)
|
||||
movl %eax, %esi
|
||||
|
||||
movl bss_start_abs, %edi
|
||||
|
||||
/* 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
|
||||
|
@ -280,172 +97,29 @@ post_reed_solomon:
|
|||
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"
|
||||
LOCAL(real_to_prot_addr):
|
||||
.long 0
|
||||
LOCAL(prot_to_real_addr):
|
||||
.long 0
|
||||
|
||||
/*
|
||||
* 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. :-(
|
||||
*/
|
||||
.macro PROT_TO_REAL
|
||||
movl LOCAL(prot_to_real_addr), %eax
|
||||
call *%eax
|
||||
.endm
|
||||
|
||||
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
|
||||
|
||||
/*
|
||||
* 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()
|
||||
|
@ -453,7 +127,7 @@ gate_a20_check_state:
|
|||
* 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
|
||||
|
@ -482,7 +156,7 @@ FUNCTION(grub_pxe_call)
|
|||
shll $16, %edx
|
||||
addl %eax, %edx
|
||||
|
||||
call prot_to_real
|
||||
PROT_TO_REAL
|
||||
.code16
|
||||
|
||||
pushl %ebx
|
||||
|
@ -494,7 +168,7 @@ FUNCTION(grub_pxe_call)
|
|||
addw $10, %sp
|
||||
movw %ax, %cx
|
||||
|
||||
DATA32 call real_to_prot
|
||||
REAL_TO_PROT
|
||||
.code32
|
||||
|
||||
movzwl %cx, %eax
|
||||
|
@ -506,3 +180,11 @@ FUNCTION(grub_pxe_call)
|
|||
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
|
||||
|
|
|
@ -51,6 +51,14 @@
|
|||
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
|
||||
*
|
||||
|
@ -162,6 +170,25 @@ protcseg:
|
|||
|
||||
/* 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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue