Hi,
I managed to get Opensolaris working, but I'm not sure if my quick workaround
is the best way to solve it.
Attached a patch, which works around the following issues:
- Opensolaris expects to receive the full path to the kernel, not just the
filename.
- Grub loads modules at the beginning of the address space, while Gpxe seems
to do at the end.
Opensolaris's kernel startup routine expects grub's behavior, and searches for
a region of free memory after the address of the last loaded module, which is
normally not available when you use gpxe.
- Opensolaris expects to be passed the DHCP ACK packet.
Perhaps someone more familiar with the gpxe codebase, can take a look at it
and transform it into a proper patch.
Yours sincerely,
Floris Bos
diff -ur gpxe.orig/src/arch/i386/image/multiboot.c gpxe/src/arch/i386/image/multiboot.c
--- gpxe.orig/src/arch/i386/image/multiboot.c 2010-04-24 22:48:28.892197481 +0200
+++ gpxe/src/arch/i386/image/multiboot.c 2010-04-24 23:24:56.220322796 +0200
@@ -37,6 +37,9 @@
#include <gpxe/elf.h>
#include <gpxe/init.h>
#include <gpxe/features.h>
+#include <gpxe/fakedhcp.h>
+#include <pxe_api.h>
+#include <gpxe/umalloc.h>
FEATURE ( FEATURE_IMAGE, "Multiboot", DHCP_EB_FEATURE_MULTIBOOT, 1 );
@@ -97,6 +100,11 @@
/** Offset within module command lines */
static unsigned int mb_cmdline_offset;
+/** DHCP ack for Solaris */
+static struct bootph __bss16 ( dhcp_ack );
+#define dhcp_ack __use_data16 ( dhcp_ack )
+
+
/**
* Build multiboot memory map
*
@@ -285,6 +293,14 @@
*/
multiboot_build_memmap ( image, &mbinfo, mbmemmap,
( sizeof(mbmemmap) / sizeof(mbmemmap[0]) ) );
+
+ /* Opensolaris wants the DHCP ack as drives parameter
+ */
+ if ( dhcp_ack.opcode == BOOTP_REP )
+ {
+ mbinfo.drives_length = sizeof(dhcp_ack);
+ mbinfo.drives_addr = virt_to_phys( &dhcp_ack );
+ }
/* Jump to OS with flat physical addressing */
DBGC ( image, "MULTIBOOT %p starting execution at %lx\n",
@@ -417,6 +433,53 @@
}
/**
+ * Opensolaris specific workarounds
+ */
+static void multiboot_opensolaris_workarounds ( struct image *image ) {
+ Elf32_Ehdr ehdr;
+
+ memset ( &dhcp_ack, 0, sizeof(dhcp_ack) );
+
+ if ( image->len < sizeof(ehdr) )
+ return;
+
+ copy_from_user( &ehdr, image->data, 0, sizeof(ehdr) );
+ if ( memcmp ( &ehdr.e_ident[EI_MAG0], ELFMAG, SELFMAG ) != 0 /* not an ELF image */
+ || ehdr.e_ident[7] != 6 ) /* ABI is not Solaris */
+ {
+ return;
+ }
+
+ DBGC ( image, "MULTIBOOT %p image ABI is Solaris, using workarounds\n",
+ image );
+
+ /**
+ * Opensolaris expects a full path containing the architecture, not just the filename of the kernel
+ */
+ if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
+ {
+ strncpy(image->name, "/platform/i86pc/kernel/amd64/unix", sizeof(image->name));
+ }
+ else
+ {
+ strncpy(image->name, "/platform/i86pc/kernel/unix", sizeof(image->name));
+ }
+
+ /**
+ * Create a (fake) DHCP ack, to be passed to Opensolaris in multiboot_exec()
+ */
+ create_fakedhcpack( last_opened_netdev(), &dhcp_ack, sizeof(dhcp_ack) );
+
+ /*
+ * Opensolaris's prekernel routine expects to have a free memory region directly after the ramdisk
+ * That doesn't go well with gpxe's memory allocation which tends to grow down from high addresses to low
+ * and causes the ramdisk to be placed directly before the kernel in memory
+ * As a workaround we simply allocate memory here, which will cause a free memory region between the kernel and ramdisk
+ */
+ urealloc(UNULL, 255*1024*1024);
+}
+
+/**
* Load multiboot image into memory
*
* @v image Multiboot file
@@ -454,6 +517,8 @@
if ( ( ( rc = multiboot_load_elf ( image ) ) != 0 ) &&
( ( rc = multiboot_load_raw ( image, &hdr ) ) != 0 ) )
return rc;
+
+ multiboot_opensolaris_workarounds( image );
return 0;
}
diff -ur gpxe.orig/src/include/gpxe/image.h gpxe/src/include/gpxe/image.h
--- gpxe.orig/src/include/gpxe/image.h 2010-04-24 22:48:28.912196578 +0200
+++ gpxe/src/include/gpxe/image.h 2010-04-24 22:56:32.280322754 +0200
@@ -29,7 +29,7 @@
/** URI of image */
struct uri *uri;
/** Name */
- char name[16];
+ char name[255];
/** Flags */
unsigned int flags;
_______________________________________________
gPXE-devel mailing list
[email protected]
http://etherboot.org/mailman/listinfo/gpxe-devel