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> 2000-04-03 OKUJI Yoshinori <okuji@gnu.org>
Add a dirty hack into the kernel loader so that the user can 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/hdreg.h> /* HDIO_GETGEO */
# include <linux/major.h> /* FLOPPY_MAJOR */ # include <linux/major.h> /* FLOPPY_MAJOR */
# include <linux/kdev_t.h> /* MAJOR */ # include <linux/kdev_t.h> /* MAJOR */
# include <linux/cdrom.h> /* CDROM_GET_CAPABILITY */
# if (__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)) # if (__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))
/* Maybe libc doesn't have large file support. */ /* Maybe libc doesn't have large file support. */
# include <linux/unistd.h> /* _llseek */ # include <linux/unistd.h> /* _llseek */
@ -58,6 +59,7 @@ int grub_stage2 (void);
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
# include <sys/ioctl.h> /* ioctl */ # include <sys/ioctl.h> /* ioctl */
# include <sys/disklabel.h> # include <sys/disklabel.h>
# include <sys/cdio.h> /* CDIOCCLRDEBUG */
#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ */ #endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ */
#ifdef HAVE_OPENDISK #ifdef HAVE_OPENDISK
@ -521,7 +523,13 @@ check_device (const char *device)
return 0; return 0;
} }
/* Make sure CD-ROMs don't get assigned a BIOS disk number
before SCSI disks! */
#ifdef __linux__ #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. */ /* Check if DEVICE is a CD-ROM drive by the HDIO_GETGEO ioctl. */
{ {
struct hd_geometry hdg; struct hd_geometry hdg;
@ -537,7 +545,15 @@ check_device (const char *device)
&& ioctl (fileno (fp), HDIO_GETGEO, &hdg)) && ioctl (fileno (fp), HDIO_GETGEO, &hdg))
return 0; return 0;
} }
# endif /* ! CDROM_GET_CAPABILITY */
#endif /* __linux__ */ #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. */ /* Attempt to read the first sector. */
if (fread (buf, 1, 512, fp) != 512) 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 */ /* copy command-line plus memory hack to staging area */
{ {
char *src = arg; char *src = arg;
char *dest = (char *) (CL_MY_LOCATION + 4); char *dest = (char *) CL_MY_LOCATION;
memmove ((char *) CL_MY_LOCATION, "mem=", 4);
*((unsigned short *) CL_OFFSET) = CL_MY_LOCATION - CL_BASE_ADDR; *((unsigned short *) CL_OFFSET) = CL_MY_LOCATION - CL_BASE_ADDR;
*((unsigned short *) CL_MAGIC_ADDR) = CL_MAGIC; *((unsigned short *) CL_MAGIC_ADDR) = CL_MAGIC;
dest = convert_to_ascii (dest, 'u', (mbi.mem_upper + 0x400)); /* Help Linux to find memory only if more than 64MB are present.
*(dest++) = 'K'; Up to that amount it is fairly capable to find by itself,
*(dest++) = ' '; 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 != ' ') while (*src && *src != ' ')
src++; src++;
@ -572,7 +580,10 @@ load_initrd (char *initrd)
return 0; 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); memmove ((void *) RAW_ADDR (moveto), (void *) cur_addr, len);
printf (" [Linux-initrd @ 0x%x, 0x%x bytes]\n", moveto, 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 /* If the option `--type=TYPE' is specified, convert the string to
a kernel type. */ a kernel type. */
if (grub_memcmp (arg, "--type=") == 0) if (grub_memcmp (arg, "--type=", 7) == 0)
{ {
arg += 7; arg += 7;
if (grub_memcmp (arg, "netbsd") == 0) if (grub_memcmp (arg, "netbsd", 6) == 0)
suggested_type = KERNEL_TYPE_NETBSD; 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; 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 /* XXX: For now, OpenBSD is identical to NetBSD, from GRUB's
point of view. */ point of view. */
suggested_type = KERNEL_TYPE_NETBSD; 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; 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; 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; suggested_type = KERNEL_TYPE_MULTIBOOT;
else else
{ {