-
Notifications
You must be signed in to change notification settings - Fork 40
/
smartos-gpxe.patch
112 lines (104 loc) · 3.75 KB
/
smartos-gpxe.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
diff --git a/src/arch/i386/image/multiboot.c b/src/arch/i386/image/multiboot.c
index 5b62095..a581318 100644
--- a/src/arch/i386/image/multiboot.c
+++ b/src/arch/i386/image/multiboot.c
@@ -37,6 +37,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <gpxe/elf.h>
#include <gpxe/init.h>
#include <gpxe/features.h>
+#include <gpxe/umalloc.h>
FEATURE ( FEATURE_IMAGE, "Multiboot", DHCP_EB_FEATURE_MULTIBOOT, 1 );
@@ -416,6 +417,44 @@ static int multiboot_load_elf ( struct image *image ) {
return 0;
}
+static void multiboot_solaris_workarounds ( struct image *image ) {
+ Elf32_Ehdr ehdr;
+
+ 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 ||
+ ehdr.e_ident[EI_OSABI] != ELFOSABI_SOLARIS )
+ return;
+
+ DBGC ( image, "MULTIBOOT %p: applying Solaris workarounds\n", image );
+
+ /* Solaris 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) );
+ }
+
+ /* Solaris's pre-kernel routine expects to have a free memory region
+ * directly after the ramdisk. However, gPXE allocates memory from
+ * high addresses to low, causing the ramdisk to be placed directly
+ * before the kernel in memory. To workaround this, we allocate a
+ * chunk of memory here, opening up a free memory region between the
+ * kernel and ramdisk. Note that the size of this region must be
+ * balanced: it must be large enough for Solaris to boot without
+ * being so large that an important class of machines is rendered
+ * unbootable. For now, 128MB seems to hit that sweet spot.
+ */
+ urealloc( UNULL, 128 * 1024 * 1024 );
+}
+
/**
* Load multiboot image into memory
*
@@ -455,6 +494,8 @@ static int multiboot_load ( struct image *image ) {
( ( rc = multiboot_load_raw ( image, &hdr ) ) != 0 ) )
return rc;
+ multiboot_solaris_workarounds( image );
+
return 0;
}
diff --git a/src/include/elf.h b/src/include/elf.h
index 04022b6..63bed89 100644
--- a/src/include/elf.h
+++ b/src/include/elf.h
@@ -138,6 +138,28 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define EI_VERSION 6 /* File version byte index */
/* Value must be EV_CURRENT */
+#define EI_OSABI 7 /* OS ABI byte index */
+
+#define ELFOSABI_NONE 0 /* No extensions or unspecified */
+#define ELFOSABI_SYSV ELFOSABI_NONE
+#define ELFOSABI_HPUX 1 /* Hewlett-Packard HP-UX */
+#define ELFOSABI_NETBSD 2 /* NetBSD */
+#define ELFOSABI_LINUX 3 /* Linux */
+#define ELFOSABI_HURD 4 /* Hurd */
+#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
+#define ELFOSABI_SOLARIS 6 /* Sun Solaris */
+#define ELFOSABI_AIX 7 /* AIX */
+#define ELFOSABI_IRIX 8 /* IRIX */
+#define ELFOSABI_FREEBSD 9 /* FreeBSD */
+#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
+#define ELFOSABI_MODESTO 11 /* Novell Modesto */
+#define ELFOSABI_OPENBSD 12 /* Open BSD */
+#define ELFOSABI_OPENVMS 13 /* Open VMS */
+#define ELFOSABI_NSK 14 /* Hewlett-Packard Non-Stop Kernel */
+#define ELFOSABI_AROS 15 /* Amiga Research OS */
+#define ELFOSABI_ARM 97 /* ARM */
+#define ELFOSABI_STANDALONE 255 /* standalone (embedded) application */
+
#define EV_NONE 0 /* Invalid ELF Version */
#define EV_CURRENT 1 /* Current version */
diff --git a/src/include/gpxe/image.h b/src/include/gpxe/image.h
index 10db8af..702ad45 100644
--- a/src/include/gpxe/image.h
+++ b/src/include/gpxe/image.h
@@ -29,7 +29,7 @@ struct image {
/** URI of image */
struct uri *uri;
/** Name */
- char name[16];
+ char name[256];
/** Flags */
unsigned int flags;