fix a bogus bug in kernel_func, load initrd below 1GB, append mem= option only if >64MB, add some CDROM detection code, don't use the last page for initrd to avoid a Linux's bug.

This commit is contained in:
okuji 2000-04-05 02:29:50 +00:00
parent ba86939fcb
commit 4d452e493f
4 changed files with 64 additions and 14 deletions

View file

@ -1,3 +1,26 @@
2000-04-05 OKUJI Yoshinori <okuji@gnu.org>
* stage2/builtins.c (kernel_func): Added missing ``size''
arguments into `grub_memcmp's. Reported by Christoph Plattner
<christoph.plattner@dot.at>.
From Torsten Duwe <duwe@caldera.de>:
* stage2/boot.c (load_initrd): Mask the address with 0x3FFFFFFF
instead of 0xFFFFFFFF to place the initrd below 1GB.
(load_image): In Linux boot, add the option "mem=" only if more
than 64MB are present.
* grub/asmstub.c [__linux__]: Include <linux/cdrom.h> for
CDROM_GET_CAPABILITY.
[__FreeBSD__ || __NetBSD__ || __OpenBSD__]: Include <sys/cdio.h>
for CDIOCCLRDEBUG.
(check_device) [__linux__] [CDROM_GET_CAPABILITY]: If ioctl for
CDROM_GET_CAPAIBILITY succeeds, return zero.
[__FreeBSD__ || __NetBSD__ || __OpenBSD__] [CDIOCCLRDEBUG]: If
ioctl for CDIOCCLRDEBUG succeeds, return zero.
* stage2/boot.c (load_initrd): Subtract 0x1000 (one page size)
from MOVETO, to avoid a Linux 2.3.xx's bug.
2000-04-03 OKUJI Yoshinori <okuji@gnu.org>
Add a dirty hack into the kernel loader so that the user can

View file

@ -45,6 +45,7 @@ int grub_stage2 (void);
# include <linux/hdreg.h> /* HDIO_GETGEO */
# include <linux/major.h> /* FLOPPY_MAJOR */
# include <linux/kdev_t.h> /* MAJOR */
# include <linux/cdrom.h> /* CDROM_GET_CAPABILITY */
# if (__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))
/* Maybe libc doesn't have large file support. */
# include <linux/unistd.h> /* _llseek */
@ -58,6 +59,7 @@ int grub_stage2 (void);
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
# include <sys/ioctl.h> /* ioctl */
# include <sys/disklabel.h>
# include <sys/cdio.h> /* CDIOCCLRDEBUG */
#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ */
#ifdef HAVE_OPENDISK
@ -521,7 +523,13 @@ check_device (const char *device)
return 0;
}
/* Make sure CD-ROMs don't get assigned a BIOS disk number
before SCSI disks! */
#ifdef __linux__
# ifdef CDROM_GET_CAPABILITY
if (ioctl (fileno (fp), CDROM_GET_CAPABILITY, 0) >= 0)
return 0;
# else /* ! CDROM_GET_CAPABILITY */
/* Check if DEVICE is a CD-ROM drive by the HDIO_GETGEO ioctl. */
{
struct hd_geometry hdg;
@ -537,7 +545,15 @@ check_device (const char *device)
&& ioctl (fileno (fp), HDIO_GETGEO, &hdg))
return 0;
}
# endif /* ! CDROM_GET_CAPABILITY */
#endif /* __linux__ */
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
# ifdef CDIOCCLRDEBUG
if (ioctl (fileno (fp), CDIOCCLRDEBUG, 0) >= 0)
return 0;
# endif /* CDIOCCLRDEBUG */
#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ */
/* Attempt to read the first sector. */
if (fread (buf, 1, 512, fp) != 512)

View file

@ -271,16 +271,24 @@ load_image (char *kernel, char *arg, kernel_t suggested_type)
/* copy command-line plus memory hack to staging area */
{
char *src = arg;
char *dest = (char *) (CL_MY_LOCATION + 4);
memmove ((char *) CL_MY_LOCATION, "mem=", 4);
char *dest = (char *) CL_MY_LOCATION;
*((unsigned short *) CL_OFFSET) = CL_MY_LOCATION - CL_BASE_ADDR;
*((unsigned short *) CL_MAGIC_ADDR) = CL_MAGIC;
dest = convert_to_ascii (dest, 'u', (mbi.mem_upper + 0x400));
*(dest++) = 'K';
*(dest++) = ' ';
/* Help Linux to find memory only if more than 64MB are present.
Up to that amount it is fairly capable to find by itself,
and at least newer Phoenix BIOSes are known to put a
10k hole just before 64MB, but report a proper total. */
if (mbi.mem_upper + 0x400 > 0x10000)
{
grub_memmove ((char *) CL_MY_LOCATION, "mem=", 4);
dest = (char *) (CL_MY_LOCATION + 4);
dest = convert_to_ascii (dest, 'u', (mbi.mem_upper + 0x400));
*(dest++) = 'K';
*(dest++) = ' ';
}
while (*src && *src != ' ')
src++;
@ -572,7 +580,10 @@ load_initrd (char *initrd)
return 0;
}
moveto = ((mbi.mem_upper + 0x400) * 0x400 - len) & 0xfffff000;
moveto = ((mbi.mem_upper + 0x400) * 0x400 - len) & 0x3ffff000;
/* XXX: Linux 2.3.xx has a bug in the memory range check, so avoid
the last page. */
moveto -= 0x1000;
memmove ((void *) RAW_ADDR (moveto), (void *) cur_addr, len);
printf (" [Linux-initrd @ 0x%x, 0x%x bytes]\n", moveto, len);

View file

@ -1832,23 +1832,23 @@ kernel_func (char *arg, int flags)
/* If the option `--type=TYPE' is specified, convert the string to
a kernel type. */
if (grub_memcmp (arg, "--type=") == 0)
if (grub_memcmp (arg, "--type=", 7) == 0)
{
arg += 7;
if (grub_memcmp (arg, "netbsd") == 0)
if (grub_memcmp (arg, "netbsd", 6) == 0)
suggested_type = KERNEL_TYPE_NETBSD;
else if (grub_memcmp (arg, "freebsd") == 0)
else if (grub_memcmp (arg, "freebsd", 7) == 0)
suggested_type = KERNEL_TYPE_FREEBSD;
else if (grub_memcmp (arg, "openbsd") == 0)
else if (grub_memcmp (arg, "openbsd", 7) == 0)
/* XXX: For now, OpenBSD is identical to NetBSD, from GRUB's
point of view. */
suggested_type = KERNEL_TYPE_NETBSD;
else if (grub_memcmp (arg, "linux") == 0)
else if (grub_memcmp (arg, "linux", 5) == 0)
suggested_type = KERNEL_TYPE_LINUX;
else if (grub_memcmp (arg, "biglinux") == 0)
else if (grub_memcmp (arg, "biglinux", 8) == 0)
suggested_type = KERNEL_TYPE_BIG_LINUX;
else if (grub_memcmp (arg, "multiboot") == 0)
else if (grub_memcmp (arg, "multiboot", 9) == 0)
suggested_type = KERNEL_TYPE_MULTIBOOT;
else
{