add the command ioprobe.
This commit is contained in:
parent
d0f94a1f1c
commit
d7c7eb7897
5 changed files with 126 additions and 72 deletions
22
ChangeLog
22
ChangeLog
|
@ -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
2
NEWS
|
@ -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.
|
||||
|
|
124
stage2/asm.S
124
stage2/asm.S
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue