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

Reply via email to