add the command map.
This commit is contained in:
parent
460515b963
commit
42afef19eb
6 changed files with 257 additions and 5 deletions
24
ChangeLog
24
ChangeLog
|
@ -1,3 +1,27 @@
|
||||||
|
1999-10-21 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
||||||
|
|
||||||
|
Add BIOS drive remapping support for chain-loading some foolish
|
||||||
|
operating systems.
|
||||||
|
|
||||||
|
* stage2/builtins.c (bios_drive_map): New variable.
|
||||||
|
(boot_func): If KERNEL_TYPE is KERNEL_TYPE_CHAINLOADER, check
|
||||||
|
if BIOS_DRIVE_MAP contains meaningful values. If so, search for
|
||||||
|
SAVED_DRIVE in BIOS_DRIVE_MAP and exchange SAVED_DRIVE with the
|
||||||
|
mapped drive if found. And then call set_int13_handler.
|
||||||
|
(map_func): New function.
|
||||||
|
(builtin_map): New variable.
|
||||||
|
(builtin_table): Added a pointer to BUILTIN_MAP.
|
||||||
|
* stage2/asm.S (ABS): New macro.
|
||||||
|
[!STAGE1_5] (set_int13_handler): New function.
|
||||||
|
[!STAGE1_5] (int13_handler): New interrupt handler for the real
|
||||||
|
mode.
|
||||||
|
[!STAGE1_5] (drive_map): New variable.
|
||||||
|
[!STAGE1_5] (int13_handler_end): New label used for just
|
||||||
|
computing the end address of int13_handler.
|
||||||
|
* stage2/shared.h (DRIVE_MAP_SIZE): New macro.
|
||||||
|
(set_int13_handler): Declared.
|
||||||
|
* grub/asmstub.c (set_int13_handler): New function. Do nothing.
|
||||||
|
|
||||||
1999-10-20 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
1999-10-20 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
||||||
|
|
||||||
* stage2/builtins.c (find_func): Print only the device names.
|
* stage2/builtins.c (find_func): Print only the device names.
|
||||||
|
|
3
NEWS
3
NEWS
|
@ -15,6 +15,9 @@ New in 0.5.94:
|
||||||
added.
|
added.
|
||||||
* The command "find" searches for a filename in all devices and print
|
* The command "find" searches for a filename in all devices and print
|
||||||
the list of the device which contain the file.
|
the list of the device which contain the file.
|
||||||
|
* 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
|
||||||
|
an operating system resides at a non-first drive.
|
||||||
|
|
||||||
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,12 @@ gateA20 (int linear)
|
||||||
/* Nothing to do in the simulator. */
|
/* Nothing to do in the simulator. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copy MAP to the drive map and set up the int13 handler. */
|
||||||
|
void
|
||||||
|
set_int13_handler (unsigned short *map)
|
||||||
|
{
|
||||||
|
/* Nothing to do in the simulator. */
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
get_code_end (void)
|
get_code_end (void)
|
||||||
|
|
141
stage2/asm.S
141
stage2/asm.S
|
@ -22,6 +22,12 @@
|
||||||
|
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
|
|
||||||
|
#ifdef STAGE1_5
|
||||||
|
#define ABS(x) ((x) - EXT_C(main) + 0x2200)
|
||||||
|
#else
|
||||||
|
#define ABS(x) ((x) - EXT_C(main) + 0x8200)
|
||||||
|
#endif
|
||||||
|
|
||||||
.file "asm.S"
|
.file "asm.S"
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
@ -46,11 +52,7 @@ ENTRY(main)
|
||||||
* Guarantee that "main" is loaded at 0x0:0x8200 in stage2 and
|
* Guarantee that "main" is loaded at 0x0:0x8200 in stage2 and
|
||||||
* at 0x0:0x2200 in stage1.5.
|
* at 0x0:0x2200 in stage1.5.
|
||||||
*/
|
*/
|
||||||
#ifndef STAGE1_5
|
ljmp $0, $ABS(codestart)
|
||||||
ljmp $0, $(codestart - EXT_C(main) + 0x8200)
|
|
||||||
#else
|
|
||||||
ljmp $0, $(codestart - EXT_C(main) + 0x2200)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compatibility version number
|
* Compatibility version number
|
||||||
|
@ -153,6 +155,135 @@ ENTRY(stop_floppy)
|
||||||
outb %al, %dx
|
outb %al, %dx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set_int13_handler(map)
|
||||||
|
*
|
||||||
|
* Copy MAP to the drive map and set up int13_handler.
|
||||||
|
*/
|
||||||
|
ENTRY(set_int13_handler)
|
||||||
|
pushl %ebp
|
||||||
|
movl %esp, %ebp
|
||||||
|
|
||||||
|
pushl %ecx
|
||||||
|
pushl %edi
|
||||||
|
pushl %esi
|
||||||
|
|
||||||
|
/* copy MAP to the drive map */
|
||||||
|
movl $DRIVE_MAP_SIZE, %ecx
|
||||||
|
movl $ABS(drive_map), %edi
|
||||||
|
movl 4(%ebp), %esi
|
||||||
|
cld
|
||||||
|
rep
|
||||||
|
movsb
|
||||||
|
|
||||||
|
/* save the original int13 handler */
|
||||||
|
movw 0x13 * 4, %ax
|
||||||
|
movw %ax, int13_offset
|
||||||
|
movw 0x13 * 4 + 2, %ax
|
||||||
|
movw %ax, int13_segment
|
||||||
|
|
||||||
|
/* get the lower memory size */
|
||||||
|
movl $EXT_C(mbi), %edi
|
||||||
|
movl 4(%edi), %eax
|
||||||
|
/* decrease the lower memory size and set it to the BIOS memory */
|
||||||
|
decl %eax
|
||||||
|
movw %ax, 0x413
|
||||||
|
/* compute the segment */
|
||||||
|
shll $6, %eax
|
||||||
|
|
||||||
|
/* save the new int13 handler */
|
||||||
|
movw %ax, 0x13 * 4 + 2
|
||||||
|
xorw %ax, %ax
|
||||||
|
movw %ax, 0x13 * 4
|
||||||
|
|
||||||
|
/* copy int13_handler to the reserved area */
|
||||||
|
shll $4, %eax
|
||||||
|
movl %eax, %edi
|
||||||
|
movl $ABS(int13_handler), %esi
|
||||||
|
movl $(int13_handler_end - int13_handler), %ecx
|
||||||
|
rep
|
||||||
|
movsb
|
||||||
|
|
||||||
|
popl %esi
|
||||||
|
popl %edi
|
||||||
|
popl %ecx
|
||||||
|
popl %ebp
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map a drive to another drive.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.code16
|
||||||
|
|
||||||
|
int13_handler:
|
||||||
|
pushw %ax
|
||||||
|
pushw %bp
|
||||||
|
movw %sp, %bp
|
||||||
|
|
||||||
|
pushw %ds
|
||||||
|
pushw %si
|
||||||
|
|
||||||
|
/* set %ds to %cs */
|
||||||
|
movw %cs, %ax
|
||||||
|
movw %ax, %ds
|
||||||
|
/* set %si to the drive map */
|
||||||
|
movw $(drive_map - int13_handler), %si
|
||||||
|
/* find the drive number from the drive map */
|
||||||
|
1:
|
||||||
|
lodsw
|
||||||
|
/* check if this is the end */
|
||||||
|
testw %ax, %ax
|
||||||
|
jz 2f
|
||||||
|
/* check if this matches the drive number */
|
||||||
|
cmpb %al, %dl
|
||||||
|
jne 1b
|
||||||
|
/* if so, perform the mapping */
|
||||||
|
movb %ah, %dl
|
||||||
|
2:
|
||||||
|
/* restore %si and %ds */
|
||||||
|
popw %si
|
||||||
|
popw %ds
|
||||||
|
/* save %ax in the stack */
|
||||||
|
pushw %ax
|
||||||
|
/* set %ax and %bp to the original values */
|
||||||
|
movw 2(%bp), %ax
|
||||||
|
movw (%bp), %bp
|
||||||
|
/* simulate the interrupt call */
|
||||||
|
pushf
|
||||||
|
/* ljmp */
|
||||||
|
.byte 0x9a
|
||||||
|
int13_offset: .word 0
|
||||||
|
int13_segment: .word 0
|
||||||
|
/* restore %bp */
|
||||||
|
movw %sp, %bp
|
||||||
|
/* save %ax */
|
||||||
|
pushw %ax
|
||||||
|
/* check if should map the drive number */
|
||||||
|
movw 4(%bp), %ax
|
||||||
|
cmpw $0x8, %ax
|
||||||
|
jne 3f
|
||||||
|
cmpw $0x15, %ax
|
||||||
|
jne 3f
|
||||||
|
/* check if the mapping was performed */
|
||||||
|
movw (%bp), %ax
|
||||||
|
testw %ax, %ax
|
||||||
|
jz 3f
|
||||||
|
/* perform the mapping */
|
||||||
|
movb %al, %dl
|
||||||
|
3:
|
||||||
|
popw %ax
|
||||||
|
movw 2(%bp), %bp
|
||||||
|
addw $6, %sp
|
||||||
|
iret
|
||||||
|
|
||||||
|
drive_map: .space (DRIVE_MAP_SIZE + 1) * 2
|
||||||
|
int13_handler_end:
|
||||||
|
|
||||||
|
.code32
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* chain_stage1(segment, offset, part_table_addr)
|
* chain_stage1(segment, offset, part_table_addr)
|
||||||
*
|
*
|
||||||
|
|
|
@ -46,6 +46,8 @@ int normal_color;
|
||||||
int highlight_color;
|
int highlight_color;
|
||||||
/* The timeout. */
|
/* The timeout. */
|
||||||
int grub_timeout = -1;
|
int grub_timeout = -1;
|
||||||
|
/* The BIOS drive map. */
|
||||||
|
static unsigned short bios_drive_map[DRIVE_MAP_SIZE + 1];
|
||||||
|
|
||||||
/* Initialize the data for builtins. */
|
/* Initialize the data for builtins. */
|
||||||
void
|
void
|
||||||
|
@ -101,6 +103,29 @@ boot_func (char *arg, int flags)
|
||||||
|
|
||||||
case KERNEL_TYPE_CHAINLOADER:
|
case KERNEL_TYPE_CHAINLOADER:
|
||||||
/* Chainloader */
|
/* Chainloader */
|
||||||
|
|
||||||
|
/* Check if we should set the int13 handler. */
|
||||||
|
if (bios_drive_map[0] != 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Search for SAVED_DRIVE. */
|
||||||
|
for (i = 0; i <= DRIVE_MAP_SIZE; i++)
|
||||||
|
{
|
||||||
|
if (! bios_drive_map[i])
|
||||||
|
break;
|
||||||
|
else if ((bios_drive_map[i] & 0xFF) == saved_drive)
|
||||||
|
{
|
||||||
|
/* Exchage SAVED_DRIVE with the mapped drive. */
|
||||||
|
saved_drive = (bios_drive_map[i] >> 8) & 0xFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the handler. This is somewhat dangerous. */
|
||||||
|
set_int13_handler (bios_drive_map);
|
||||||
|
}
|
||||||
|
|
||||||
gateA20 (0);
|
gateA20 (0);
|
||||||
boot_drive = saved_drive;
|
boot_drive = saved_drive;
|
||||||
chain_stage1 (0, BOOTSEC_LOCATION, BOOTSEC_LOCATION - 16);
|
chain_stage1 (0, BOOTSEC_LOCATION, BOOTSEC_LOCATION - 16);
|
||||||
|
@ -1432,6 +1457,62 @@ static struct builtin builtin_makeactive =
|
||||||
" This command is limited to _primary_ PC partitions on a hard disk."
|
" This command is limited to _primary_ PC partitions on a hard disk."
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* map */
|
||||||
|
/* Map FROM_DRIVE to TO_DRIVE. */
|
||||||
|
static int
|
||||||
|
map_func (char *arg, int flags)
|
||||||
|
{
|
||||||
|
char *to_drive;
|
||||||
|
char *from_drive;
|
||||||
|
unsigned long to, from;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
to_drive = arg;
|
||||||
|
from_drive = skip_to (0, arg);
|
||||||
|
|
||||||
|
/* Get the drive number for TO_DRIVE. */
|
||||||
|
set_device (to_drive);
|
||||||
|
if (errnum)
|
||||||
|
return 1;
|
||||||
|
to = current_drive;
|
||||||
|
|
||||||
|
/* Get the drive number for FROM_DRIVE. */
|
||||||
|
set_device (from_drive);
|
||||||
|
if (errnum)
|
||||||
|
return 1;
|
||||||
|
from = current_drive;
|
||||||
|
|
||||||
|
/* If TO and FROM is the same, do nothing. */
|
||||||
|
if (to == from)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Search for an empty slot in BIOS_DRIVE_MAP. */
|
||||||
|
for (i = 0; i <= DRIVE_MAP_SIZE; i++)
|
||||||
|
if (! bios_drive_map[i])
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i > DRIVE_MAP_SIZE)
|
||||||
|
{
|
||||||
|
errnum = ERR_WONT_FIT;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bios_drive_map[i] = from | (to << 8);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct builtin builtin_map =
|
||||||
|
{
|
||||||
|
"map",
|
||||||
|
map_func,
|
||||||
|
BUILTIN_CMDLINE,
|
||||||
|
"map TO_DRIVE FROM_DRIVE",
|
||||||
|
"Map the drive FROM_DRIVE to the drive TO_DRIVE. This is necessary"
|
||||||
|
" when you chain-load some operating systems, such as DOS, if such a"
|
||||||
|
" OS resides at a non-first drive."
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* module */
|
/* module */
|
||||||
static int
|
static int
|
||||||
|
@ -2101,6 +2182,7 @@ struct builtin *builtin_table[] =
|
||||||
&builtin_install,
|
&builtin_install,
|
||||||
&builtin_kernel,
|
&builtin_kernel,
|
||||||
&builtin_makeactive,
|
&builtin_makeactive,
|
||||||
|
&builtin_map,
|
||||||
&builtin_module,
|
&builtin_module,
|
||||||
&builtin_modulenounzip,
|
&builtin_modulenounzip,
|
||||||
&builtin_password,
|
&builtin_password,
|
||||||
|
|
|
@ -117,6 +117,9 @@ extern char *grub_scratch_mem;
|
||||||
#define MENU_BUF (UNIQUE_BUF + UNIQUE_BUFLEN)
|
#define MENU_BUF (UNIQUE_BUF + UNIQUE_BUFLEN)
|
||||||
#define MENU_BUFLEN (0x8000 + PASSWORD_BUF - UNIQUE_BUF)
|
#define MENU_BUFLEN (0x8000 + PASSWORD_BUF - UNIQUE_BUF)
|
||||||
|
|
||||||
|
/* The size of the drive map. */
|
||||||
|
#define DRIVE_MAP_SIZE 8
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Linux setup parameters
|
* Linux setup parameters
|
||||||
*/
|
*/
|
||||||
|
@ -494,6 +497,9 @@ void cmain (void);
|
||||||
/* Halt the processor (called after an unrecoverable error). */
|
/* Halt the processor (called after an unrecoverable error). */
|
||||||
void stop (void) __attribute__ ((noreturn));
|
void stop (void) __attribute__ ((noreturn));
|
||||||
|
|
||||||
|
/* Copy MAP to the drive map and set up int13_handler. */
|
||||||
|
void set_int13_handler (unsigned short *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