]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/lib/i386/relocator16.S: Revert moving A20 code into PM
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 7 Feb 2012 21:31:14 +0000 (22:31 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 7 Feb 2012 21:31:14 +0000 (22:31 +0100)
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.

ChangeLog
grub-core/lib/i386/relocator.c
grub-core/lib/i386/relocator16.S
include/grub/i386/relocator_private.h [new file with mode: 0644]

index 313d135aa6296dac4437912279cc4efd67d4027f..ede7f8e1e1be3b4325bcdfbae3ca95813a5ae87a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+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
index 1f0aa0dd1b476382f8fcfd28285e116500bc7c09..ac7d4ca4cb8b0f916e7bc1a67e07c8bea9a0fc51 100644 (file)
@@ -25,6 +25,7 @@
 
 #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;
@@ -200,8 +201,10 @@ grub_relocator16_boot (struct grub_relocator *rel,
 
   /* 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;
index 8500c2f947f2628fbfd8a7aaae1831cfa841ef9c..d6c5fe5f83fcd9881108439e0fa8e9b9337d570b 100644 (file)
@@ -26,6 +26,8 @@
 
 #define PSEUDO_REAL_DSEG 0x20
 
+#include <grub/cpu/relocator_private.h>
+
 #include "relocator_common.S"
        
        .p2align        4       /* force 16-byte alignment */
@@ -63,6 +65,37 @@ VARIABLE(grub_relocator16_start)
        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)
@@ -70,10 +103,9 @@ 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
@@ -101,14 +133,6 @@ LOCAL(gate_a20_check_state):
        /* 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
@@ -137,41 +161,15 @@ LOCAL(gate_a20_check_state):
        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
         */
diff --git a/include/grub/i386/relocator_private.h b/include/grub/i386/relocator_private.h
new file mode 100644 (file)
index 0000000..b7c96a6
--- /dev/null
@@ -0,0 +1 @@
+#define GRUB_RELOCATOR16_STACK_SIZE 4096