2005-07-16 Yoshinori K. Okuji <okuji@enbug.org>
* kern/i386/pc/startup.S (grub_gate_a20): Rewritten for robustness. This routine now supports a BIOS call and System Control Port A to modify the gate A20. * include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE): Increased to 0x440.
This commit is contained in:
parent
09f9923fbb
commit
654fc59fe4
3 changed files with 121 additions and 31 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2005-07-16 Yoshinori K. Okuji <okuji@enbug.org>
|
||||||
|
|
||||||
|
* kern/i386/pc/startup.S (grub_gate_a20): Rewritten for
|
||||||
|
robustness. This routine now supports a BIOS call and System
|
||||||
|
Control Port A to modify the gate A20.
|
||||||
|
|
||||||
|
* include/grub/i386/pc/kernel.h (GRUB_KERNEL_MACHINE_RAW_SIZE):
|
||||||
|
Increased to 0x440.
|
||||||
|
|
||||||
2005-07-12 Hollis Blanchard <hollis@penguinppc.org>
|
2005-07-12 Hollis Blanchard <hollis@penguinppc.org>
|
||||||
|
|
||||||
* disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_open): dprintf the
|
* disk/powerpc/ieee1275/ofdisk.c (grub_ofdisk_open): dprintf the
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#define GRUB_KERNEL_MACHINE_PREFIX 0x1c
|
#define GRUB_KERNEL_MACHINE_PREFIX 0x1c
|
||||||
|
|
||||||
/* The size of the first region which won't be compressed. */
|
/* The size of the first region which won't be compressed. */
|
||||||
#define GRUB_KERNEL_MACHINE_RAW_SIZE 0x400
|
#define GRUB_KERNEL_MACHINE_RAW_SIZE 0x440
|
||||||
|
|
||||||
#ifndef ASM_FILE
|
#ifndef ASM_FILE
|
||||||
|
|
||||||
|
|
|
@ -384,50 +384,131 @@ realcseg:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
FUNCTION(grub_gate_a20)
|
FUNCTION(grub_gate_a20)
|
||||||
movl %eax, %ecx
|
movl %eax, %edx
|
||||||
|
|
||||||
call gloop1
|
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 EXT_C(prot_to_real)
|
||||||
|
|
||||||
|
.code16
|
||||||
|
movw $0x2400, %ax
|
||||||
|
testb %dl, %dl
|
||||||
|
jz 1f
|
||||||
|
incw %ax
|
||||||
|
1: int $0x15
|
||||||
|
|
||||||
|
DATA32 call EXT_C(real_to_prot)
|
||||||
|
.code32
|
||||||
|
|
||||||
|
popl %ebp
|
||||||
|
call gate_a20_check_state
|
||||||
|
cmpb %al, %dl
|
||||||
|
jnz gate_a20_try_keyboard_controller
|
||||||
|
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
|
movb $0xd1, %al
|
||||||
outb $0x64
|
outb $0x64
|
||||||
|
4:
|
||||||
gloopint1:
|
|
||||||
inb $0x64
|
inb $0x64
|
||||||
andb $0x02, %al
|
andb $0x02, %al
|
||||||
jnz gloopint1
|
jnz 4b
|
||||||
|
|
||||||
movb $0xdd, %al
|
movb $0xdd, %al
|
||||||
testl %ecx, %ecx
|
testb %dl, %dl
|
||||||
jz gdoit
|
jz 5f
|
||||||
|
|
||||||
orb $0x02, %al
|
orb $0x02, %al
|
||||||
gdoit:
|
5: outb $0x60
|
||||||
outb $0x60
|
call gate_a20_flush_keyboard_buffer
|
||||||
|
|
||||||
call gloop1
|
|
||||||
|
|
||||||
/* output a dummy command (USB keyboard hack) */
|
/* output a dummy command (USB keyboard hack) */
|
||||||
movb $0xff, %al
|
movb $0xff, %al
|
||||||
outb $0x64
|
outb $0x64
|
||||||
call gloop1
|
call gate_a20_flush_keyboard_buffer
|
||||||
|
|
||||||
|
call gate_a20_check_state
|
||||||
|
cmpb %al, %dl
|
||||||
|
jnz gate_a20_try_system_control_port_a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
gloop1:
|
gate_a20_try_system_control_port_a:
|
||||||
inb $0x64
|
/* fourth, try the system control port A */
|
||||||
andb $0x02, %al
|
inb $0x92
|
||||||
jnz gloop1
|
andb $(~0x03), %al
|
||||||
|
testb %dl, %dl
|
||||||
|
jz 6f
|
||||||
|
orb $0x02, %al
|
||||||
|
6: outb $0x92
|
||||||
|
|
||||||
gloop2:
|
call gate_a20_check_state
|
||||||
inb $0x64
|
cmpb %al, %dl
|
||||||
andb $0x01, %al
|
/* everything failed, so restart from the beginning */
|
||||||
jz gloop2ret
|
jnz gate_a20_try_bios
|
||||||
inb $0x60
|
|
||||||
jmp gloop2
|
|
||||||
|
|
||||||
gloop2ret:
|
|
||||||
ret
|
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 0x2000 with that at 0x102000 */
|
||||||
|
movl $GRUB_BOOT_MACHINE_KERNEL_ADDR, %ebx
|
||||||
|
pushl %ebx
|
||||||
|
/* save the original byte in CL */
|
||||||
|
movb (%ebx), %cl
|
||||||
|
/* store the value at 0x102000 in AL */
|
||||||
|
addl $0x100000, %ebx
|
||||||
|
movb (%ebx), %al
|
||||||
|
/* try to set one less value at 0x2000 */
|
||||||
|
popl %ebx
|
||||||
|
movb %al, %ch
|
||||||
|
decb %ch
|
||||||
|
movb %ch, (%ebx)
|
||||||
|
/* serialize */
|
||||||
|
outb $0x80
|
||||||
|
outb $0x80
|
||||||
|
/* store the value at 0x2000 in CH */
|
||||||
|
movb (%ebx), %ch
|
||||||
|
/* this result is 1 if A20 is on or 0 if it is off */
|
||||||
|
subb %ch, %al
|
||||||
|
/* restore the original */
|
||||||
|
movb %cl, (%ebx)
|
||||||
|
popl %ecx
|
||||||
|
popl %ebx
|
||||||
|
ret
|
||||||
|
|
||||||
#include "lzo1x.S"
|
#include "lzo1x.S"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue