/sbin/grub works
This commit is contained in:
parent
db34e7d7f1
commit
3688d873d4
12 changed files with 302 additions and 122 deletions
45
ChangeLog
45
ChangeLog
|
@ -1,3 +1,48 @@
|
||||||
|
1999-03-21 Gordon Matzigkeit <gord@trick.fig.org>
|
||||||
|
|
||||||
|
* shared_src/boot.c (load_image): Make sure we use the mapped
|
||||||
|
address before actually writing data to memaddr.
|
||||||
|
|
||||||
|
* shared_src/char_io.c (get_cmdline): Only zero-terminate if there
|
||||||
|
were leading blanks. This prevents accidental truncation of
|
||||||
|
commands.
|
||||||
|
|
||||||
|
* grub/asmstub.c (get_diskinfo): Cache device geometries as well
|
||||||
|
as file handles.
|
||||||
|
Use the Linux HDIO_GETGEO ioctl to make a better guess at hard
|
||||||
|
disk geometries.
|
||||||
|
|
||||||
|
1999-03-16 Gordon Matzigkeit <gord@trick.fig.org>
|
||||||
|
|
||||||
|
* shared_src/shared.h (geometry_t): Delete typedef, until we
|
||||||
|
actually use it.
|
||||||
|
|
||||||
|
1999-03-16 OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
|
||||||
|
|
||||||
|
* shared_src/asm.S (biosdisk): Use a structure for geometry
|
||||||
|
instead of a integer.
|
||||||
|
(get_diskinfo): Take a pointer to a geometry structure as the
|
||||||
|
second argument, and fill a geometry in it. Return 1 if an error
|
||||||
|
occurs, otherwise return 0.
|
||||||
|
* shared_src/boot.c (bsd_boot): Compute BIOS geometries for BSD.
|
||||||
|
* shared_src/cmdline.c (enter_cmdline): Declare dest_geom as
|
||||||
|
struct geometry.
|
||||||
|
* shared_src/disk_io.c (buf_geom): Declare as struct geometry.
|
||||||
|
* shared_src/filesys.h (SECTORS): Deleted.
|
||||||
|
(HEADS): Likewise.
|
||||||
|
(CYLINDERS): Likewise.
|
||||||
|
* shared_src/shared.h (BIOSDISK_FLAG_LBA_EXTENSION): New macro.
|
||||||
|
(struct geometry): New structure.
|
||||||
|
(buf_geom): Correct the prototype.
|
||||||
|
(get_diskinfo): Likewise.
|
||||||
|
(biosdisk): Likewise.
|
||||||
|
|
||||||
|
1999-03-15 Gordon Matzigkeit <gord@trick.fig.org>
|
||||||
|
|
||||||
|
* grub/asmstub.c (doit): Nested function to get a clean stack
|
||||||
|
frame while in grub_stage2.
|
||||||
|
Use different assembler magic. From OKUJI Yoshinori.
|
||||||
|
|
||||||
1999-03-14 Gordon Matzigkeit <gord@trick.fig.org>
|
1999-03-14 Gordon Matzigkeit <gord@trick.fig.org>
|
||||||
|
|
||||||
* shared_src/stage2.c (run_menu): Use A_REVERSE and A_NORMAL
|
* shared_src/stage2.c (run_menu): Use A_REVERSE and A_NORMAL
|
||||||
|
|
4
NEWS
4
NEWS
|
@ -1,5 +1,9 @@
|
||||||
NEWS - list of user-visible changes between releases of GRUB
|
NEWS - list of user-visible changes between releases of GRUB
|
||||||
|
|
||||||
|
New:
|
||||||
|
* The /sbin/grub stage2 simulator now works for simple cases, and uses
|
||||||
|
the Linux HDIO_GETGEO ioctl to determine hard disk geometry.
|
||||||
|
|
||||||
New in 0.5.91 - 1999-03-14, Gordon Matzigkeit:
|
New in 0.5.91 - 1999-03-14, Gordon Matzigkeit:
|
||||||
* LBA and preliminary AWARD BIOS disk extension support.
|
* LBA and preliminary AWARD BIOS disk extension support.
|
||||||
* Started docs/grub.texi.
|
* Started docs/grub.texi.
|
||||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -692,7 +692,7 @@ fi
|
||||||
PACKAGE=grub
|
PACKAGE=grub
|
||||||
|
|
||||||
|
|
||||||
VERSION=0.5.91
|
VERSION=0.5.92
|
||||||
|
|
||||||
|
|
||||||
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
|
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
|
||||||
|
|
6
debian/changelog
vendored
6
debian/changelog
vendored
|
@ -1,3 +1,9 @@
|
||||||
|
grub (0.5.92) unstable; urgency=low
|
||||||
|
|
||||||
|
*
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
grub (0.5.91) unstable; urgency=low
|
grub (0.5.91) unstable; urgency=low
|
||||||
|
|
||||||
* Added support for LBA mode and preliminary AWARD/AMI hard disk BIOS
|
* Added support for LBA mode and preliminary AWARD/AMI hard disk BIOS
|
||||||
|
|
182
grub/asmstub.c
182
grub/asmstub.c
|
@ -39,10 +39,22 @@ int grub_stage2 (void);
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
# include <sys/ioctl.h> /* ioctl */
|
||||||
|
# include <linux/hdreg.h> /* HDIO_GETGEO */
|
||||||
|
#endif /* __linux__ */
|
||||||
|
|
||||||
/* Simulated memory sizes. */
|
/* Simulated memory sizes. */
|
||||||
#define EXTENDED_MEMSIZE (4 * 1024 * 1024) /* 4MB */
|
#define EXTENDED_MEMSIZE (4 * 1024 * 1024) /* 4MB */
|
||||||
#define CONVENTIONAL_MEMSIZE (640) /* 640kB */
|
#define CONVENTIONAL_MEMSIZE (640) /* 640kB */
|
||||||
|
|
||||||
|
/* Simulated disk sizes. */
|
||||||
|
#define DEFAULT_FD_CYLINDERS 80
|
||||||
|
#define DEFAULT_FD_HEADS 2
|
||||||
|
#define DEFAULT_FD_SECTORS 18
|
||||||
|
#define DEFAULT_HD_CYLINDERS 620
|
||||||
|
#define DEFAULT_HD_HEADS 128
|
||||||
|
#define DEFAULT_HD_SECTORS 63
|
||||||
|
|
||||||
unsigned long install_partition = 0x20000;
|
unsigned long install_partition = 0x20000;
|
||||||
unsigned long boot_drive = 0;
|
unsigned long boot_drive = 0;
|
||||||
|
@ -53,7 +65,7 @@ char config_file[] = "/boot/grub/menu.lst";
|
||||||
char *grub_scratch_mem = 0;
|
char *grub_scratch_mem = 0;
|
||||||
|
|
||||||
#define NUM_DISKS 256
|
#define NUM_DISKS 256
|
||||||
static FILE **disks = 0;
|
static struct geometry *disks = 0;
|
||||||
|
|
||||||
/* The main entry point into this mess. */
|
/* The main entry point into this mess. */
|
||||||
int
|
int
|
||||||
|
@ -65,6 +77,31 @@ grub_stage2 (void)
|
||||||
int i;
|
int i;
|
||||||
char *scratch, *simstack;
|
char *scratch, *simstack;
|
||||||
|
|
||||||
|
/* We need a nested function so that we get a clean stack frame,
|
||||||
|
regardless of how the code is optimized. */
|
||||||
|
static volatile void doit ()
|
||||||
|
{
|
||||||
|
/* Make sure our stack lives in the simulated memory area. */
|
||||||
|
asm volatile ("movl %%esp, %0\n\tmovl %1, %%esp\n"
|
||||||
|
: "&=r" (realstack) : "r" (simstack));
|
||||||
|
|
||||||
|
/* FIXME: Do a setjmp here for the stop command. */
|
||||||
|
if (1)
|
||||||
|
{
|
||||||
|
/* Actually enter the generic stage2 code. */
|
||||||
|
status = 0;
|
||||||
|
init_bios_info ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Somebody aborted. */
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Replace our stack before we use any local variables. */
|
||||||
|
asm volatile ("movl %0, %%esp\n" : : "r" (realstack));
|
||||||
|
}
|
||||||
|
|
||||||
assert (grub_scratch_mem == 0);
|
assert (grub_scratch_mem == 0);
|
||||||
scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15);
|
scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15);
|
||||||
assert (scratch);
|
assert (scratch);
|
||||||
|
@ -93,32 +130,9 @@ grub_stage2 (void)
|
||||||
keypad (stdscr, TRUE);
|
keypad (stdscr, TRUE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Make sure our stack lives in the simulated memory area. */
|
/* Set our stack, and go for it. */
|
||||||
simstack = (char *) RAW_ADDR (PROTSTACKINIT);
|
simstack = (char *) PROTSTACKINIT;
|
||||||
#ifdef SIMULATE_STACK
|
doit ();
|
||||||
__asm __volatile ("movl %%esp, %0;" : "=d" (realstack));
|
|
||||||
__asm __volatile ("movl %0, %%esp" :: "d" (simstack));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
|
||||||
/* FIXME: Do a setjmp here for the stop command. */
|
|
||||||
if (1)
|
|
||||||
{
|
|
||||||
/* Actually enter the generic stage2 code. */
|
|
||||||
status = 0;
|
|
||||||
init_bios_info ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Somebody aborted. */
|
|
||||||
status = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SIMULATE_STACK
|
|
||||||
/* Replace our stack before we use any local variables. */
|
|
||||||
__asm __volatile ("movl %0, %%esp" :: "d" (realstack));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBCURSES
|
#ifdef HAVE_LIBCURSES
|
||||||
endwin ();
|
endwin ();
|
||||||
|
@ -126,8 +140,8 @@ grub_stage2 (void)
|
||||||
|
|
||||||
/* Close off the file pointers we used. */
|
/* Close off the file pointers we used. */
|
||||||
for (i = 0; i < NUM_DISKS; i ++)
|
for (i = 0; i < NUM_DISKS; i ++)
|
||||||
if (disks[i])
|
if (disks[i].flags)
|
||||||
fclose (disks[i]);
|
fclose ((FILE *) disks[i].flags);
|
||||||
|
|
||||||
/* Release memory. */
|
/* Release memory. */
|
||||||
free (disks);
|
free (disks);
|
||||||
|
@ -352,47 +366,107 @@ set_attrib (int attr)
|
||||||
/* Low-level disk I/O. Our stubbed version just returns a file
|
/* Low-level disk I/O. Our stubbed version just returns a file
|
||||||
descriptor, not the actual geometry. */
|
descriptor, not the actual geometry. */
|
||||||
int
|
int
|
||||||
get_diskinfo (int drive)
|
get_diskinfo (int drive, struct geometry *geometry)
|
||||||
{
|
{
|
||||||
/* The unpartitioned device name: /dev/XdX */
|
/* FIXME: this function is truly horrid. We try opening the device,
|
||||||
char devname[9];
|
then severely abuse the GEOMETRY->flags field to pass a file
|
||||||
|
pointer to biosdisk. Thank God nobody's looking at this comment,
|
||||||
|
or my reputation would be ruined. --Gord */
|
||||||
|
|
||||||
/* See if we have a cached device. */
|
/* See if we have a cached device. */
|
||||||
if (disks[drive])
|
if (! disks[drive].flags)
|
||||||
return (int) disks[drive];
|
{
|
||||||
|
/* The unpartitioned device name: /dev/XdX */
|
||||||
|
char devname[9];
|
||||||
|
|
||||||
/* Try opening the drive device. */
|
/* Try opening the drive device. */
|
||||||
strcpy (devname, "/dev/");
|
strcpy (devname, "/dev/");
|
||||||
if (drive & 0x80)
|
|
||||||
devname[5] = 'h';
|
|
||||||
else
|
|
||||||
devname[5] = 'f';
|
|
||||||
devname[6] = 'd';
|
|
||||||
|
|
||||||
/* Check to make sure we don't exceed /dev/hdz. */
|
#ifdef __linux__
|
||||||
devname[7] = (drive & 0x7f) + 'a';
|
/* Linux uses /dev/hda, and /dev/sda, but /dev/fd0. Go figure. */
|
||||||
if (devname[7] > 'z')
|
if (drive & 0x80)
|
||||||
return 0;
|
{
|
||||||
devname[8] = '\0';
|
/* Check to make sure we don't exceed /dev/hdz. */
|
||||||
|
devname[5] = 'h';
|
||||||
|
devname[7] = 'a' + (drive & 0x7f);
|
||||||
|
if (devname[7] > 'z')
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
devname[5] = 'f';
|
||||||
|
devname[7] = '0' + drive;
|
||||||
|
if (devname[7] > '9')
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#else /* ! __linux__ */
|
||||||
|
if (drive & 0x80)
|
||||||
|
devname[5] = 'h';
|
||||||
|
|
||||||
/* Open read/write, or read-only if that failed. */
|
devname[7] = '0' + drive;
|
||||||
disks[drive] = fopen (devname, "r+");
|
if (devname[7] > '9')
|
||||||
if (! disks[drive])
|
return -1;
|
||||||
disks[drive] = fopen (devname, "r");
|
#endif /* __linux__ */
|
||||||
|
|
||||||
return (int) disks[drive];
|
devname[6] = 'd';
|
||||||
|
devname[8] = '\0';
|
||||||
|
|
||||||
|
/* Open read/write, or read-only if that failed. */
|
||||||
|
disks[drive].flags = (int) fopen (devname, "r+");
|
||||||
|
if (! disks[drive].flags)
|
||||||
|
disks[drive].flags = (int) fopen (devname, "r");
|
||||||
|
|
||||||
|
if (disks[drive].flags)
|
||||||
|
{
|
||||||
|
#ifdef __linux__
|
||||||
|
struct hd_geometry hdg;
|
||||||
|
if (! ioctl (fileno ((FILE *) disks[drive].flags),
|
||||||
|
HDIO_GETGEO, &hdg))
|
||||||
|
{
|
||||||
|
/* Got the geometry, so save it. */
|
||||||
|
disks[drive].cylinders = hdg.cylinders;
|
||||||
|
disks[drive].heads = hdg.heads;
|
||||||
|
disks[drive].sectors = hdg.sectors;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* FIXME: should have some other alternatives before using
|
||||||
|
arbitrary defaults. */
|
||||||
|
#endif
|
||||||
|
/* Set some arbitrary defaults. */
|
||||||
|
if (drive & 0x80)
|
||||||
|
{
|
||||||
|
/* Hard drive. */
|
||||||
|
disks[drive].cylinders = DEFAULT_HD_CYLINDERS;
|
||||||
|
disks[drive].heads = DEFAULT_HD_HEADS;
|
||||||
|
disks[drive].sectors = DEFAULT_HD_SECTORS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Floppy. */
|
||||||
|
disks[drive].cylinders = DEFAULT_FD_CYLINDERS;
|
||||||
|
disks[drive].heads = DEFAULT_FD_HEADS;
|
||||||
|
disks[drive].sectors = DEFAULT_FD_SECTORS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! disks[drive].flags)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
*geometry = disks[drive];
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
biosdisk (int subfunc, int drive, int geometry,
|
biosdisk (int subfunc, int drive, struct geometry *geometry,
|
||||||
int sector, int nsec, int segment)
|
int sector, int nsec, int segment)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
/* Get the file pointer from the geometry, and make sure it matches. */
|
/* Get the file pointer from the geometry, and make sure it matches. */
|
||||||
fp = (FILE *) geometry;
|
fp = (FILE *) geometry->flags;
|
||||||
if (! fp || fp != disks[drive])
|
if (! fp || fp != (FILE *) disks[drive].flags)
|
||||||
return BIOSDISK_ERROR_GEOMETRY;
|
return BIOSDISK_ERROR_GEOMETRY;
|
||||||
|
|
||||||
/* Seek to the specified location. */
|
/* Seek to the specified location. */
|
||||||
|
|
|
@ -352,10 +352,12 @@ ENTRY(biosdisk)
|
||||||
push %ecx
|
push %ecx
|
||||||
push %edx
|
push %edx
|
||||||
push %esi
|
push %esi
|
||||||
|
push %edi
|
||||||
|
|
||||||
/* Check whether we have LBA. */
|
/* Check whether we have LBA. */
|
||||||
movb 0x13(%ebp), %al
|
movl 0x10(%ebp), %eax
|
||||||
andb $0x10, %al
|
andb 0xc(%eax), %eax
|
||||||
|
andl $BIOSDISK_FLAG_LBA_EXTENSION, %eax
|
||||||
jz disk_compute_args /* nope. */
|
jz disk_compute_args /* nope. */
|
||||||
|
|
||||||
/* set up disk address packet for extended calls (LBA mode) */
|
/* set up disk address packet for extended calls (LBA mode) */
|
||||||
|
@ -416,39 +418,37 @@ ENTRY(biosdisk)
|
||||||
/* either failed, or a floppy, so try standard BIOS calls */
|
/* either failed, or a floppy, so try standard BIOS calls */
|
||||||
disk_compute_args:
|
disk_compute_args:
|
||||||
/*
|
/*
|
||||||
* GEOMETRY is a longword representing the BIOS geometry:
|
* GEOMETRY is a structure representing the BIOS geometry:
|
||||||
* 4 bit BIOS extension (0 = none, 1 = LBA)
|
* 32 bit flags (bytes 12-15)
|
||||||
* 12 bit cylinder (bytes 2 & 3)
|
* 32 bit cylinders (bytes 8-11)
|
||||||
* 8 bit head (byte 1)
|
* 32 bit heads (bytes 4-7)
|
||||||
* 8 bit sector (byte 0)
|
* 32 bit sectors (bytes 0-3)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* set up original sector number */
|
/* set up original sector number */
|
||||||
xorl %edx, %edx
|
xorl %edx, %edx
|
||||||
movl 0x14(%ebp), %eax
|
movl 0x14(%ebp), %eax
|
||||||
|
|
||||||
|
/* get the pointer to GEOMETRY */
|
||||||
|
movl 0x10(%ebp), %edi
|
||||||
|
|
||||||
/* get sector offset, place in %ecx */
|
/* get sector offset, place in %ecx */
|
||||||
xorl %ebx, %ebx
|
movl 0x8(%edi), %ebx
|
||||||
movb 0x10(%ebp), %bl
|
|
||||||
divl %ebx
|
divl %ebx
|
||||||
movl %edx, %ecx
|
movl %edx, %ecx
|
||||||
|
|
||||||
/* get track offset (head number) in %edx,
|
/* get track offset (head number) in %edx,
|
||||||
and cylinder offset in %eax */
|
and cylinder offset in %eax */
|
||||||
xorl %edx, %edx
|
xorl %edx, %edx
|
||||||
xorl %ebx, %ebx
|
movl 0x4(%edi), %ebx
|
||||||
movb 0x11(%ebp), %bl
|
|
||||||
inc %ebx
|
|
||||||
divl %ebx
|
divl %ebx
|
||||||
|
|
||||||
/* check cylinder offset, is there a geometry problem here? */
|
/* check cylinder offset, is there a geometry problem here? */
|
||||||
movl 0x10(%ebp), %ebx
|
movl (%edi), %ebx
|
||||||
shrl $16, %ebx
|
|
||||||
andb $0xf, %bh /* mask out bios extension code */
|
|
||||||
cmpl %ebx, %eax
|
cmpl %ebx, %eax
|
||||||
|
|
||||||
/* if not, go on to standard read function */
|
/* if not, go on to standard read function */
|
||||||
jle disk_use_standard_bios
|
jl disk_use_standard_bios
|
||||||
|
|
||||||
movl $BIOSDISK_ERROR_GEOMETRY, %eax
|
movl $BIOSDISK_ERROR_GEOMETRY, %eax
|
||||||
jmp disk_exit_32
|
jmp disk_exit_32
|
||||||
|
@ -538,6 +538,7 @@ disk_exit_16:
|
||||||
movb %bl, %al /* return value in %eax */
|
movb %bl, %al /* return value in %eax */
|
||||||
|
|
||||||
disk_exit_32:
|
disk_exit_32:
|
||||||
|
pop %edi
|
||||||
pop %esi
|
pop %esi
|
||||||
pop %edx
|
pop %edx
|
||||||
pop %ecx
|
pop %ecx
|
||||||
|
@ -549,8 +550,9 @@ disk_exit_32:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* get_diskinfo(drive): return a word that represents the
|
* get_diskinfo(drive, geometry): return a structure that represents the
|
||||||
* max number of sectors and heads and cylinders for this drive
|
* max number of sectors and heads and cylinders for DRIVE in GEOMETRY.
|
||||||
|
* If an error occures, return non-zero, otherwise return zero.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -633,11 +635,12 @@ hard_drive:
|
||||||
jz 1f /* LBA not supported */
|
jz 1f /* LBA not supported */
|
||||||
|
|
||||||
/* Wahoo! Got LBA! */
|
/* Wahoo! Got LBA! */
|
||||||
movb $0x1, %bh
|
movl $BIOSDISK_FLAG_LBA_EXTENSION, %edi
|
||||||
|
/* FIXME: Should use INT 13 AH=42h */
|
||||||
data32
|
data32
|
||||||
jmp 2f
|
jmp 2f
|
||||||
|
|
||||||
1: xorb %bh, %bh /* Too bad, no LBA */
|
1: xorl %edi, %edi /* Too bad, no LBA */
|
||||||
2: movb $0x8, %ah /* ask for disk info */
|
2: movb $0x8, %ah /* ask for disk info */
|
||||||
int $0x13
|
int $0x13
|
||||||
|
|
||||||
|
@ -649,33 +652,36 @@ hard_drive:
|
||||||
|
|
||||||
probe_success:
|
probe_success:
|
||||||
/*
|
/*
|
||||||
* form a dword representing all this gunk:
|
* Store the information for CHS and BIOS extension to registers:
|
||||||
* 4 bit BIOS extension (0 = none, 1 = LBA)
|
* 32 bit BIOS extension -> edi
|
||||||
* 12 bit cylinder
|
* 32 bit cylinder -> ebx
|
||||||
* 8 bit head
|
* 32 bit head -> ecx
|
||||||
* 8 bit sector
|
* 32 bit sector -> edx
|
||||||
*/
|
*/
|
||||||
movb %bh, %ah /* restore BIOS extensions bits */
|
|
||||||
|
|
||||||
#ifdef AWARD_INT13_EXTENSIONS
|
#ifdef AWARD_INT13_EXTENSIONS
|
||||||
movb %dh, %al /* bits 10,11 of cylinder count */
|
movb %dh, %al /* bits 10,11 of cylinder count */
|
||||||
andb $0xc0, %al
|
andb $0xc0, %al
|
||||||
#endif
|
|
||||||
shlw $2, %ax /* << 2 */
|
shlw $2, %ax /* << 2 */
|
||||||
|
#endif
|
||||||
movb %cl, %al /* bits 8,9 of cylinder count */
|
movb %cl, %al /* bits 8,9 of cylinder count */
|
||||||
andb $0xc0, %al
|
andb $0xc0, %al
|
||||||
shlw $2, %ax /* << 2 */
|
shlw $2, %ax /* << 2 */
|
||||||
movb %ch, %al /* Lower 8 bits */
|
movb %ch, %al /* Lower 8 bits */
|
||||||
|
movswl %ax, %ebx /* max cylinder */
|
||||||
|
incl %ebx /* number of cylinders */
|
||||||
shll $16, %eax /* << 16 */
|
shll $16, %eax /* << 16 */
|
||||||
|
|
||||||
#ifdef AWARD_INT13_EXTENSIONS
|
#ifdef AWARD_INT13_EXTENSIONS
|
||||||
andb $0x3f, %dh /* mask off cylinder gunk */
|
andb $0x3f, %dh /* mask off cylinder gunk */
|
||||||
#endif
|
#endif
|
||||||
movb %dh, %ah /* max head */
|
movb %dh, %al /* max head */
|
||||||
andb $0x3f, %cl /* mask off cylinder gunk */
|
|
||||||
movb %cl, %al /* max sector (and # sectors) */
|
andb $0x3f, %cl /* mask off cylinder gunk */
|
||||||
|
movsbl %cl, %edx /* max sector (and # sectors) */
|
||||||
|
|
||||||
|
movsbl %al, %ecx
|
||||||
|
incl %ecx /* number of heads */
|
||||||
|
|
||||||
movl %eax, %ebx /* save return value */
|
|
||||||
data32
|
data32
|
||||||
jmp got_drive
|
jmp got_drive
|
||||||
|
|
||||||
|
@ -684,18 +690,37 @@ probe_failed:
|
||||||
* Urk. Call failed. It is not supported for floppies by old
|
* Urk. Call failed. It is not supported for floppies by old
|
||||||
* BIOSes, but it should work for all hard drives!!
|
* BIOSes, but it should work for all hard drives!!
|
||||||
*
|
*
|
||||||
* Return a 0 here... presume there is no drive present. ????
|
* Return a 1 here... presume there is no drive present. ????
|
||||||
*/
|
*/
|
||||||
|
|
||||||
movl $0, %ebx /* not present value */
|
data32
|
||||||
|
call EXT_C(real_to_prot)
|
||||||
|
.code32
|
||||||
|
|
||||||
|
movl $1, %eax
|
||||||
|
popl %esi
|
||||||
|
popl %edi
|
||||||
|
popl %edx
|
||||||
|
popl %ecx
|
||||||
|
popl %ebx
|
||||||
|
popl %ebp
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
.code16
|
||||||
got_drive:
|
got_drive:
|
||||||
data32
|
data32
|
||||||
call EXT_C(real_to_prot) /* back to protected mode */
|
call EXT_C(real_to_prot) /* back to protected mode */
|
||||||
.code32
|
.code32
|
||||||
|
|
||||||
/* set up return in correct register */
|
/* set up return structure */
|
||||||
movl %ebx, %eax
|
movl 0x0c(%ebp), %eax
|
||||||
|
movl %ebx, (%eax)
|
||||||
|
movl %ecx, 0x04(%eax)
|
||||||
|
movl %edx, 0x08(%eax)
|
||||||
|
movl %edi, 0x0c(%eax)
|
||||||
|
|
||||||
|
xorl %eax, %eax
|
||||||
|
|
||||||
popl %esi
|
popl %esi
|
||||||
popl %edi
|
popl %edi
|
||||||
|
|
|
@ -381,6 +381,7 @@ load_image (void)
|
||||||
loaded++;
|
loaded++;
|
||||||
|
|
||||||
/* load the segment */
|
/* load the segment */
|
||||||
|
memaddr = RAW_ADDR (memaddr);
|
||||||
if (memcheck (memaddr, memsiz)
|
if (memcheck (memaddr, memsiz)
|
||||||
&& grub_read ((char *) memaddr, filesiz) == filesiz)
|
&& grub_read ((char *) memaddr, filesiz) == filesiz)
|
||||||
{
|
{
|
||||||
|
@ -532,7 +533,18 @@ bsd_boot (int type, int bootdev)
|
||||||
bi.bi_n_bios_used = 0; /* this field is apparently unused */
|
bi.bi_n_bios_used = 0; /* this field is apparently unused */
|
||||||
|
|
||||||
for (i = 0; i < N_BIOS_GEOM; i++)
|
for (i = 0; i < N_BIOS_GEOM; i++)
|
||||||
bi.bi_bios_geom[i] = get_diskinfo (i + 0x80);
|
{
|
||||||
|
struct geometry geom;
|
||||||
|
|
||||||
|
/* XXX Should check the return value. */
|
||||||
|
get_diskinfo (i + 0x80, &geom);
|
||||||
|
/* FIXME: If HEADS or SECTORS is greater than 255, then this will
|
||||||
|
break the geometry information. That is a drawback of BSD
|
||||||
|
but not of GRUB. */
|
||||||
|
bi.bi_bios_geom[i] = (((geom.cylinders - 1) << 16)
|
||||||
|
+ (((geom.heads - 1) & 0xff) << 8)
|
||||||
|
+ (geom.sectors & 0xff));
|
||||||
|
}
|
||||||
|
|
||||||
bi.bi_size = sizeof (struct bootinfo);
|
bi.bi_size = sizeof (struct bootinfo);
|
||||||
bi.bi_memsizes_valid = 1;
|
bi.bi_memsizes_valid = 1;
|
||||||
|
|
|
@ -398,9 +398,10 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen)
|
||||||
lpos++;
|
lpos++;
|
||||||
}
|
}
|
||||||
while (cmdline[lpos]);
|
while (cmdline[lpos]);
|
||||||
}
|
|
||||||
|
|
||||||
cmdline[c] = 0;
|
/* Zero-terminate the string. */
|
||||||
|
cmdline[c] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -562,13 +563,16 @@ strstr (char *s1, char *s2)
|
||||||
int
|
int
|
||||||
memcheck (int start, int len)
|
memcheck (int start, int len)
|
||||||
{
|
{
|
||||||
/* FIXME: fails when used with addresses on our stack. */
|
/* FIXME: Don't bother checking memory for now, since our globals
|
||||||
|
are out of range. */
|
||||||
|
#ifndef GRUB_UTIL
|
||||||
if ((start < RAW_ADDR (0x1000)) ||
|
if ((start < RAW_ADDR (0x1000)) ||
|
||||||
(start < RAW_ADDR (0x100000) &&
|
(start < RAW_ADDR (0x100000) &&
|
||||||
RAW_ADDR (mbi.mem_lower * 1024) < (start + len)) ||
|
RAW_ADDR (mbi.mem_lower * 1024) < (start + len)) ||
|
||||||
(start >= RAW_ADDR (0x100000) &&
|
(start >= RAW_ADDR (0x100000) &&
|
||||||
RAW_ADDR (mbi.mem_upper * 1024) < ((start - 0x100000) + len)))
|
RAW_ADDR (mbi.mem_upper * 1024) < ((start - 0x100000) + len)))
|
||||||
errnum = ERR_WONT_FIT;
|
errnum = ERR_WONT_FIT;
|
||||||
|
#endif /* GRUB_UTIL */
|
||||||
|
|
||||||
return (!errnum);
|
return (!errnum);
|
||||||
}
|
}
|
||||||
|
|
|
@ -372,7 +372,8 @@ returnit:
|
||||||
set_device (dest_dev) && open_partition () &&
|
set_device (dest_dev) && open_partition () &&
|
||||||
devread (0, 0, SECTOR_SIZE, old_sect))
|
devread (0, 0, SECTOR_SIZE, old_sect))
|
||||||
{
|
{
|
||||||
int dest_drive = current_drive, dest_geom = buf_geom;
|
int dest_drive = current_drive;
|
||||||
|
struct geometry dest_geom = buf_geom;
|
||||||
int dest_sector = part_start, i;
|
int dest_sector = part_start, i;
|
||||||
|
|
||||||
#ifndef NO_DECOMPRESSION
|
#ifndef NO_DECOMPRESSION
|
||||||
|
@ -466,11 +467,11 @@ returnit:
|
||||||
|
|
||||||
if (!errnum
|
if (!errnum
|
||||||
&& (biosdisk(BIOSDISK_WRITE,
|
&& (biosdisk(BIOSDISK_WRITE,
|
||||||
dest_drive, dest_geom,
|
dest_drive, &dest_geom,
|
||||||
dest_sector, 1, (BOOTSEC_LOCATION>>4))
|
dest_sector, 1, (BOOTSEC_LOCATION>>4))
|
||||||
|| (write_stage2_sect
|
|| (write_stage2_sect
|
||||||
&& biosdisk(BIOSDISK_WRITE,
|
&& biosdisk(BIOSDISK_WRITE,
|
||||||
current_drive, buf_geom,
|
current_drive, &buf_geom,
|
||||||
stage2_sect, 1, SCRATCHSEG))))
|
stage2_sect, 1, SCRATCHSEG))))
|
||||||
errnum = ERR_WRITE;
|
errnum = ERR_WRITE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ int current_slice;
|
||||||
/* disk buffer parameters */
|
/* disk buffer parameters */
|
||||||
int buf_drive = -1;
|
int buf_drive = -1;
|
||||||
int buf_track;
|
int buf_track;
|
||||||
int buf_geom;
|
struct geometry buf_geom;
|
||||||
|
|
||||||
/* filesystem common variables */
|
/* filesystem common variables */
|
||||||
int filepos;
|
int filepos;
|
||||||
|
@ -103,26 +103,24 @@ rawread (int drive, int sector, int byte_offset, int byte_len, char *buf)
|
||||||
*/
|
*/
|
||||||
if (buf_drive != drive)
|
if (buf_drive != drive)
|
||||||
{
|
{
|
||||||
buf_geom = get_diskinfo (drive);
|
if (get_diskinfo (drive, &buf_geom))
|
||||||
|
{
|
||||||
|
errnum = ERR_NO_DISK;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
buf_drive = drive;
|
buf_drive = drive;
|
||||||
buf_track = -1;
|
buf_track = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf_geom == 0)
|
|
||||||
{
|
|
||||||
errnum = ERR_NO_DISK;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get first sector of track */
|
/* Get first sector of track */
|
||||||
soff = sector % SECTORS (buf_geom);
|
soff = sector % buf_geom.sectors;
|
||||||
track = sector - soff;
|
track = sector - soff;
|
||||||
num_sect = SECTORS (buf_geom) - soff;
|
num_sect = buf_geom.sectors - soff;
|
||||||
bufaddr = BUFFERADDR + (soff * SECTOR_SIZE) + byte_offset;
|
bufaddr = BUFFERADDR + (soff * SECTOR_SIZE) + byte_offset;
|
||||||
|
|
||||||
if (track != buf_track)
|
if (track != buf_track)
|
||||||
{
|
{
|
||||||
int bios_err, read_start = track, read_len = SECTORS (buf_geom);
|
int bios_err, read_start = track, read_len = buf_geom.sectors;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there's more than one read in this entire loop, then
|
* If there's more than one read in this entire loop, then
|
||||||
|
@ -136,7 +134,7 @@ rawread (int drive, int sector, int byte_offset, int byte_len, char *buf)
|
||||||
bufaddr = BUFFERADDR + byte_offset;
|
bufaddr = BUFFERADDR + byte_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
bios_err = biosdisk (BIOSDISK_READ, drive, buf_geom,
|
bios_err = biosdisk (BIOSDISK_READ, drive, &buf_geom,
|
||||||
read_start, read_len, BUFFERSEG);
|
read_start, read_len, BUFFERSEG);
|
||||||
if (bios_err)
|
if (bios_err)
|
||||||
{
|
{
|
||||||
|
@ -151,7 +149,7 @@ rawread (int drive, int sector, int byte_offset, int byte_len, char *buf)
|
||||||
* required sector(s) rather than failing completely.
|
* required sector(s) rather than failing completely.
|
||||||
*/
|
*/
|
||||||
if (slen > num_sect
|
if (slen > num_sect
|
||||||
|| biosdisk (BIOSDISK_READ, drive, buf_geom,
|
|| biosdisk (BIOSDISK_READ, drive, &buf_geom,
|
||||||
sector, slen, BUFFERSEG))
|
sector, slen, BUFFERSEG))
|
||||||
errnum = ERR_READ;
|
errnum = ERR_READ;
|
||||||
|
|
||||||
|
@ -293,7 +291,7 @@ make_saved_active (void)
|
||||||
|
|
||||||
buf_track = -1;
|
buf_track = -1;
|
||||||
|
|
||||||
if (biosdisk (BIOSDISK_WRITE, saved_drive, buf_geom,
|
if (biosdisk (BIOSDISK_WRITE, saved_drive, &buf_geom,
|
||||||
0, 1, SCRATCHSEG))
|
0, 1, SCRATCHSEG))
|
||||||
{
|
{
|
||||||
errnum = ERR_WRITE;
|
errnum = ERR_WRITE;
|
||||||
|
@ -406,7 +404,7 @@ real_open_partition (int flags)
|
||||||
bsd_evil_hack = 0;
|
bsd_evil_hack = 0;
|
||||||
current_slice = 0;
|
current_slice = 0;
|
||||||
part_start = 0;
|
part_start = 0;
|
||||||
part_length = SECTORS (buf_geom) * HEADS (buf_geom) * CYLINDERS (buf_geom);
|
part_length = buf_geom.sectors * buf_geom.heads * buf_geom.cylinders;
|
||||||
|
|
||||||
if (current_drive & 0x80)
|
if (current_drive & 0x80)
|
||||||
{
|
{
|
||||||
|
@ -900,6 +898,7 @@ print_completions (char *filename)
|
||||||
{
|
{
|
||||||
/* disk completions */
|
/* disk completions */
|
||||||
int disk_no, i, j;
|
int disk_no, i, j;
|
||||||
|
struct geometry geom;
|
||||||
|
|
||||||
printf (" Possible disks are: ");
|
printf (" Possible disks are: ");
|
||||||
|
|
||||||
|
@ -908,8 +907,8 @@ print_completions (char *filename)
|
||||||
for (j = 0; j < 8; j++)
|
for (j = 0; j < 8; j++)
|
||||||
{
|
{
|
||||||
disk_no = (i * 0x80) + j;
|
disk_no = (i * 0x80) + j;
|
||||||
if ((disk_choice || disk_no == current_drive)
|
if ((disk_choice || disk_no == current_drive) &&
|
||||||
&& get_diskinfo (disk_no))
|
! get_diskinfo (disk_no, &geom))
|
||||||
printf (" %cd%d", (i ? 'h' : 'f'), j);
|
printf (" %cd%d", (i ? 'h' : 'f'), j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,6 @@
|
||||||
|
|
||||||
#include "pc_slice.h"
|
#include "pc_slice.h"
|
||||||
|
|
||||||
#define SECTORS(geom) ( (geom) & 0xFF )
|
|
||||||
#define HEADS(geom) ( ( ( (geom) >> 8 ) & 0xFF ) + 1 )
|
|
||||||
#define CYLINDERS(geom) ( ( ( (geom) >> 16 ) & 0x3FF ) + 1 )
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default to all functioning filesystems enabled
|
* Default to all functioning filesystems enabled
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -58,6 +58,7 @@ extern char *grub_scratch_mem;
|
||||||
#define BIOSDISK_READ 0x0
|
#define BIOSDISK_READ 0x0
|
||||||
#define BIOSDISK_WRITE 0x1
|
#define BIOSDISK_WRITE 0x1
|
||||||
#define BIOSDISK_ERROR_GEOMETRY 0x100
|
#define BIOSDISK_ERROR_GEOMETRY 0x100
|
||||||
|
#define BIOSDISK_FLAG_LBA_EXTENSION 0x1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the filesystem (not raw device) buffer.
|
* This is the filesystem (not raw device) buffer.
|
||||||
|
@ -304,6 +305,19 @@ extern int fsys_type;
|
||||||
extern int block_file;
|
extern int block_file;
|
||||||
#endif /* NO_BLOCK_FILES */
|
#endif /* NO_BLOCK_FILES */
|
||||||
|
|
||||||
|
/* The information for a disk geometry */
|
||||||
|
struct geometry
|
||||||
|
{
|
||||||
|
/* The number of cylinders */
|
||||||
|
unsigned long cylinders;
|
||||||
|
/* The number of heads */
|
||||||
|
unsigned long heads;
|
||||||
|
/* The number of sectors */
|
||||||
|
unsigned long sectors;
|
||||||
|
/* Flags */
|
||||||
|
unsigned long flags;
|
||||||
|
};
|
||||||
|
|
||||||
extern long part_start;
|
extern long part_start;
|
||||||
extern long part_length;
|
extern long part_length;
|
||||||
|
|
||||||
|
@ -311,7 +325,7 @@ extern int current_slice;
|
||||||
|
|
||||||
extern int buf_drive;
|
extern int buf_drive;
|
||||||
extern int buf_track;
|
extern int buf_track;
|
||||||
extern int buf_geom;
|
extern struct geometry buf_geom;
|
||||||
|
|
||||||
/* these are the current file position and maximum file position */
|
/* these are the current file position and maximum file position */
|
||||||
extern int filepos;
|
extern int filepos;
|
||||||
|
@ -418,8 +432,8 @@ int checkkey (void);
|
||||||
void set_attrib (int attr);
|
void set_attrib (int attr);
|
||||||
|
|
||||||
/* Low-level disk I/O */
|
/* Low-level disk I/O */
|
||||||
int get_diskinfo (int drive);
|
int get_diskinfo (int drive, struct geometry *geometry);
|
||||||
int biosdisk (int read, int drive, int geometry,
|
int biosdisk (int read, int drive, struct geometry *geometry,
|
||||||
int sector, int nsec, int segment);
|
int sector, int nsec, int segment);
|
||||||
void stop_floppy (void);
|
void stop_floppy (void);
|
||||||
|
|
||||||
|
@ -494,6 +508,6 @@ int load_image (void);
|
||||||
int load_module (void);
|
int load_module (void);
|
||||||
int load_initrd (void);
|
int load_initrd (void);
|
||||||
|
|
||||||
void init_bios_info (void) __attribute__ ((noreturn));
|
void init_bios_info (void);
|
||||||
|
|
||||||
#endif /* ASM_FILE */
|
#endif /* ASM_FILE */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue