summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalf Ertzinger <ralf@skytale.net>2008-10-19 14:08:27 -0700
committerH. Peter Anvin <hpa@zytor.com>2008-10-19 14:08:27 -0700
commitd3554fa350b52af6c23c0ce9eee5369db36d0de3 (patch)
tree4017be0dc0ce8f6e477678548d33823ec80f04d7
parent5ae9675217168272e645bca55ddc7b7ba1400dbd (diff)
downloadsyslinux-d3554fa350b52af6c23c0ce9eee5369db36d0de3.tar.gz
mboot.c32: add Solaris mode
Add a "Solaris" mode to mboot.c32, which mimics a nonstandard extension to Multiboot used by Solaris' pxeboot program. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--com32/modules/mboot.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/com32/modules/mboot.c b/com32/modules/mboot.c
index bb92b147..da0f3fd0 100644
--- a/com32/modules/mboot.c
+++ b/com32/modules/mboot.c
@@ -33,6 +33,7 @@
#include <console.h>
#include <zlib.h>
#include <com32.h>
+#include <syslinux/pxe.h>
#include "i386-elf.h"
#include "mb_info.h"
@@ -53,6 +54,9 @@
#define MEM_HOLE_START 0xa0000 /* Memory hole runs from 640k ... */
#define MEM_HOLE_END 0x100000 /* ... to 1MB */
#define X86_PAGE_SIZE 0x1000
+#define DHCP_ACK_SIZE 1500 /* Maximum size of the DHCP ACK package.
+ Probably too large since we're interested
+ in the first bunch of bytes only. */
size_t __stack_size = STACK_SIZE; /* How much stack we'll use */
extern void *__mem_end; /* Start of malloc() heap */
@@ -926,12 +930,26 @@ int main(int argc, char **argv)
char *p;
size_t mbi_run_addr, mbi_size, entry;
int i;
+ int opt_solaris = 0;
+ void *dhcpdata;
+ size_t dhcplen;
/* Say hello */
openconsole(&dev_null_r, &dev_stdcon_w);
printf("%s. %s\n", version_string, copyright_string);
+ /* This is way too ugly. */
+ if (!strcmp("-solaris", argv[1])) {
+ opt_solaris = 1;
+ argv[1] = argv[0];
+ argv = &argv[1];
+ argc -= 1;
+ }
+
+ if (opt_solaris)
+ printf("Solaris DHCP passing enabled\n");
+
if (argc < 2 || !strcmp(argv[1], module_separator)) {
printf("Fatal: No kernel filename!\n");
exit(1);
@@ -958,6 +976,8 @@ int main(int argc, char **argv)
mbi_size += strlen(argv[i]) + 1;
}
}
+ if (opt_solaris)
+ mbi_size += DHCP_ACK_SIZE;
/* Allocate space in the load buffer for the MBI, all the command
* lines, and all the module details. */
@@ -1030,6 +1050,29 @@ int main(int argc, char **argv)
mbi->boot_loader_name = ((size_t)p) - mbi_reloc_offset;
p += strlen(version_string) + 1;
+ if (opt_solaris) {
+ /* Try to get the DHCP ACK packet from PXE */
+ if (!pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) {
+ /* Solaris expects the DHCP ACK packet to be passed in the drives_*
+ structure. However, the flags field must indicate that the
+ drives_structure is not being used.
+ Furthermore, the boot_device must be set to 0x20ffffff
+ */
+ dhcplen = MIN(dhcplen, DHCP_ACK_SIZE);
+ memcpy(p, dhcpdata, dhcplen);
+ mbi->drives_addr = ((size_t)p) - mbi_reloc_offset;
+ mbi->drives_length = dhcplen;
+ mbi->flags &= ~MB_INFO_DRIVE_INFO;
+ p += dhcplen;
+
+ mbi->boot_device = 0x20ffffff;
+ mbi->flags |= MB_INFO_BOOTDEV;
+ } else {
+ printf("Could not get DHCP information from PXE\n");
+ return 1;
+ }
+ }
+
/* Now, do all the loading, and boot it */
entry = load_kernel(mbi, (char *)(mbi->cmdline + mbi_reloc_offset));
for (i=0; i<modules; i++) {