summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/scripts/gpxelinux.gpxe4
-rw-r--r--contrib/scripts/static.gpxe8
-rw-r--r--src/Makefile.housekeeping42
-rw-r--r--src/core/config.c1
-rw-r--r--src/core/main.c15
-rw-r--r--src/image/default.gpxe2
-rw-r--r--src/image/embed.S7
-rw-r--r--src/image/embedded.c109
-rw-r--r--src/include/gpxe/embedded.h9
-rw-r--r--src/include/gpxe/errfile.h1
-rw-r--r--src/include/gpxe/uri.h1
-rw-r--r--src/usr/autoboot.c30
12 files changed, 138 insertions, 91 deletions
diff --git a/contrib/scripts/gpxelinux.gpxe b/contrib/scripts/gpxelinux.gpxe
new file mode 100644
index 00000000..dcfc80e6
--- /dev/null
+++ b/contrib/scripts/gpxelinux.gpxe
@@ -0,0 +1,4 @@
+#!gpxe
+dhcp net0
+imgload img1
+boot img1
diff --git a/contrib/scripts/static.gpxe b/contrib/scripts/static.gpxe
new file mode 100644
index 00000000..e3539fc0
--- /dev/null
+++ b/contrib/scripts/static.gpxe
@@ -0,0 +1,8 @@
+#!gpxe
+ifopen net0
+set net0/ip 10.0.2.15
+set net0/netmask 255.255.255.0
+set net0/gateway 10.0.2.2
+set net0/dns 10.0.2.3
+kernel http://etherboot.org/gtest/gtest.gpxe
+boot gtest.gpxe
diff --git a/src/Makefile.housekeeping b/src/Makefile.housekeeping
index ab6f29c2..d8413447 100644
--- a/src/Makefile.housekeeping
+++ b/src/Makefile.housekeeping
@@ -85,6 +85,13 @@ VERYCLEANUP += .toolcheck
# Check for various tool workarounds
#
+# Make syntax does not allow use of comma or space in certain places.
+# This ugly workaround is suggested in the manual.
+#
+COMMA := ,
+EMPTY :=
+SPACE := $(EMPTY) $(EMPTY)
+
# Check for an old version of gas (binutils 2.9.1)
#
OLDGAS := $(shell $(AS) --version | grep -q '2\.9\.1' && $(ECHO) -DGAS291)
@@ -280,9 +287,9 @@ ASFLAGS += --fatal-warnings
ASFLAGS += $(EXTRA_ASFLAGS)
LDFLAGS += $(EXTRA_LDFLAGS)
-# Embedded image, if present
+# Embedded image(s), or default if not set
#
-EMBEDDED_IMAGE = /dev/null
+EMBEDDED_IMAGE = image/default.gpxe
# Inhibit -Werror if NO_WERROR is specified on make command line
#
@@ -406,13 +413,31 @@ drivers :
roms :
@$(ECHO) $(ROMS)
-# Embedded binary
-$(BIN)/embedimg.bin: $(EMBEDDED_IMAGE)
- $(QM)$(ECHO) " [COPY] $@"
- $(Q)$(CP) -f $(EMBEDDED_IMAGE) $@
+# List of embedded images included in the last build of embedded.o.
+# This is needed in order to correctly rebuild embedded.o whenever the
+# list of objects changes.
+#
+EMBEDDED_LIST := $(BIN)/.embedded.list
+ifeq ($(wildcard $(EMBEDDED_LIST)),)
+EMBEDDED_LIST_IMAGE :=
+else
+EMBEDDED_LIST_IMAGE := $(shell cat $(EMBEDDED_LIST))
+endif
+ifneq ($(EMBEDDED_LIST_IMAGE),$(EMBEDDED_IMAGE))
+$(shell $(ECHO) "$(EMBEDDED_IMAGE)" > $(EMBEDDED_LIST))
+endif
+
+$(EMBEDDED_LIST) :
+
+VERYCLEANUP += $(EMBEDDED_LIST)
+
+EMBEDDED_FILES := $(subst $(COMMA), ,$(EMBEDDED_IMAGE))
+EMBED_ALL := $(foreach i,$(shell seq 1 $(words $(EMBEDDED_FILES))),\
+ EMBED ( $(i), \"$(word $(i), $(EMBEDDED_FILES))\",\
+ \"$(notdir $(word $(i),$(EMBEDDED_FILES)))\" ))
-$(BIN)/embed.o: $(BIN)/embedimg.bin
-CFLAGS_embed = -DEMBEDIMG=\"$(BIN)/embedimg.bin\"
+$(BIN)/embedded.o : $(EMBEDDED_FILES) $(EMBEDDED_LIST)
+CFLAGS_embedded = -DEMBED_ALL="$(EMBED_ALL)"
# Generate the NIC file from the parsed source files. The NIC file is
# only for rom-o-matic.
@@ -491,7 +516,6 @@ TGT_MAKEROM_FLAGS = $(strip $(MAKEROM_FLAGS_$(TGT_ROM_NAME)) \
# Calculate list of debugging versions of objects to be included in
# the target.
#
-COMMA := ,
DEBUG_LIST = $(subst $(COMMA), ,$(DEBUG))
DEBUG_OBJ_LEVEL = $(firstword $(word 2,$(subst :, ,$(1))) 1)
DEBUG_OBJ_BASE = $(word 1,$(subst :, ,$(1))).dbg$(call DEBUG_OBJ_LEVEL,$(1))
diff --git a/src/core/config.c b/src/core/config.c
index b14d25a8..741579fe 100644
--- a/src/core/config.c
+++ b/src/core/config.c
@@ -218,3 +218,4 @@ REQUIRE_OBJECT ( gdbstub_cmd );
*
*/
REQUIRE_OBJECT ( device );
+REQUIRE_OBJECT ( embedded );
diff --git a/src/core/main.c b/src/core/main.c
index e72b8c90..8d360c42 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -19,6 +19,7 @@ Literature dealing with the network protocols:
#include <gpxe/features.h>
#include <gpxe/shell.h>
#include <gpxe/shell_banner.h>
+#include <gpxe/image.h>
#include <usr/autoboot.h>
#include <config/general.h>
@@ -36,6 +37,7 @@ static struct feature features_end[0] __table_end ( struct feature, features );
*/
__asmcall int main ( void ) {
struct feature *feature;
+ struct image *image;
/* Some devices take an unreasonably long time to initialise */
printf ( PRODUCT_SHORT_NAME " initialising devices...\n" );
@@ -68,11 +70,16 @@ __asmcall int main ( void ) {
/* User wants shell; just give them a shell */
shell();
} else {
- /* User doesn't want shell; try booting. If booting
- * fails, offer a second chance to enter the shell for
- * diagnostics.
+ /* User doesn't want shell; load and execute the first
+ * image. If booting fails (i.e. if the image
+ * returns, or fails to execute), offer a second
+ * chance to enter the shell for diagnostics.
*/
- autoboot();
+ for_each_image ( image ) {
+ image_exec ( image );
+ break;
+ }
+
if ( shell_banner() )
shell();
}
diff --git a/src/image/default.gpxe b/src/image/default.gpxe
new file mode 100644
index 00000000..0b080b58
--- /dev/null
+++ b/src/image/default.gpxe
@@ -0,0 +1,2 @@
+#!gpxe
+autoboot
diff --git a/src/image/embed.S b/src/image/embed.S
deleted file mode 100644
index ef7d693b..00000000
--- a/src/image/embed.S
+++ /dev/null
@@ -1,7 +0,0 @@
- .section ".data", "aw", @progbits
- .balign 4
- .globl _embedded_image_start
-_embedded_image_start:
- .incbin EMBEDIMG
- .globl _embedded_image_end
-_embedded_image_end:
diff --git a/src/image/embedded.c b/src/image/embedded.c
index 0ce09783..f76ca11b 100644
--- a/src/image/embedded.c
+++ b/src/image/embedded.c
@@ -1,49 +1,94 @@
/** @file
*
- * Take a possible embedded image and put it in a struct image
- * data structure.
+ * Embedded image support
+ *
+ * Embedded images are images built into the gPXE binary and do not require
+ * fetching over the network.
*/
+#include <string.h>
#include <gpxe/image.h>
-#include <gpxe/malloc.h>
#include <gpxe/uaccess.h>
-#include <gpxe/umalloc.h>
-#include <gpxe/embedded.h>
+#include <gpxe/init.h>
-extern char _embedded_image_start[], _embedded_image_end[];
+/**
+ * Free embedded image
+ *
+ * @v refcnt Reference counter
+ */
+static void embedded_image_free ( struct refcnt *refcnt __unused ) {
+ /* Do nothing */
+}
-struct image *embedded_image(void)
-{
- static int reclaimed = 0;
- struct image *image;
- size_t eisize = _embedded_image_end - _embedded_image_start;
+/* Raw image data for all embedded images */
+#undef EMBED
+#define EMBED( _index, _path, _name ) \
+ extern char embedded_image_ ## _index ## _data[]; \
+ extern char embedded_image_ ## _index ## _len[]; \
+ __asm__ ( ".section \".rodata\", \"a\", @progbits\n\t" \
+ "\nembedded_image_" #_index "_data:\n\t" \
+ ".incbin \"" _path "\"\n\t" \
+ "\nembedded_image_" #_index "_end:\n\t" \
+ ".equ embedded_image_" #_index "_len, " \
+ "( embedded_image_" #_index "_end - " \
+ " embedded_image_" #_index "_data )\n\t" \
+ ".previous\n\t" );
+EMBED_ALL
- if ( !eisize )
- return NULL; /* No embedded image */
+/* Image structures for all embedded images */
+#undef EMBED
+#define EMBED( _index, _path, _name ) { \
+ .refcnt = { .free = embedded_image_free, }, \
+ .name = _name, \
+ .data = ( userptr_t ) ( embedded_image_ ## _index ## _data ), \
+ .len = ( size_t ) embedded_image_ ## _index ## _len, \
+},
+static struct image embedded_images[] = {
+ EMBED_ALL
+};
- if ( reclaimed )
- return NULL; /* Already reclaimed */
+/**
+ * Register all embedded images
+ */
+static void embedded_init ( void ) {
+ unsigned int i;
+ struct image *image;
+ void *data;
+ int rc;
- DBG ( "Embedded image: %zd bytes at %p\n",
- eisize, _embedded_image_start );
+ /* Fix up data pointers and register images */
+ for ( i = 0 ; i < ( sizeof ( embedded_images ) /
+ sizeof ( embedded_images[0] ) ) ; i++ ) {
+ image = &embedded_images[i];
- image = alloc_image();
- if (!image)
- return NULL;
+ /* virt_to_user() cannot be used in a static
+ * initialiser, so we cast the pointer to a userptr_t
+ * in the initialiser and fix it up here. (This will
+ * actually be a no-op on most platforms.)
+ */
+ data = ( ( void * ) image->data );
+ image->data = virt_to_user ( data );
- image->len = eisize;
- image->data = umalloc(eisize);
- if (image->data == UNULL) {
- image_put(image);
- return image = NULL;
- }
- copy_to_user(image->data, 0, _embedded_image_start, eisize);
- register_image(image);
+ DBG ( "Embedded image \"%s\": %zd bytes at %p\n",
+ image->name, image->len, data );
- /* Reclaim embedded image memory */
- reclaimed = 1;
- mpopulate(_embedded_image_start, eisize);
+ if ( ( rc = register_image ( image ) ) != 0 ) {
+ DBG ( "Could not register embedded image \"%s\": "
+ "%s\n", image->name, strerror ( rc ) );
+ return;
+ }
+ }
- return image;
+ /* Load the first image */
+ image = &embedded_images[0];
+ if ( ( rc = image_autoload ( image ) ) != 0 ) {
+ DBG ( "Could not load embedded image \"%s\": %s\n",
+ image->name, strerror ( rc ) );
+ return;
+ }
}
+/** Embedded image initialisation function */
+struct init_fn embedded_init_fn __init_fn ( INIT_NORMAL ) = {
+ .initialise = embedded_init,
+};
diff --git a/src/include/gpxe/embedded.h b/src/include/gpxe/embedded.h
deleted file mode 100644
index ec457055..00000000
--- a/src/include/gpxe/embedded.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _GPXE_EMBEDDED_H
-#define _GPXE_EMBEDDED_H
-
-#include <gpxe/image.h>
-
-struct image *embedded_image(void);
-
-#endif
-
diff --git a/src/include/gpxe/errfile.h b/src/include/gpxe/errfile.h
index 4809e50c..90c21a7e 100644
--- a/src/include/gpxe/errfile.h
+++ b/src/include/gpxe/errfile.h
@@ -145,6 +145,7 @@
#define ERRFILE_script ( ERRFILE_IMAGE | 0x00020000 )
#define ERRFILE_segment ( ERRFILE_IMAGE | 0x00030000 )
#define ERRFILE_efi_image ( ERRFILE_IMAGE | 0x00040000 )
+#define ERRFILE_embedded ( ERRFILE_IMAGE | 0x00050000 )
#define ERRFILE_asn1 ( ERRFILE_OTHER | 0x00000000 )
#define ERRFILE_chap ( ERRFILE_OTHER | 0x00010000 )
diff --git a/src/include/gpxe/uri.h b/src/include/gpxe/uri.h
index 37f3aac9..3803868d 100644
--- a/src/include/gpxe/uri.h
+++ b/src/include/gpxe/uri.h
@@ -7,6 +7,7 @@
*
*/
+#include <stddef.h>
#include <stdlib.h>
#include <gpxe/refcnt.h>
diff --git a/src/usr/autoboot.c b/src/usr/autoboot.c
index cad625e4..98e79a7f 100644
--- a/src/usr/autoboot.c
+++ b/src/usr/autoboot.c
@@ -23,7 +23,6 @@
#include <gpxe/dhcp.h>
#include <gpxe/settings.h>
#include <gpxe/image.h>
-#include <gpxe/embedded.h>
#include <gpxe/sanboot.h>
#include <gpxe/uri.h>
#include <usr/ifmgmt.h>
@@ -60,30 +59,6 @@ static struct net_device * find_boot_netdev ( void ) {
}
/**
- * Boot embedded image
- *
- * @ret rc Return status code
- */
-static int boot_embedded_image ( void ) {
- struct image *image;
- int rc;
-
- image = embedded_image();
- if ( !image )
- return ENOENT;
-
- if ( ( rc = imgload ( image ) ) != 0 ) {
- printf ( "Could not load embedded image: %s\n",
- strerror ( rc ) );
- } else if ( ( rc = imgexec ( image ) ) != 0 ) {
- printf ( "Could not boot embedded image: %s\n",
- strerror ( rc ) );
- }
- image_put ( image );
- return rc;
-}
-
-/**
* Boot using next-server and filename
*
* @v filename Boot filename
@@ -196,11 +171,6 @@ static int netboot ( struct net_device *netdev ) {
return rc;
route();
- /* Try to boot an embedded image if we have one */
- rc = boot_embedded_image ();
- if ( rc != ENOENT )
- return rc;
-
/* Try PXE menu boot, if applicable */
fetch_string_setting ( NULL, &vendor_class_id_setting,
buf, sizeof ( buf ) );