summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/image.c83
-rw-r--r--src/include/ipxe/image.h1
-rw-r--r--src/tests/pixbuf_test.c7
3 files changed, 47 insertions, 44 deletions
diff --git a/src/core/image.c b/src/core/image.c
index 365e4d80..529e3d72 100644
--- a/src/core/image.c
+++ b/src/core/image.c
@@ -158,6 +158,32 @@ int image_set_cmdline ( struct image *image, const char *cmdline ) {
}
/**
+ * Determine image type
+ *
+ * @v image Executable image
+ * @ret rc Return status code
+ */
+static int image_probe ( struct image *image ) {
+ struct image_type *type;
+ int rc;
+
+ /* Try each type in turn */
+ for_each_table_entry ( type, IMAGE_TYPES ) {
+ if ( ( rc = type->probe ( image ) ) == 0 ) {
+ image->type = type;
+ DBGC ( image, "IMAGE %s is %s\n",
+ image->name, type->name );
+ break;
+ }
+ DBGC ( image, "IMAGE %s is not %s: %s\n", image->name,
+ type->name, strerror ( rc ) );
+ }
+
+ DBGC ( image, "IMAGE %s format not recognised\n", image->name );
+ return -ENOTSUP;
+}
+
+/**
* Register executable image
*
* @v image Executable image
@@ -189,6 +215,14 @@ int register_image ( struct image *image ) {
image->name, user_to_phys ( image->data, 0 ),
user_to_phys ( image->data, image->len ) );
+ /* Try to detect image type, if applicable. Ignore failures,
+ * since we expect to handle some unrecognised images
+ * (e.g. kernel initrds, multiboot modules, random files
+ * provided via our EFI virtual filesystem, etc).
+ */
+ if ( ! image->type )
+ image_probe ( image );
+
return 0;
}
@@ -227,36 +261,6 @@ struct image * find_image ( const char *name ) {
}
/**
- * Determine image type
- *
- * @v image Executable image
- * @ret rc Return status code
- */
-int image_probe ( struct image *image ) {
- struct image_type *type;
- int rc;
-
- /* Succeed if we already have a type */
- if ( image->type )
- return 0;
-
- /* Try each type in turn */
- for_each_table_entry ( type, IMAGE_TYPES ) {
- if ( ( rc = type->probe ( image ) ) == 0 ) {
- image->type = type;
- DBGC ( image, "IMAGE %s is %s\n",
- image->name, type->name );
- return 0;
- }
- DBGC ( image, "IMAGE %s is not %s: %s\n", image->name,
- type->name, strerror ( rc ) );
- }
-
- DBGC ( image, "IMAGE %s format not recognised\n", image->name );
- return -ENOEXEC;
-}
-
-/**
* Execute image
*
* @v image Executable image
@@ -288,9 +292,11 @@ int image_exec ( struct image *image ) {
*/
current_image = image_get ( image );
- /* Check that this image can be selected for execution */
- if ( ( rc = image_select ( image ) ) != 0 )
+ /* Check that this image can be executed */
+ if ( ! ( image->type && image->type->exec ) ) {
+ rc = -ENOEXEC;
goto err;
+ }
/* Check that image is trusted (if applicable) */
if ( require_trusted_images && ! ( image->flags & IMAGE_TRUSTED ) ) {
@@ -382,8 +388,8 @@ int image_replace ( struct image *replacement ) {
}
/* Check that the replacement image can be executed */
- if ( ( rc = image_probe ( replacement ) ) != 0 )
- return rc;
+ if ( ! ( replacement->type && replacement->type->exec ) )
+ return -ENOEXEC;
/* Clear any existing replacement */
image_put ( image->replacement );
@@ -404,16 +410,13 @@ int image_replace ( struct image *replacement ) {
*/
int image_select ( struct image *image ) {
struct image *tmp;
- int rc;
/* Unselect all other images */
for_each_image ( tmp )
tmp->flags &= ~IMAGE_SELECTED;
/* Check that this image can be executed */
- if ( ( rc = image_probe ( image ) ) != 0 )
- return rc;
- if ( ! image->type->exec )
+ if ( ! ( image->type && image->type->exec ) )
return -ENOEXEC;
/* Mark image as selected */
@@ -472,9 +475,7 @@ int image_pixbuf ( struct image *image, struct pixel_buffer **pixbuf ) {
int rc;
/* Check that this image can be used to create a pixel buffer */
- if ( ( rc = image_probe ( image ) ) != 0 )
- return rc;
- if ( ! image->type->pixbuf )
+ if ( ! ( image->type && image->type->pixbuf ) )
return -ENOTSUP;
/* Try creating pixel buffer */
diff --git a/src/include/ipxe/image.h b/src/include/ipxe/image.h
index 5d003842..6abd7a2d 100644
--- a/src/include/ipxe/image.h
+++ b/src/include/ipxe/image.h
@@ -163,7 +163,6 @@ extern int image_set_cmdline ( struct image *image, const char *cmdline );
extern int register_image ( struct image *image );
extern void unregister_image ( struct image *image );
struct image * find_image ( const char *name );
-extern int image_probe ( struct image *image );
extern int image_exec ( struct image *image );
extern int image_replace ( struct image *replacement );
extern int image_select ( struct image *image );
diff --git a/src/tests/pixbuf_test.c b/src/tests/pixbuf_test.c
index 28c502b4..aaa516bb 100644
--- a/src/tests/pixbuf_test.c
+++ b/src/tests/pixbuf_test.c
@@ -57,8 +57,8 @@ void pixbuf_okx ( struct pixel_buffer_test *test, const char *file,
/* Correct image data pointer */
test->image->data = virt_to_user ( ( void * ) test->image->data );
- /* Check that image is detected as PNM */
- okx ( image_probe ( test->image ) == 0, file, line );
+ /* Check that image is detected as correct type */
+ okx ( register_image ( test->image ) == 0, file, line );
okx ( test->image->type == test->type, file, line );
/* Check that a pixel buffer can be created from the image */
@@ -77,4 +77,7 @@ void pixbuf_okx ( struct pixel_buffer_test *test, const char *file,
pixbuf_put ( pixbuf );
}
+
+ /* Unregister image */
+ unregister_image ( test->image );
}