pkgsrc/sysutils/grub/patches/patch-ac
jmmv 4d1ccdc020 Workaround a bug that prevents GRUB to load ELF kernels that explicitly
specify load addresses in their Multiboot header.  (E.g., NetBSD.)

This has already been sent to GRUB's bug tracking system:

	http://savannah.gnu.org/bugs/?func=detailitem&item_id=15590

Bump PKGREVISION to 4.
2006-02-03 09:59:32 +00:00

186 lines
4.5 KiB
Text

$NetBSD: patch-ac,v 1.4 2006/02/03 09:59:32 jmmv Exp $
--- stage2/boot.c.orig 2004-03-30 13:44:08.000000000 +0200
+++ stage2/boot.c
@@ -22,6 +22,7 @@
#include "shared.h"
#include "freebsd.h"
+#include "netbsd_reboot.h"
#include "imgact_aout.h"
#include "i386-elf.h"
@@ -104,7 +105,21 @@ load_image (char *kernel, char *arg, ker
&& BOOTABLE_I386_ELF ((*((Elf32_Ehdr *) buffer))))
{
if (type == KERNEL_TYPE_MULTIBOOT)
- entry_addr = (entry_func) pu.elf->e_entry;
+ {
+ if (flags & MULTIBOOT_AOUT_KLUDGE)
+ {
+ struct multiboot_header *mbh;
+
+ mbh = (struct multiboot_header *) (buffer + i);
+
+ entry_addr = (entry_func) mbh->entry_addr;
+ text_len = mbh->load_end_addr - mbh->load_addr;
+ data_len = 0;
+ bss_len = mbh->bss_end_addr - mbh->load_end_addr;
+ }
+ else
+ entry_addr = (entry_func) pu.elf->e_entry;
+ }
else
entry_addr = (entry_func) (pu.elf->e_entry & 0xFFFFFF);
@@ -610,9 +625,19 @@ load_image (char *kernel, char *arg, ker
if (type == KERNEL_TYPE_FREEBSD || type == KERNEL_TYPE_NETBSD)
memaddr = RAW_ADDR (phdr->p_paddr & 0xFFFFFF);
else
- memaddr = RAW_ADDR (phdr->p_paddr);
+ {
+ memaddr = RAW_ADDR (phdr->p_paddr);
+ if (flags & MULTIBOOT_AOUT_KLUDGE &&
+ memaddr >= mbi.mem_upper * 1024)
+ {
+ memaddr &= RAW_ADDR (0xFFFFFF);
+ }
+ }
memsiz = phdr->p_memsz;
+ if (flags & MULTIBOOT_AOUT_KLUDGE)
+ memsiz += bss_len;
+
if (memaddr < RAW_ADDR (0x100000))
errnum = ERR_BELOW_1MB;
@@ -872,6 +897,91 @@ bsd_boot_entry (int flags, int bootdev,
* variables.
*/
+int
+netbsd_value(char arg)
+{
+ switch (arg) {
+ case 'a':
+ return(NB_RB_ASKNAME);
+ break;
+ case 'b':
+ return(NB_RB_HALT);
+ break;
+ case 'c':
+ return(NB_RB_USERCONF);
+ break;
+ case 'd':
+ return(NB_RB_KDB);
+ break;
+ case 'm':
+ return(NB_RB_MINIROOT);
+ break;
+ case 'q':
+ return(NB_AB_QUIET);
+ break;
+ case 's':
+ return(NB_RB_SINGLE);
+ break;
+ case 'v':
+ return(NB_AB_VERBOSE);
+ break;
+ case 'x':
+ return(NB_AB_DEBUG);
+ break;
+ case 'z':
+ return(NB_AB_SILENT);
+ break;
+ default:
+ break;
+ }
+ return(0);
+}
+
+int
+freebsd_value(char arg)
+{
+ switch (arg) {
+ case 'C':
+ return(RB_CDROM);
+ break;
+ case 'a':
+ return(RB_ASKNAME);
+ break;
+ case 'b':
+ return(RB_HALT);
+ break;
+ case 'c':
+ return(RB_CONFIG);
+ break;
+ case 'd':
+ return(RB_KDB);
+ break;
+ case 'D':
+ return(RB_MULTIPLE);
+ break;
+ case 'g':
+ return(RB_GDB);
+ break;
+ case 'h':
+ return(RB_SERIAL);
+ break;
+ case 'm':
+ return(RB_MUTE);
+ break;
+ case 'r':
+ return(RB_DFLTROOT);
+ break;
+ case 's':
+ return(RB_SINGLE);
+ break;
+ case 'v':
+ return(RB_VERBOSE);
+ break;
+ default:
+ break;
+ }
+ return(0);
+}
void
bsd_boot (kernel_t type, int bootdev, char *arg)
@@ -894,31 +1004,12 @@ bsd_boot (kernel_t type, int bootdev, ch
{
while (*str && *str != ' ')
{
- if (*str == 'C')
- clval |= RB_CDROM;
- if (*str == 'a')
- clval |= RB_ASKNAME;
- if (*str == 'b')
- clval |= RB_HALT;
- if (*str == 'c')
- clval |= RB_CONFIG;
- if (*str == 'd')
- clval |= RB_KDB;
- if (*str == 'D')
- clval |= RB_MULTIPLE;
- if (*str == 'g')
- clval |= RB_GDB;
- if (*str == 'h')
- clval |= RB_SERIAL;
- if (*str == 'm')
- clval |= RB_MUTE;
- if (*str == 'r')
- clval |= RB_DFLTROOT;
- if (*str == 's')
- clval |= RB_SINGLE;
- if (*str == 'v')
- clval |= RB_VERBOSE;
- str++;
+ if (type == KERNEL_TYPE_NETBSD) {
+ clval |= netbsd_value(*str);
+ } else {
+ clval |= freebsd_value(*str);
+ }
+ str++;
}
continue;
}