add the command keycode.
This commit is contained in:
parent
1f6d422a9a
commit
24b486cfc3
6 changed files with 246 additions and 5 deletions
28
ChangeLog
28
ChangeLog
|
@ -1,3 +1,31 @@
|
||||||
|
1999-10-23 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
||||||
|
|
||||||
|
* stage2/asm.S [!STAGE1_5] (set_int15_handler): New function.
|
||||||
|
[!STAGE1_5] (unset_int15_handler): Likewise.
|
||||||
|
[!STAGE1_5] (int15_handler): New interrupt handler for the real
|
||||||
|
mode.
|
||||||
|
[!STAGE1_5] (int15_offset): New variable.
|
||||||
|
[!STAGE1_5] (int15_segment): Likewise.
|
||||||
|
[!STAGE1_5] (key_map): Likewise.
|
||||||
|
[!STAGE1_5] (set_int13_handler): Use the macro ABS for
|
||||||
|
INT13_OFFSET and INT13_SEGMENT.
|
||||||
|
* stage2/shared.h (KEY_MAP_SIZE): New macro.
|
||||||
|
(set_int15_handler): Declared.
|
||||||
|
(unset_int15_handler): Likewise.
|
||||||
|
* stage2/builtins.c (boot_func): Do not allow I to be equal to
|
||||||
|
DRIVE_MAP_SIZE.
|
||||||
|
Call unset_int15_handler unless KERNEL_TYPE is KERNEL_TYPE_NONE.
|
||||||
|
(map_func): Search for an empty slot till I is less than
|
||||||
|
DRIVE_MAP_SIZE.
|
||||||
|
Check if I is equal to DRIVE_MAP_SIZE instead of if I is greater
|
||||||
|
than DRIVE_MAP_SIZE.
|
||||||
|
(keycode_func): New function.
|
||||||
|
(builtin_keycode): New variable.
|
||||||
|
(builtin_table): Added a pointer to BUILTIN_KEYCODE.
|
||||||
|
* grub/asmstub.c (set_int15_handler): New function.
|
||||||
|
(unset_int15_handler): Likewise.
|
||||||
|
(key_map): New variable.
|
||||||
|
|
||||||
1999-10-23 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
1999-10-23 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
||||||
|
|
||||||
From Michael Hohmuth <hohmuth@innocent.com>:
|
From Michael Hohmuth <hohmuth@innocent.com>:
|
||||||
|
|
1
NEWS
1
NEWS
|
@ -18,6 +18,7 @@ New in 0.5.94:
|
||||||
* The command "map" maps a drive to another drive so that we can
|
* The command "map" maps a drive to another drive so that we can
|
||||||
chain-load some foolish operating systems (such as DOS) even if such
|
chain-load some foolish operating systems (such as DOS) even if such
|
||||||
an operating system resides at a non-first drive.
|
an operating system resides at a non-first drive.
|
||||||
|
* The command "keycode" maps a key code to another.
|
||||||
|
|
||||||
New in 0.5.93:
|
New in 0.5.93:
|
||||||
* ELF format of FreeBSD kernel is supported.
|
* ELF format of FreeBSD kernel is supported.
|
||||||
|
|
|
@ -597,6 +597,23 @@ gateA20 (int linear)
|
||||||
/* Nothing to do in the simulator. */
|
/* Nothing to do in the simulator. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set up the int15 handler. */
|
||||||
|
void
|
||||||
|
set_int15_handler (void)
|
||||||
|
{
|
||||||
|
/* Nothing to do in the simulator. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore the original int15 handler. */
|
||||||
|
void
|
||||||
|
unset_int15_handler (void)
|
||||||
|
{
|
||||||
|
/* Nothing to do in the simulator. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The key map. */
|
||||||
|
unsigned short key_map[KEY_MAP_SIZE + 1];
|
||||||
|
|
||||||
/* Copy MAP to the drive map and set up the int13 handler. */
|
/* Copy MAP to the drive map and set up the int13 handler. */
|
||||||
void
|
void
|
||||||
set_int13_handler (unsigned short *map)
|
set_int13_handler (unsigned short *map)
|
||||||
|
|
105
stage2/asm.S
105
stage2/asm.S
|
@ -186,6 +186,107 @@ ENTRY(stop_floppy)
|
||||||
outb %al, %dx
|
outb %al, %dx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set_int15_handler(void)
|
||||||
|
*
|
||||||
|
* Set up int15_handler.
|
||||||
|
*/
|
||||||
|
ENTRY(set_int15_handler)
|
||||||
|
/* save the original int15 handler */
|
||||||
|
movw 0x15 * 4, %ax
|
||||||
|
movw %ax, ABS(int15_offset)
|
||||||
|
movw 0x15 * 4 + 2, %ax
|
||||||
|
movw %ax, ABS(int15_segment)
|
||||||
|
|
||||||
|
/* save the new int15 handler */
|
||||||
|
movl $ABS(int15_handler), %eax
|
||||||
|
rorl $4, %eax
|
||||||
|
movw %ax, 0x15 * 4 + 2
|
||||||
|
shrl $28, %eax
|
||||||
|
movw %ax, 0x15 * 4
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unset_int15_handler(void)
|
||||||
|
*
|
||||||
|
* Restore the original int15 handler
|
||||||
|
*/
|
||||||
|
ENTRY(unset_int15_handler)
|
||||||
|
/* check if int15_handler is set */
|
||||||
|
movl $ABS(int15_handler), %eax
|
||||||
|
rorl $4, %eax
|
||||||
|
cmpw %ax, 0x15 * 4 + 2
|
||||||
|
jne 1f
|
||||||
|
shrl $28, %eax
|
||||||
|
cmpw %ax, 0x15 * 4
|
||||||
|
jne 1f
|
||||||
|
|
||||||
|
/* restore the original */
|
||||||
|
movw ABS(int15_offset), %ax
|
||||||
|
movw %ax, 0x15 * 4
|
||||||
|
movw ABS(int15_segment), %ax
|
||||||
|
movw %ax, 0x15 * 4 + 2
|
||||||
|
|
||||||
|
1:
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Translate a key code to another.
|
||||||
|
*/
|
||||||
|
.code16
|
||||||
|
int15_handler:
|
||||||
|
/* check if AH=4F */
|
||||||
|
cmpb $0x4F, %ah
|
||||||
|
jmp 1f
|
||||||
|
|
||||||
|
pushw %dx
|
||||||
|
pushw %ds
|
||||||
|
pushw %si
|
||||||
|
|
||||||
|
/* save %ax in %dx */
|
||||||
|
movw %ax, %dx
|
||||||
|
/* set %ds to 0 */
|
||||||
|
xorw %ax, %ax
|
||||||
|
movw %ax, %ds
|
||||||
|
/* set %si to the key map */
|
||||||
|
movw $ABS(key_map), %si
|
||||||
|
/* find the key code from the key map */
|
||||||
|
2:
|
||||||
|
lodsw
|
||||||
|
/* check if this the end */
|
||||||
|
testw %ax, %ax
|
||||||
|
jz 3f
|
||||||
|
/* check if this matches the key code */
|
||||||
|
cmpb %al, %dl
|
||||||
|
jne 2b
|
||||||
|
/* if so, perform the mapping */
|
||||||
|
movb %ah, %dl
|
||||||
|
3:
|
||||||
|
/* restore %ax */
|
||||||
|
movw %dx, %ax
|
||||||
|
/* restore other registers */
|
||||||
|
popw %si
|
||||||
|
popw %ds
|
||||||
|
popw %dx
|
||||||
|
iret
|
||||||
|
1:
|
||||||
|
/* simulate the interrupt call */
|
||||||
|
pushf
|
||||||
|
/* ljmp */
|
||||||
|
.byte 0x9a
|
||||||
|
int15_offset: .word 0
|
||||||
|
int15_segment: .word 0
|
||||||
|
iret
|
||||||
|
|
||||||
|
.code32
|
||||||
|
|
||||||
|
ENTRY(key_map)
|
||||||
|
.space (KEY_MAP_SIZE + 1) * 2
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set_int13_handler(map)
|
* set_int13_handler(map)
|
||||||
*
|
*
|
||||||
|
@ -209,9 +310,9 @@ ENTRY(set_int13_handler)
|
||||||
|
|
||||||
/* save the original int13 handler */
|
/* save the original int13 handler */
|
||||||
movw 0x13 * 4, %ax
|
movw 0x13 * 4, %ax
|
||||||
movw %ax, int13_offset
|
movw %ax, ABS(int13_offset)
|
||||||
movw 0x13 * 4 + 2, %ax
|
movw 0x13 * 4 + 2, %ax
|
||||||
movw %ax, int13_segment
|
movw %ax, ABS(int13_segment)
|
||||||
|
|
||||||
/* get the lower memory size */
|
/* get the lower memory size */
|
||||||
movl $EXT_C(mbi), %edi
|
movl $EXT_C(mbi), %edi
|
||||||
|
|
|
@ -83,6 +83,12 @@ disk_read_print_func (int sector)
|
||||||
static int
|
static int
|
||||||
boot_func (char *arg, int flags)
|
boot_func (char *arg, int flags)
|
||||||
{
|
{
|
||||||
|
/* Clear the int15 handler if we can boot the kernel successfully.
|
||||||
|
This assumes that the boot code never fails only if KERNEL_TYPE is
|
||||||
|
not KERNEL_TYPE_NONE. Is this assumption is bad? */
|
||||||
|
if (kernel_type != KERNEL_TYPE_NONE)
|
||||||
|
unset_int15_handler ();
|
||||||
|
|
||||||
switch (kernel_type)
|
switch (kernel_type)
|
||||||
{
|
{
|
||||||
case KERNEL_TYPE_FREEBSD:
|
case KERNEL_TYPE_FREEBSD:
|
||||||
|
@ -110,7 +116,7 @@ boot_func (char *arg, int flags)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Search for SAVED_DRIVE. */
|
/* Search for SAVED_DRIVE. */
|
||||||
for (i = 0; i <= DRIVE_MAP_SIZE; i++)
|
for (i = 0; i < DRIVE_MAP_SIZE; i++)
|
||||||
{
|
{
|
||||||
if (! bios_drive_map[i])
|
if (! bios_drive_map[i])
|
||||||
break;
|
break;
|
||||||
|
@ -1465,6 +1471,80 @@ static struct builtin builtin_kernel =
|
||||||
" using this command."
|
" using this command."
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* keycode */
|
||||||
|
static int
|
||||||
|
keycode_func (char *arg, int flags)
|
||||||
|
{
|
||||||
|
char *to_code, *from_code;
|
||||||
|
int to, from;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
to_code = arg;
|
||||||
|
from_code = skip_to (0, to_code);
|
||||||
|
|
||||||
|
safe_parse_maxint (&to_code, &to);
|
||||||
|
if (errnum)
|
||||||
|
return 1;
|
||||||
|
if (to < 0 || to > 0xff)
|
||||||
|
{
|
||||||
|
/* FIXME: more appropriate error code! */
|
||||||
|
errnum = ERR_NUMBER_PARSING;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
safe_parse_maxint (&from_code, &from);
|
||||||
|
if (errnum)
|
||||||
|
return 1;
|
||||||
|
if (from < 0 || to > 0xff)
|
||||||
|
{
|
||||||
|
/* FIXME: more appropriate error code! */
|
||||||
|
errnum = ERR_NUMBER_PARSING;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If TO is identical with FROM, do nothing. */
|
||||||
|
if (to == from)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Find an empty slot. */
|
||||||
|
for (i = 0; i < KEY_MAP_SIZE; i++)
|
||||||
|
{
|
||||||
|
if ((key_map[i] & 0xff) == from)
|
||||||
|
{
|
||||||
|
/* Perhaps the user wants to overwrite the map. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! key_map[i])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == KEY_MAP_SIZE)
|
||||||
|
{
|
||||||
|
errnum = ERR_WONT_FIT;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
key_map[i] = (to << 8) | from;
|
||||||
|
|
||||||
|
/* Ugly but should work. */
|
||||||
|
unset_int15_handler ();
|
||||||
|
set_int15_handler ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct builtin builtin_keycode =
|
||||||
|
{
|
||||||
|
"keycode",
|
||||||
|
keycode_func,
|
||||||
|
BUILTIN_CMDLINE | BUILTIN_MENU,
|
||||||
|
"keycode TO_CODE FROM_CODE",
|
||||||
|
"Change the keyboard map. The keycode FROM_CODE is mapped to the keycode"
|
||||||
|
" TO_CODE. They must be decimal or hexadecimal."
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* makeactive */
|
/* makeactive */
|
||||||
static int
|
static int
|
||||||
|
@ -1517,11 +1597,11 @@ map_func (char *arg, int flags)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Search for an empty slot in BIOS_DRIVE_MAP. */
|
/* Search for an empty slot in BIOS_DRIVE_MAP. */
|
||||||
for (i = 0; i <= DRIVE_MAP_SIZE; i++)
|
for (i = 0; i < DRIVE_MAP_SIZE; i++)
|
||||||
if (! bios_drive_map[i])
|
if (! bios_drive_map[i])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (i > DRIVE_MAP_SIZE)
|
if (i == DRIVE_MAP_SIZE)
|
||||||
{
|
{
|
||||||
errnum = ERR_WONT_FIT;
|
errnum = ERR_WONT_FIT;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -2217,6 +2297,7 @@ struct builtin *builtin_table[] =
|
||||||
&builtin_initrd,
|
&builtin_initrd,
|
||||||
&builtin_install,
|
&builtin_install,
|
||||||
&builtin_kernel,
|
&builtin_kernel,
|
||||||
|
&builtin_keycode,
|
||||||
&builtin_makeactive,
|
&builtin_makeactive,
|
||||||
&builtin_map,
|
&builtin_map,
|
||||||
&builtin_module,
|
&builtin_module,
|
||||||
|
|
|
@ -120,6 +120,10 @@ extern char *grub_scratch_mem;
|
||||||
/* The size of the drive map. */
|
/* The size of the drive map. */
|
||||||
#define DRIVE_MAP_SIZE 8
|
#define DRIVE_MAP_SIZE 8
|
||||||
|
|
||||||
|
/* The size of the key map. */
|
||||||
|
#define KEY_MAP_SIZE 8
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Linux setup parameters
|
* Linux setup parameters
|
||||||
*/
|
*/
|
||||||
|
@ -500,6 +504,15 @@ void stop (void) __attribute__ ((noreturn));
|
||||||
/* Copy MAP to the drive map and set up int13_handler. */
|
/* Copy MAP to the drive map and set up int13_handler. */
|
||||||
void set_int13_handler (unsigned short *map);
|
void set_int13_handler (unsigned short *map);
|
||||||
|
|
||||||
|
/* Set up int15_handler. */
|
||||||
|
void set_int15_handler (void);
|
||||||
|
|
||||||
|
/* Restore the original int15 handler. */
|
||||||
|
void unset_int15_handler (void);
|
||||||
|
|
||||||
|
/* The key map. */
|
||||||
|
extern unsigned short key_map[];
|
||||||
|
|
||||||
/* calls for direct boot-loader chaining */
|
/* calls for direct boot-loader chaining */
|
||||||
void chain_stage1 (int segment, int offset, int part_table_addr)
|
void chain_stage1 (int segment, int offset, int part_table_addr)
|
||||||
__attribute__ ((noreturn));
|
__attribute__ ((noreturn));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue