Kaynağa Gözat

[ELF] Add ability to boot ELF images generated by wraplinux and mkelfImage

Delete ELF as a generic image type.  The method for invoking an
ELF-based image (as well as any tables that must be set up to allow it
to boot) will always depend on the specific architecture.  core/elf.c
now only provides the elf_load() function, to avoid duplicating
functionality between ELF-based image types.

Add arch/i386/image/elfboot.c, to handle the generic case of 32-bit
x86 ELF images.  We don't currently set up any multiboot tables, ELF
notes, etc.  This seems to be sufficient for loading kernels generated
using both wraplinux and coreboot's mkelfImage.

Note that while Etherboot 5.4 allowed ELF images to return, we don't.
There is no callback mechanism for the loaded image to shut down gPXE,
which means that we have to shut down before invoking the image.  This
means that we lose device state, protection against being trampled on,
etc.  It is not safe to continue afterwards.
tags/v0.9.4
Michael Brown 16 yıl önce
ebeveyn
işleme
77a5cc6b13

+ 110
- 0
src/arch/i386/image/elfboot.c Dosyayı Görüntüle

@@ -0,0 +1,110 @@
1
+/*
2
+ * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <errno.h>
20
+#include <elf.h>
21
+#include <gpxe/image.h>
22
+#include <gpxe/elf.h>
23
+#include <gpxe/features.h>
24
+#include <gpxe/init.h>
25
+
26
+/**
27
+ * @file
28
+ *
29
+ * ELF bootable image
30
+ *
31
+ */
32
+
33
+FEATURE ( FEATURE_IMAGE, "ELF", DHCP_EB_FEATURE_ELF, 1 );
34
+
35
+struct image_type elfboot_image_type __image_type ( PROBE_NORMAL );
36
+
37
+/**
38
+ * Execute ELF image
39
+ *
40
+ * @v image		ELF image
41
+ * @ret rc		Return status code
42
+ */
43
+static int elfboot_exec ( struct image *image ) {
44
+	physaddr_t entry = image->priv.phys;
45
+
46
+	/* An ELF image has no callback interface, so we need to shut
47
+	 * down before invoking it.
48
+	 */
49
+	shutdown();
50
+
51
+	/* Jump to OS with flat physical addressing */
52
+	__asm__ __volatile__ ( PHYS_CODE ( "call *%%edi\n\t" )
53
+			       : : "D" ( entry )
54
+			       : "eax", "ebx", "ecx", "edx", "esi", "ebp",
55
+			         "memory" );
56
+
57
+	DBGC ( image, "ELF %p returned\n", image );
58
+
59
+	/* It isn't safe to continue after calling shutdown() */
60
+	while ( 1 ) {}
61
+
62
+	return -ECANCELED;  /* -EIMPOSSIBLE, anyone? */
63
+}
64
+
65
+/**
66
+ * Load ELF image into memory
67
+ *
68
+ * @v image		ELF file
69
+ * @ret rc		Return status code
70
+ */
71
+static int elfboot_load ( struct image *image ) {
72
+	Elf32_Ehdr ehdr;
73
+	static const uint8_t e_ident[] = {
74
+		[EI_MAG0]	= ELFMAG0,
75
+		[EI_MAG1]	= ELFMAG1,
76
+		[EI_MAG2]	= ELFMAG2,
77
+		[EI_MAG3]	= ELFMAG3,
78
+		[EI_CLASS]	= ELFCLASS32,
79
+		[EI_DATA]	= ELFDATA2LSB,
80
+		[EI_VERSION]	= EV_CURRENT,
81
+	};
82
+	int rc;
83
+
84
+	/* Read ELF header */
85
+	copy_from_user ( &ehdr, image->data, 0, sizeof ( ehdr ) );
86
+	if ( memcmp ( ehdr.e_ident, e_ident, sizeof ( e_ident ) ) != 0 ) {
87
+		DBG ( "Invalid ELF identifier\n" );
88
+		return -ENOEXEC;
89
+	}
90
+
91
+	/* This is an ELF image, valid or otherwise */
92
+	if ( ! image->type )
93
+		image->type = &elfboot_image_type;
94
+
95
+	/* Load the image using core ELF support */
96
+	if ( ( rc = elf_load ( image ) ) != 0 ) {
97
+		DBGC ( image, "ELF %p could not load: %s\n",
98
+		       image, strerror ( rc ) );
99
+		return rc;
100
+	}
101
+
102
+	return 0;
103
+}
104
+
105
+/** ELF image type */
106
+struct image_type elfboot_image_type __image_type ( PROBE_NORMAL ) = {
107
+	.name = "ELF",
108
+	.load = elfboot_load,
109
+	.exec = elfboot_exec,
110
+};

+ 1
- 0
src/arch/i386/include/bits/errfile.h Dosyayı Görüntüle

@@ -20,6 +20,7 @@
20 20
 #define ERRFILE_multiboot      ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00030000 )
21 21
 #define ERRFILE_nbi	       ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00040000 )
22 22
 #define ERRFILE_pxe_image      ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00050000 )
