/sbin/grub works
This commit is contained in:
parent
db34e7d7f1
commit
3688d873d4
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>
|
||||
|
||||
* 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
|
||||
|
||||
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:
|
||||
* LBA and preliminary AWARD BIOS disk extension support.
|
||||
* Started docs/grub.texi.
|
||||
|
|
|
@ -692,7 +692,7 @@ fi
|
|||
PACKAGE=grub
|
||||
|
||||
|
||||
VERSION=0.5.91
|
||||
VERSION=0.5.92
|
||||
|
||||
|
||||
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
grub (0.5.92) unstable; urgency=low
|
||||
|
||||
*
|
||||
|
||||
--
|
||||
|
||||
grub (0.5.91) unstable; urgency=low
|
||||
|
||||
* 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 <stdio.h>
|
||||
|
||||
#ifdef __linux__
|
||||
# include <sys/ioctl.h> /* ioctl */
|
||||
# include <linux/hdreg.h> /* HDIO_GETGEO */
|
||||
#endif /* __linux__ */
|
||||
|
||||
/* Simulated memory sizes. */
|
||||
#define EXTENDED_MEMSIZE (4 * 1024 * 1024) /* 4MB */
|
||||
#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 boot_drive = 0;
|
||||
|
@ -53,7 +65,7 @@ char config_file[] = "/boot/grub/menu.lst";
|
|||
char *grub_scratch_mem = 0;
|
||||
|
||||
#define NUM_DISKS 256
|
||||
static FILE **disks = 0;
|
||||
static struct geometry *disks = 0;
|
||||
|
||||
/* The main entry point into this mess. */
|
||||
int
|
||||
|
@ -65,6 +77,31 @@ grub_stage2 (void)
|
|||
int i;
|
||||
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);
|
||||
scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15);
|
||||
assert (scratch);
|
||||
|
@ -93,32 +130,9 @@ grub_stage2 (void)
|
|||
keypad (stdscr, TRUE);
|
||||
#endif
|
||||
|
||||
/* Make sure our stack lives in the simulated memory area. */
|
||||
simstack = (char *) RAW_ADDR (PROTSTACKINIT);
|
||||
#ifdef SIMULATE_STACK
|
||||
__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
|
||||
/* Set our stack, and go for it. */
|
||||
simstack = (char *) PROTSTACKINIT;
|
||||
doit ();
|
||||
|
||||
#ifdef HAVE_LIBCURSES
|
||||
endwin ();
|
||||
|
@ -126,8 +140,8 @@ grub_stage2 (void)
|
|||
|
||||
/* Close off the file pointers we used. */
|
||||
for (i = 0; i < NUM_DISKS; i ++)
|
||||
if (disks[i])
|
||||
fclose (disks[i]);
|
||||
if (disks[i].flags)
|
||||
fclose ((FILE *) disks[i].flags);
|
||||
|
||||
/* Release memory. */
|
||||
free (disks);
|
||||
|
@ -352,47 +366,107 @@ set_attrib (int attr)
|
|||
/* Low-level disk I/O. Our stubbed version just returns a file
|
||||
descriptor, not the actual geometry. */
|
||||
int
|
||||
get_diskinfo (int drive)
|
||||
get_diskinfo (int drive, struct geometry *geometry)
|
||||
{
|
||||
/* The unpartitioned device name: /dev/XdX */
|
||||
char devname[9];
|
||||
/* FIXME: this function is truly horrid. We try opening the device,
|
||||
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. */
|
||||
if (disks[drive])
|
||||
return (int) disks[drive];
|
||||
if (! disks[drive].flags)
|
||||
{
|
||||
/* The unpartitioned device name: /dev/XdX */
|
||||
char devname[9];
|
||||
|
||||
/* Try opening the drive device. */
|
||||
strcpy (devname, "/dev/");
|
||||
if (drive & 0x80)
|
||||
devname[5] = 'h';
|
||||
else
|
||||
devname[5] = 'f';
|
||||
devname[6] = 'd';
|
||||
/* Try opening the drive device. */
|
||||
strcpy (devname, "/dev/");
|
||||
|
||||
/* Check to make sure we don't exceed /dev/hdz. */
|
||||
devname[7] = (drive & 0x7f) + 'a';
|
||||
if (devname[7] > 'z')
|
||||
return 0;
|
||||
devname[8] = '\0';
|
||||
#ifdef __linux__
|
||||
/* Linux uses /dev/hda, and /dev/sda, but /dev/fd0. Go figure. */
|
||||
if (drive & 0x80)
|
||||
{
|
||||
/* 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. */
|
||||
disks[drive] = fopen (devname, "r+");
|
||||
if (! disks[drive])
|
||||
disks[drive] = fopen (devname, "r");
|
||||
devname[7] = '0' + drive;
|
||||
if (devname[7] > '9')
|
||||
return -1;
|
||||
#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
|
||||
biosdisk (int subfunc, int drive, int geometry,
|
||||
biosdisk (int subfunc, int drive, struct geometry *geometry,
|
||||
int sector, int nsec, int segment)
|
||||
{
|
||||
char *buf;
|
||||
FILE *fp;
|
||||
|
||||
/* Get the file pointer from the geometry, and make sure it matches. */
|
||||
fp = (FILE *) geometry;
|
||||
if (! fp || fp != disks[drive])
|
||||
fp = (FILE *) geometry->flags;
|
||||
if (! fp || fp != (FILE *) disks[drive].flags)
|
||||
return BIOSDISK_ERROR_GEOMETRY;
|
||||
|
||||
/* Seek to the specified location. */
|
||||
|
|
|
@ -352,10 +352,12 @@ ENTRY(biosdisk)
|
|||
push %ecx
|
||||
push %edx
|
||||
push %esi
|
||||
push %edi
|
||||
|
||||
/* Check whether we have LBA. */
|
||||
movb 0x13(%ebp), %al
|
||||
andb $0x10, %al
|
||||
movl 0x10(%ebp), %eax
|
||||
andb 0xc(%eax), %eax
|
||||
andl $BIOSDISK_FLAG_LBA_EXTENSION, %eax
|
||||
jz disk_compute_args /* nope. */
|
||||
|
||||
/* 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 */
|
||||
disk_compute_args:
|
||||
/*
|
||||
* GEOMETRY is a longword representing the BIOS geometry:
|
||||
* 4 bit BIOS extension (0 = none, 1 = LBA)
|
||||
* 12 bit cylinder (bytes 2 & 3)
|
||||
* 8 bit head (byte 1)
|
||||
* 8 bit sector (byte 0)
|
||||
* GEOMETRY is a structure representing the BIOS geometry:
|
||||
* 32 bit flags (bytes 12-15)
|
||||
* 32 bit cylinders (bytes 8-11)
|
||||
* 32 bit heads (bytes 4-7)
|
||||
* 32 bit sectors (bytes 0-3)
|
||||
*/
|
||||
|
||||
/* set up original sector number */
|
||||
xorl %edx, %edx
|
||||
movl 0x14(%ebp), %eax
|
||||
|
||||
/* get the pointer to GEOMETRY */
|
||||
movl 0x10(%ebp), %edi
|
||||
|
||||
/* get sector offset, place in %ecx */
|
||||
xorl %ebx, %ebx
|
||||
movb 0x10(%ebp), %bl
|
||||
movl 0x8(%edi), %ebx
|
||||
divl %ebx
|
||||
movl %edx, %ecx
|
||||
|
||||
/* get track offset (head number) in %edx,
|
||||
and cylinder offset in %eax */
|
||||
xorl %edx, %edx
|
||||
xorl %ebx, %ebx
|
||||
movb 0x11(%ebp), %bl
|
||||
inc %ebx
|
||||
movl 0x4(%edi), %ebx
|
||||
divl %ebx
|
||||
|
||||
/* check cylinder offset, is there a geometry problem here? */
|
||||
movl 0x10(%ebp), %ebx
|
||||
shrl $16, %ebx
|
||||
andb $0xf, %bh /* mask out bios extension code */
|
||||
movl (%edi), %ebx
|
||||
cmpl %ebx, %eax
|
||||
|
||||
/* if not, go on to standard read function */
|
||||
jle disk_use_standard_bios
|
||||
jl disk_use_standard_bios
|
||||
|
||||
movl $BIOSDISK_ERROR_GEOMETRY, %eax
|
||||
jmp disk_exit_32
|
||||
|
@ -538,6 +538,7 @@ disk_exit_16:
|
|||
movb %bl, %al /* return value in %eax */
|
||||
|
||||
disk_exit_32:
|
||||
pop %edi
|
||||
pop %esi
|
||||
pop %edx
|
||||
pop %ecx
|
||||
|
@ -549,8 +550,9 @@ disk_exit_32:
|
|||
|
||||
/*
|
||||
*
|
||||
* get_diskinfo(drive): return a word that represents the
|
||||
* max number of sectors and heads and cylinders for this drive
|
||||
* get_diskinfo(drive, geometry): return a structure that represents the
|
||||
* 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 */
|
||||
|
||||
/* Wahoo! Got LBA! */
|
||||
movb $0x1, %bh
|
||||
movl $BIOSDISK_FLAG_LBA_EXTENSION, %edi
|
||||
/* FIXME: Should use INT 13 AH=42h */
|
||||
data32
|
||||
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 */
|
||||
int $0x13
|
||||
|
||||
|
@ -649,33 +652,36 @@ hard_drive:
|
|||
|
||||
probe_success:
|
||||
/*
|
||||
* form a dword representing all this gunk:
|
||||
* 4 bit BIOS extension (0 = none, 1 = LBA)
|
||||
* 12 bit cylinder
|
||||
* 8 bit head
|
||||
* 8 bit sector
|
||||
* Store the information for CHS and BIOS extension to registers:
|
||||
* 32 bit BIOS extension -> edi
|
||||
* 32 bit cylinder -> ebx
|
||||
* 32 bit head -> ecx
|
||||
* 32 bit sector -> edx
|
||||
*/
|
||||
movb %bh, %ah /* restore BIOS extensions bits */
|
||||
|
||||
#ifdef AWARD_INT13_EXTENSIONS
|
||||
movb %dh, %al /* bits 10,11 of cylinder count */
|
||||
andb $0xc0, %al
|
||||
#endif
|
||||
shlw $2, %ax /* << 2 */
|
||||
#endif
|
||||
movb %cl, %al /* bits 8,9 of cylinder count */
|
||||
andb $0xc0, %al
|
||||
shlw $2, %ax /* << 2 */
|
||||
movb %ch, %al /* Lower 8 bits */
|
||||
movswl %ax, %ebx /* max cylinder */
|
||||
incl %ebx /* number of cylinders */
|
||||
shll $16, %eax /* << 16 */
|
||||
|
||||
#ifdef AWARD_INT13_EXTENSIONS
|
||||
andb $0x3f, %dh /* mask off cylinder gunk */
|
||||
#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) */
|
||||
movsbl %cl, %edx /* max sector (and # sectors) */
|
||||
|
||||
movsbl %al, %ecx
|
||||
incl %ecx /* number of heads */
|
||||
|
||||
movl %eax, %ebx /* save return value */
|
||||
data32
|
||||
jmp got_drive
|
||||
|
||||
|
@ -684,18 +690,37 @@ probe_failed:
|
|||
* Urk. Call failed. It is not supported for floppies by old
|
||||
* 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:
|
||||
data32
|
||||
call EXT_C(real_to_prot) /* back to protected mode */
|
||||
.code32
|
||||
|
||||
/* set up return in correct register */
|
||||
movl %ebx, %eax
|
||||
/* set up return structure */
|
||||
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 %edi
|
||||
|
|
|
@ -381,6 +381,7 @@ load_image (void)
|
|||
loaded++;
|
||||
|
||||
/* load the segment */
|
||||
memaddr = RAW_ADDR (memaddr);
|
||||
if (memcheck (memaddr, memsiz)
|
||||
&& 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 */
|
||||
|
||||
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_memsizes_valid = 1;
|
||||
|
|
|
@ -398,9 +398,10 @@ get_cmdline (char *prompt, char *commands, char *cmdline, int maxlen)
|
|||
lpos++;
|
||||
}
|
||||
while (cmdline[lpos]);
|
||||
}
|
||||
|
||||
cmdline[c] = 0;
|
||||
/* Zero-terminate the string. */
|
||||
cmdline[c] = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -562,13 +563,16 @@ strstr (char *s1, char *s2)
|
|||
int
|
||||
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)) ||
|
||||
(start < RAW_ADDR (0x100000) &&
|
||||
RAW_ADDR (mbi.mem_lower * 1024) < (start + len)) ||
|
||||
(start >= RAW_ADDR (0x100000) &&
|
||||
RAW_ADDR (mbi.mem_upper * 1024) < ((start - 0x100000) + len)))
|
||||
errnum = ERR_WONT_FIT;
|
||||
#endif /* GRUB_UTIL */
|
||||
|
||||
return (!errnum);
|
||||
}
|
||||
|
|
|
@ -372,7 +372,8 @@ returnit:
|
|||
set_device (dest_dev) && open_partition () &&
|
||||
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;
|
||||
|
||||
#ifndef NO_DECOMPRESSION
|
||||
|
@ -466,11 +467,11 @@ returnit:
|
|||
|
||||
if (!errnum
|
||||
&& (biosdisk(BIOSDISK_WRITE,
|
||||
dest_drive, dest_geom,
|
||||
dest_drive, &dest_geom,
|
||||
dest_sector, 1, (BOOTSEC_LOCATION>>4))
|
||||
|| (write_stage2_sect
|
||||
&& biosdisk(BIOSDISK_WRITE,
|
||||
current_drive, buf_geom,
|
||||
current_drive, &buf_geom,
|
||||
stage2_sect, 1, SCRATCHSEG))))
|
||||
errnum = ERR_WRITE;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ int current_slice;
|
|||
/* disk buffer parameters */
|
||||
int buf_drive = -1;
|
||||
int buf_track;
|
||||
int buf_geom;
|
||||
struct geometry buf_geom;
|
||||
|
||||
/* filesystem common variables */
|
||||
int filepos;
|
||||
|
@ -103,26 +103,24 @@ rawread (int drive, int sector, int byte_offset, int byte_len, char *buf)
|
|||
*/
|
||||
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_track = -1;
|
||||
}
|
||||
|
||||
if (buf_geom == 0)
|
||||
{
|
||||
errnum = ERR_NO_DISK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get first sector of track */
|
||||
soff = sector % SECTORS (buf_geom);
|
||||
soff = sector % buf_geom.sectors;
|
||||
track = sector - soff;
|
||||
num_sect = SECTORS (buf_geom) - soff;
|
||||
num_sect = buf_geom.sectors - soff;
|
||||
bufaddr = BUFFERADDR + (soff * SECTOR_SIZE) + byte_offset;
|
||||
|
||||
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
|
||||
|
@ -136,7 +134,7 @@ rawread (int drive, int sector, int byte_offset, int byte_len, char *buf)
|
|||
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);
|
||||
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.
|
||||
*/
|
||||
if (slen > num_sect
|
||||
|| biosdisk (BIOSDISK_READ, drive, buf_geom,
|
||||
|| biosdisk (BIOSDISK_READ, drive, &buf_geom,
|
||||
sector, slen, BUFFERSEG))
|
||||
errnum = ERR_READ;
|
||||
|
||||
|
@ -293,7 +291,7 @@ make_saved_active (void)
|
|||
|
||||
buf_track = -1;
|
||||
|
||||
if (biosdisk (BIOSDISK_WRITE, saved_drive, buf_geom,
|
||||
if (biosdisk (BIOSDISK_WRITE, saved_drive, &buf_geom,
|
||||
0, 1, SCRATCHSEG))
|
||||
{
|
||||
errnum = ERR_WRITE;
|
||||
|
@ -406,7 +404,7 @@ real_open_partition (int flags)
|
|||
bsd_evil_hack = 0;
|
||||
current_slice = 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)
|
||||
{
|
||||
|
@ -900,6 +898,7 @@ print_completions (char *filename)
|
|||
{
|
||||
/* disk completions */
|
||||
int disk_no, i, j;
|
||||
struct geometry geom;
|
||||
|
||||
printf (" Possible disks are: ");
|
||||
|
||||
|
@ -908,8 +907,8 @@ print_completions (char *filename)
|
|||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
disk_no = (i * 0x80) + j;
|
||||
if ((disk_choice || disk_no == current_drive)
|
||||
&& get_diskinfo (disk_no))
|
||||
if ((disk_choice || disk_no == current_drive) &&
|
||||
! get_diskinfo (disk_no, &geom))
|
||||
printf (" %cd%d", (i ? 'h' : 'f'), j);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,10 +21,6 @@
|
|||
|
||||
#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
|
||||
*/
|
||||
|
|
|
@ -58,6 +58,7 @@ extern char *grub_scratch_mem;
|
|||
#define BIOSDISK_READ 0x0
|
||||
#define BIOSDISK_WRITE 0x1
|
||||
#define BIOSDISK_ERROR_GEOMETRY 0x100
|
||||
#define BIOSDISK_FLAG_LBA_EXTENSION 0x1
|
||||
|
||||
/*
|
||||
* This is the filesystem (not raw device) buffer.
|
||||
|
@ -304,6 +305,19 @@ extern int fsys_type;
|
|||
extern int block_file;
|
||||
#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_length;
|
||||
|
||||
|
@ -311,7 +325,7 @@ extern int current_slice;
|
|||
|
||||
extern int buf_drive;
|
||||
extern int buf_track;
|
||||
extern int buf_geom;
|
||||
extern struct geometry buf_geom;
|
||||
|
||||
/* these are the current file position and maximum file position */
|
||||
extern int filepos;
|
||||
|
@ -418,8 +432,8 @@ int checkkey (void);
|
|||
void set_attrib (int attr);
|
||||
|
||||
/* Low-level disk I/O */
|
||||
int get_diskinfo (int drive);
|
||||
int biosdisk (int read, int drive, int geometry,
|
||||
int get_diskinfo (int drive, struct geometry *geometry);
|
||||
int biosdisk (int read, int drive, struct geometry *geometry,
|
||||
int sector, int nsec, int segment);
|
||||
void stop_floppy (void);
|
||||
|
||||
|
@ -494,6 +508,6 @@ int load_image (void);
|
|||
int load_module (void);
|
||||
int load_initrd (void);
|
||||
|
||||
void init_bios_info (void) __attribute__ ((noreturn));
|
||||
void init_bios_info (void);
|
||||
|
||||
#endif /* ASM_FILE */
|
||||
|
|
Loading…
Reference in New Issue