From: Vladimir 'phcoder' Serbinenko Date: Tue, 7 Feb 2012 21:31:14 +0000 (+0100) Subject: * grub-core/lib/i386/relocator16.S: Revert moving A20 code into PM X-Git-Tag: 2.00~685 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=215c90cb822c1704d3b529b300a0835c4e026cd6;p=thirdparty%2Fgrub.git * 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. --- diff --git a/ChangeLog b/ChangeLog index 313d135aa..ede7f8e1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2012-02-07 Vladimir Serbinenko + + * 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 * grub-core/commands/minicmd.c (GRUB_MOD_INIT): Add missing SIZE diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c index 1f0aa0dd1..ac7d4ca4c 100644 --- a/grub-core/lib/i386/relocator.c +++ b/grub-core/lib/i386/relocator.c @@ -25,6 +25,7 @@ #include #include +#include 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; diff --git a/grub-core/lib/i386/relocator16.S b/grub-core/lib/i386/relocator16.S index 8500c2f94..d6c5fe5f8 100644 --- a/grub-core/lib/i386/relocator16.S +++ b/grub-core/lib/i386/relocator16.S @@ -26,6 +26,8 @@ #define PSEUDO_REAL_DSEG 0x20 +#include + #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 index 000000000..b7c96a664 --- /dev/null +++ b/include/grub/i386/relocator_private.h @@ -0,0 +1 @@ +#define GRUB_RELOCATOR16_STACK_SIZE 4096