23
+#define ERRFILE_elfboot	       ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00060000 )
23 24
 
24 25
 #define ERRFILE_undi		 ( ERRFILE_ARCH | ERRFILE_NET | 0x00000000 )
25 26
 #define ERRFILE_undiload	 ( ERRFILE_ARCH | ERRFILE_NET | 0x00010000 )

+ 1
- 2
src/config.h Dosyayı Görüntüle

@@ -121,8 +121,7 @@
121 121
  *
122 122
  */
123 123
 #undef	IMAGE_NBI		/* NBI image support */
124
-#undef	IMAGE_ELF64		/* ELF64 image support */
125
-#undef	IMAGE_ELF		/* ELF image support */
124
+#define	IMAGE_ELF		/* ELF image support */
126 125
 #undef	IMAGE_FREEBSD		/* FreeBSD kernel image support */
127 126
 #define	IMAGE_MULTIBOOT		/* MultiBoot image support */
128 127
 #undef	IMAGE_AOUT		/* a.out image support */

+ 1
- 4
src/core/config.c Dosyayı Görüntüle

@@ -131,11 +131,8 @@ REQUIRE_OBJECT ( nmb );
131 131
 #ifdef IMAGE_NBI
132 132
 REQUIRE_OBJECT ( nbi );
133 133
 #endif
134
-#ifdef IMAGE_ELF64
135
-REQUIRE_OBJECT ( elf64 );
136
-#endif
137 134
 #ifdef IMAGE_ELF
138
-REQUIRE_OBJECT ( elf );
135
+REQUIRE_OBJECT ( elfboot );
139 136
 #endif
140 137
 #ifdef IMAGE_FREEBSD
141 138
 REQUIRE_OBJECT ( freebsd );

+ 6
- 23
src/image/elf.c Dosyayı Görüntüle

@@ -21,6 +21,9 @@
21 21
  *
22 22
  * ELF image format
23 23
  *
24
+ * A "pure" ELF image is not a bootable image.  There are various
25
+ * bootable formats based upon ELF (e.g. Multiboot), which share
26
+ * common ELF-related functionality.
24 27
  */
25 28
 
26 29
 #include <errno.h>
@@ -30,22 +33,10 @@
30 33
 #include <gpxe/image.h>
31 34
 #include <gpxe/elf.h>
32 35
 
33
-struct image_type elf_image_type __image_type ( PROBE_NORMAL );
34
-
35 36
 typedef Elf32_Ehdr	Elf_Ehdr;
36 37
 typedef Elf32_Phdr	Elf_Phdr;
37 38
 typedef Elf32_Off	Elf_Off;
38 39
 
39
-/**
40
- * Execute ELF image
41
- *
42
- * @v image		ELF file
43
- * @ret rc		Return status code
44
- */
45
-static int elf_exec ( struct image *image __unused ) {
46
-	return -ENOTSUP;
47
-}
48
-
49 40
 /**
50 41
  * Load ELF segment into memory
51 42
  *
@@ -112,6 +103,9 @@ int elf_load ( struct image *image ) {
112 103
 	unsigned int phnum;
113 104
 	int rc;
114 105
 
106
+	/* Image type must already have been set by caller */
107
+	assert ( image->type != NULL );
108
+
115 109
 	/* Read ELF header */
116 110
 	copy_from_user ( &ehdr, image->data, 0, sizeof ( ehdr ) );
117 111
 	if ( memcmp ( &ehdr.e_ident[EI_MAG0], ELFMAG, SELFMAG ) != 0 ) {
@@ -119,10 +113,6 @@ int elf_load ( struct image *image ) {
119 113
 		return -ENOEXEC;
120 114
 	}
121 115
 
122
-	/* This is an ELF image, valid or otherwise */
123
-	if ( ! image->type )
124
-		image->type = &elf_image_type;
125
-
126 116
 	/* Read ELF program headers */
127 117
 	for ( phoff = ehdr.e_phoff , phnum = ehdr.e_phnum ; phnum ;
128 118
 	      phoff += ehdr.e_phentsize, phnum-- ) {
@@ -141,10 +131,3 @@ int elf_load ( struct image *image ) {
141 131
 
142 132
 	return 0;
143 133
 }
144
-
145
-/** ELF image type */
146
-struct image_type elf_image_type __image_type ( PROBE_NORMAL ) = {
147
-	.name = "ELF",
148
-	.load = elf_load,
149
-	.exec = elf_exec,
150
-};

+ 1
- 0
src/include/gpxe/features.h Dosyayı Görüntüle

@@ -43,6 +43,7 @@
43 43
 #define DHCP_EB_FEATURE_MULTIBOOT	0x19 /**< Multiboot format */
44 44
 #define DHCP_EB_FEATURE_NBI		0x20 /**< NBI format */
45 45
 #define DHCP_EB_FEATURE_PXE		0x21 /**< PXE format */
46
+#define DHCP_EB_FEATURE_ELF		0x22 /**< ELF format */
46 47
 
47 48
 /** @} */
48 49
 

Loading…
İptal
Kaydet