diff --git a/ChangeLog b/ChangeLog index c62675dae..b5a0dc15d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2000-04-05 OKUJI Yoshinori + + * stage2/builtins.c (kernel_func): Added missing ``size'' + arguments into `grub_memcmp's. Reported by Christoph Plattner + . + + From Torsten Duwe : + * 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 for + CDROM_GET_CAPABILITY. + [__FreeBSD__ || __NetBSD__ || __OpenBSD__]: Include + 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 Add a dirty hack into the kernel loader so that the user can diff --git a/grub/asmstub.c b/grub/asmstub.c index e5b8fda99..eae7c4d97 100644 --- a/grub/asmstub.c +++ b/grub/asmstub.c @@ -45,6 +45,7 @@ int grub_stage2 (void); # include /* HDIO_GETGEO */ # include /* FLOPPY_MAJOR */ # include /* MAJOR */ +# include /* CDROM_GET_CAPABILITY */ # if (__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)) /* Maybe libc doesn't have large file support. */ # include /* _llseek */ @@ -58,6 +59,7 @@ int grub_stage2 (void); #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) # include /* ioctl */ # include +# include /* 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) diff --git a/stage2/boot.c b/stage2/boot.c index 6b5dba1ae..47743bca7 100644 --- a/stage2/boot.c +++ b/stage2/boot.c @@ -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); diff --git a/stage2/builtins.c b/stage2/builtins.c index 0bd3b758e..52baabcbf 100644 --- a/stage2/builtins.c +++ b/stage2/builtins.c @@ -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 {