summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-04-26 19:52:39 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-04-26 19:54:54 -0700
commit619579f87baddecc8601281215f878b57faa0f67 (patch)
tree271d1aa46a67d36891c1abb6b0f2184c44f0f321
parente57c9da3f1b4d8426f68b8fb0c1b6ebcf0b43bda (diff)
downloadsyslinux-3.80-pre1.tar.gz
mboot: reimplement the Solaris DHCP hack, add compliant a.out modesyslinux-3.80-pre1
Reimplement the Solaris DHCP information passing hack. Add a spec-compliant mode for the "a.out kludge". The spec is pretty clear that the bit should override the ELF header (after all, otherwise there wouldn't be any need for the bit), but Grub disagrees. We default to Grub-compliant mode, as Solaris seems to set the bit even though it's an ELF kernel, but add the option to enable spec-compliant mode, as apparently some versions of FreeBSD need it. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--com32/mboot/Makefile2
-rw-r--r--com32/mboot/map.c2
-rw-r--r--com32/mboot/mboot.c27
-rw-r--r--com32/mboot/mboot.h7
-rw-r--r--com32/mboot/solaris.c51
5 files changed, 83 insertions, 6 deletions
diff --git a/com32/mboot/Makefile b/com32/mboot/Makefile
index 64c1d078..a6902716 100644
--- a/com32/mboot/Makefile
+++ b/com32/mboot/Makefile
@@ -24,7 +24,7 @@ LNXLIBS = ../libutil/libutil_lnx.a
MODULES = mboot.c32
TESTFILES =
-OBJS = mboot.o map.o mem.o apm.o
+OBJS = mboot.o map.o mem.o apm.o solaris.o
all: $(MODULES) $(TESTFILES)
diff --git a/com32/mboot/map.c b/com32/mboot/map.c
index b134a558..bdfcfcf0 100644
--- a/com32/mboot/map.c
+++ b/com32/mboot/map.c
@@ -157,7 +157,7 @@ int map_image(void *ptr, size_t len)
* This is insane, since it makes the AOUT_KLUDGE bit functionally
* useless, but at least Solaris apparently depends on this behavior.
*/
- if (eh) {
+ if (eh && !(opt.aout && mbh_len && (mbh->flags & MULTIBOOT_AOUT_KLUDGE))) {
regs.eip = eh->e_entry;
ph = (Elf32_Phdr *)(cptr+eh->e_phoff);
diff --git a/com32/mboot/mboot.c b/com32/mboot/mboot.c
index 3b42093f..41a5ef17 100644
--- a/com32/mboot/mboot.c
+++ b/com32/mboot/mboot.c
@@ -36,6 +36,7 @@
struct multiboot_info mbinfo;
struct syslinux_pm_regs regs;
+struct my_options opt;
struct module_data {
void *data;
@@ -152,15 +153,31 @@ int main(int argc, char *argv[])
openconsole(&dev_null_r, &dev_stdcon_w);
- if (argc < 2) {
- error("Usage: mboot.c32 mboot_file args... [--- module args...]...\n");
+ argv++;
+
+ while (*argv) {
+ if (!strcmp(*argv, "-solaris"))
+ opt.solaris = true;
+ else if (!strcmp(*argv, "-aout"))
+ opt.aout = true;
+ else
+ break;
+ argv++;
+ }
+
+ if (!*argv) {
+ error("Usage: mboot.c32 [opts] mboot_file args... [--- module args...]...\n"
+ "Options:\n"
+ " -solaris Enable Solaris DHCP information passing\n"
+ " -aout Use the \"a.out kludge\" if enabled, even for ELF\n"
+ " This matches the Multiboot spec, but differs from Grub\n");
return 1;
}
/* Load the files */
- nmodules = get_modules(argv+1, &modules);
+ nmodules = get_modules(argv, &modules);
if (nmodules < 1) {
- error("No modules found!\n");
+ error("No files found!\n");
return 1; /* Failure */
}
@@ -195,6 +212,8 @@ int main(int argc, char *argv[])
/* Add auxilliary information */
mboot_make_memmap();
mboot_apm();
+ if (opt.solaris)
+ mboot_solaris_dhcp_hack();
/* Run it */
mboot_run(keeppxe ? 3 : 0);
diff --git a/com32/mboot/mboot.h b/com32/mboot/mboot.h
index 0f33a511..c05d69f1 100644
--- a/com32/mboot/mboot.h
+++ b/com32/mboot/mboot.h
@@ -69,6 +69,10 @@ static inline void error(const char *msg)
/* mboot.c */
extern struct multiboot_info mbinfo;
extern struct syslinux_pm_regs regs;
+extern struct my_options {
+ bool solaris;
+ bool aout;
+} opt;
/* map.c */
#define MAP_HIGH 1
@@ -84,4 +88,7 @@ void mboot_make_memmap(void);
/* apm.c */
void mboot_apm(void);
+/* solaris.c */
+void mboot_solaris_dhcp_hack(void);
+
#endif /* MBOOT_H */
diff --git a/com32/mboot/solaris.c b/com32/mboot/solaris.c
new file mode 100644
index 00000000..338e9eb8
--- /dev/null
+++ b/com32/mboot/solaris.c
@@ -0,0 +1,51 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 H. Peter Anvin - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * solaris.c
+ *
+ * Solaris DHCP hack
+ *
+ * Solaris uses a nonstandard hack to pass DHCP information from a netboot.
+ */
+
+#include "mboot.h"
+#include <syslinux/pxe.h>
+
+void mboot_solaris_dhcp_hack(void)
+{
+ void *dhcpdata;
+ size_t dhcplen;
+
+ if (!pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) {
+ mbinfo.drives_addr = map_data(dhcpdata, dhcplen, 4, 0);
+ mbinfo.drives_length = dhcplen;
+ mbinfo.boot_device = 0x20ffffff;
+ mbinfo.flags = (mbinfo.flags & ~MB_INFO_DRIVE_INFO) | MB_INFO_BOOTDEV;
+ }
+}