add the command ioprobe.

This commit is contained in:
okuji 1999-10-29 10:52:28 +00:00
parent d0f94a1f1c
commit d7c7eb7897
5 changed files with 126 additions and 72 deletions

View file

@ -1,3 +1,25 @@
1999-10-29 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
* stage2/asm.S (track_int13): Defined unconditionally. Do not
use int3 any more, but replace the int13 handler with
set_tf_int13_handler.
(int1_handler): Defined unconditionally. Do not check for 0x0F.
Add missing `$'s. If the code is 0xEC-0xEF, use %dx instead of
immediate. If the code is 0xE4-0xE7, use immediate instead of
%dx. Set %ds to zero before scanning IO_MAP. Check for the
buffer overrun of IO_MAP before adding a port.
[!DEFINE_TRACK_INT13] (int13_first_instruction): Removed.
[!DEFINE_TRACK_INT13] (int3_handler): Likewise.
(set_tf_int13_handler): New interrupt handler.
(set_tf_int13_offset): New variable.
(set_tf_int13_segment): Likewise.
* stage2/builtins.c (ioprobe_func): New function.
(builtin_ioprobe): New variable.
(builtin_table): Added a pointer to BUILTIN_IOPROBE.
* stage2/shared.h (IO_MAP_SIZE): New macro.
(track_int13): Declared.
(io_map): Likewise.
1999-10-29 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
* stage2/char_io.c (print_error) [!STAGE1_5]: Print "Error:"

2
NEWS
View file

@ -21,6 +21,8 @@ New in 0.5.94:
* The command "setkey" maps a key to another.
* The GRUB manual is rewritten, and now consists of three parts and
appendices.
* The command "ioprobe" detects what I/O ports are used for a BIOS
drive.
New in 0.5.93:
* ELF format of FreeBSD kernel is supported.

View file

@ -186,8 +186,7 @@ ENTRY(stop_floppy)
outb %al, %dx
ret
#ifdef DEFINE_TRACK_INT13
/*
* track_int13(int drive)
*
@ -201,40 +200,29 @@ ENTRY(track_int13)
pushl %ebx
pushl %edi
/* computer the linear address of int13 handler */
/* save the original int13 handler */
movl $0x4c, %edi
xorl %ebx, %ebx
xorl %eax, %eax
movw (%edi), %ax
movw %ax, ABS(set_tf_int13_offset)
movw 2(%edi), %ax
shll $4, %eax
movw (%edi), %bx
addl %eax, %ebx
/* save the first intruction */
movb (%ebx), %al
movb %al, ABS(int13_first_instruction)
/* set the first instruction to int3 */
movb $0xCC, (%ebx)
movw %ax, ABS(set_tf_int13_segment)
/* save the new int13 handler */
movl $ABS(set_tf_int13_handler), %eax
movl %eax, (%edi)
/* replace the int1 handler */
movl 0x4, %edi
movl $0x4, %edi
pushl (%edi)
movl $ABS(int1_handler), %eax
movl %eax, (%edi)
/* replace the int3 handler */
movl 0xc, %edi
pushl (%edi)
movl $ABS(int3_handler), %eax
movl %eax, (%edi)
/* read the MBR to call int13 successfully */
movb 8(%ebp), %dl
DATA32 call EXT_C(prot_to_real)
call EXT_C(prot_to_real)
.code16
movw $SCRATCHSEG, %ax
movw %ax, %es
xorw %bx, %bx
@ -247,13 +235,16 @@ ENTRY(track_int13)
DATA32 call EXT_C(real_to_prot)
.code32
/* restore the int3 handler */
movl 0xc, %edi
/* restore the int1 handler */
movl $0x4, %edi
popl (%edi)
/* restore the int1 handler */
movl 0x4, %edi
popl (%edi)
/* restore the int13 handler */
movl $0x4c, %edi
movw ABS(set_tf_int13_offset), %ax
movw %ax, (%edi)
movw ABS(set_tf_int13_segment), %ax
movw %ax, 2(%edi)
popl %edi
popl %ebx
@ -299,15 +290,13 @@ int1_handler:
je 1b
cmpb $0x26, %al
je 1b
cmpb $0x0F, %al
je 1b
cmpb $0x64, %al
jl 2f
cmpb $0x67, %al
jle 1b
2: cmpb 0xF0, %al
2: cmpb $0xF0, %al
jl 3f
cmpb 0xF3, %al
cmpb $0xF3, %al
jle 1b
3: /* check if this code is out* or in* */
@ -318,13 +307,13 @@ int1_handler:
cmpb $0x6F, %al
jle 5f
4: /* in? or out? (immediate operand version) */
4: /* in? or out? (register operand version) */
cmpb $0xEC, %al
jl 6f
cmpb $0xEF, %al
jle 7f
jle 5f
6: /* in? or out? (register operand version) */
6: /* in? or out? (immediate operand version) */
cmpb $0xE4, %al
jl 8f
cmpb $0xE7, %al
@ -337,6 +326,10 @@ int1_handler:
5: /* %dx has a port */
/* set %ds to zero */
xorw %ax, %ax
movw %ax, %ds
/* set %si to the io map */
movw $ABS(io_map), %si
@ -352,7 +345,10 @@ int1_handler:
/* if so, leave from this handler */
jmp 8f
1: /* add the port into the io map */
1: /* check for the buffer overrun */
cmpw $(ABS(io_map) + (IO_MAP_SIZE + 1) * 2), %si
je 8f
/* add the port into the io map */
movw %dx, -2(%si)
8: /* restore registers */
@ -370,52 +366,36 @@ int1_handler:
* call clears the flag automatically.
*
* Note: we need not to clear this flag after the tracking explicitly,
* because int13 restores the original FLAGS.
*
* Note2: In this implementation, ignore the first instruction, because
* int1 is a trap but not a fault.
* because iret restores the original FLAGS.
*/
int13_first_instruction:
.byte 0
int3_handler:
pushw %bp
movw %sp, %bp
set_tf_int13_handler:
/* save %ax int the stack */
pushw %ax
pushw %bx
pushw %ds
/* set the TF flag in the stack */
movw 6(%bp), %ax
orw $0x100, %ax
movw %ax, 6(%bp)
/* restore the first instruction */
movb ABS(int13_first_instruction), %al
movw 4(%bp), %bx
movw %bx, %ds
movw 2(%bp), %bx
decw %bx
movb %al, (%bx)
/* re-execute the first instruction */
movw %bx, 2(%bp)
popw %ds
popw %bx
/* set the TF flag */
pushf
popw %ax
popw %bp
orw $0x100, %ax
pushw %ax
popf
/* restore %ax */
popw %ax
/* simulate the interrupt call */
pushf
/* lcall */
.byte 0x9a
set_tf_int13_offset: .word 0
set_tf_int13_segment: .word 0
iret
.code32
ENTRY(io_map)
#define IO_MAP_SIZE 0
.space (IO_MAP_SIZE + 1) * 2
#endif /* DEFINE_TRACK_INT13 */
/*
* set_int15_handler(void)

View file

@ -1441,6 +1441,49 @@ static struct builtin builtin_install =
" this is the name of the true Stage 2) at boot time."
};
/* ioprobe */
static int
ioprobe_func (char *arg, int flags)
{
#ifdef GRUB_UTIL
errnum = ERR_UNRECOGNIZED;
return 1;
#else /* ! GRUB_UTIL */
unsigned short *port;
/* Get the drive number. */
set_device (arg);
if (errnum)
return 1;
/* Clean out IO_MAP. */
grub_memset ((char *) io_map, 0, IO_MAP_SIZE * sizeof (unsigned short));
/* Track the int13 handler. */
track_int13 (current_drive);
/* Print out the result. */
for (port = io_map; *port != 0; port++)
grub_printf (" 0x%x", (unsigned int) *port);
return 0;
#endif /* ! GRUB_UTIL */
}
static struct builtin builtin_ioprobe =
{
"ioprobe",
ioprobe_func,
BUILTIN_CMDLINE,
"ioprobe DRIVE",
"Probe I/O ports used for the drive DRIVE."
};
/* kernel */
static int
@ -2470,6 +2513,7 @@ struct builtin *builtin_table[] =
&builtin_impsprobe,
&builtin_initrd,
&builtin_install,
&builtin_ioprobe,
&builtin_kernel,
&builtin_makeactive,
&builtin_map,

View file

@ -123,6 +123,8 @@ extern char *grub_scratch_mem;
/* The size of the key map. */
#define KEY_MAP_SIZE 128
/* The size of the io map. */
#define IO_MAP_SIZE 128
/*
* Linux setup parameters
@ -538,9 +540,13 @@ void set_int15_handler (void);
/* Restore the original int15 handler. */
void unset_int15_handler (void);
/* Track the int13 handler to probe I/O address space. */
void track_int13 (int drive);
/* The key map. */
extern unsigned short bios_key_map[];
extern unsigned short ascii_key_map[];
extern unsigned short io_map[];
/* calls for direct boot-loader chaining */
void chain_stage1 (int segment, int offset, int part_table_addr)