+2012-02-07 Vladimir Serbinenko <phcoder@gmail.com>
+
+ * grub-core/lib/i386/relocator16.S: Revert moving A20 code into PM
+ part. Instead setup the correct stack in RM.
+ * grub-core/lib/i386/relocator.c (grub_relocator16_boot): Reserve place
+ for stack.
+ * include/grub/i386/relocator_private.h: New file.
+
2012-02-05 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/commands/minicmd.c (GRUB_MOD_INIT): Add missing SIZE
#include <grub/i386/relocator.h>
#include <grub/relocator_private.h>
+#include <grub/cpu/relocator_private.h>
extern grub_uint8_t grub_relocator_forward_start;
extern grub_uint8_t grub_relocator_forward_end;
/* Put it higher than the byte it checks for A20 check. */
err = grub_relocator_alloc_chunk_align (rel, &ch, 0x8010,
- 0xa0000 - RELOCATOR_SIZEOF (16),
- RELOCATOR_SIZEOF (16), 16,
+ 0xa0000 - RELOCATOR_SIZEOF (16)
+ - GRUB_RELOCATOR16_STACK_SIZE,
+ RELOCATOR_SIZEOF (16)
+ + GRUB_RELOCATOR16_STACK_SIZE, 16,
GRUB_RELOCATOR_PREFERENCE_NONE);
if (err)
return err;
#define PSEUDO_REAL_DSEG 0x20
+#include <grub/cpu/relocator_private.h>
+
#include "relocator_common.S"
.p2align 4 /* force 16-byte alignment */
andl $(~GRUB_MEMORY_CPU_CR4_PAE_ON), %eax
movl %eax, %cr4
+ /* Update other registers. */
+ movl $PSEUDO_REAL_DSEG, %eax
+ movl %eax, %ds
+ movl %eax, %es
+ movl %eax, %fs
+ movl %eax, %gs
+ movl %eax, %ss
+
+ movl %esi, %eax
+ shrl $4, %eax
+ movw %ax, (LOCAL (segment) - LOCAL (base)) (%esi, 1)
+
+ /* jump to a 16 bit segment */
+ ljmp $PSEUDO_REAL_CSEG, $(LOCAL (cont2) - LOCAL(base))
+LOCAL(cont2):
+ .code16
+
+ /* clear the PE bit of CR0 */
+ movl %cr0, %eax
+ andl $(~GRUB_MEMORY_CPU_CR0_PE_ON), %eax
+ movl %eax, %cr0
+
+ /* flush prefetch queue, reload %cs */
+ /* ljmp */
+ .byte 0xea
+ .word LOCAL(cont3)-LOCAL(base)
+LOCAL(segment):
+ .word 0
+
+LOCAL(cont3):
+
/* movw imm16, %ax. */
.byte 0xb8
VARIABLE(grub_relocator16_keep_a20_enabled)
test %ax, %ax
jnz LOCAL(gate_a20_done)
- /* first of all, test if already in a good state */
- call LOCAL(gate_a20_check_state)
- testb %al, %al
- jz LOCAL(gate_a20_done)
+ movw %cs, %ax
+ movw %ax, %ss
+ leaw EXT_C(grub_relocator16_end) + GRUB_RELOCATOR16_STACK_SIZE, %sp
/* second, try a BIOS call */
movw $0x2400, %ax
/* iterate the checking for a while */
movw $100, %cx
1:
- call 3f
- testb %al, %al
- jz 2f
- loop 1b
-2:
- ret
-
-3:
xorw %ax, %ax
movw %ax, %ds
decw %ax
subb %dh, %al
xorb $1, %al
/* restore the original */
- movb %dl, %es:(%di)
+ movb %dl, %ds:(%si)
+
+ testb %al, %al
+ jz LOCAL(gate_a20_done)
+ loop 1b
+2:
ret
LOCAL(gate_a20_done):
- /* Update other registers. */
- movl $PSEUDO_REAL_DSEG, %eax
- movl %eax, %ds
- movl %eax, %es
- movl %eax, %fs
- movl %eax, %gs
- movl %eax, %ss
-
- movl %esi, %eax
- shrl $4, %eax
- movw %ax, (LOCAL (segment) - LOCAL (base)) (%esi, 1)
-
- /* jump to a 16 bit segment */
- ljmp $PSEUDO_REAL_CSEG, $(LOCAL (cont2) - LOCAL(base))
-LOCAL(cont2):
- .code16
-
- /* clear the PE bit of CR0 */
- movl %cr0, %eax
- andl $(~GRUB_MEMORY_CPU_CR0_PE_ON), %eax
- movl %eax, %cr0
-
- /* flush prefetch queue, reload %cs */
- /* ljmp */
- .byte 0xea
- .word LOCAL(cont3)-LOCAL(base)
-LOCAL(segment):
- .word 0
-
-LOCAL(cont3):
-
/* we are in real mode now
* set up the real mode segment registers : DS, SS, ES
*/