diff options
author | Ralf Ertzinger <ralf@skytale.net> | 2008-10-19 14:08:27 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-10-19 14:08:27 -0700 |
commit | d3554fa350b52af6c23c0ce9eee5369db36d0de3 (patch) | |
tree | 4017be0dc0ce8f6e477678548d33823ec80f04d7 | |
parent | 5ae9675217168272e645bca55ddc7b7ba1400dbd (diff) | |
download | syslinux-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.c | 43 |
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++) { |