2007-01-11 17:04:36 +01:00
|
|
|
#ifndef _GPXE_IMAGE_H
|
|
|
|
#define _GPXE_IMAGE_H
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
*
|
2007-01-12 00:43:29 +01:00
|
|
|
* Executable/loadable images
|
2007-01-11 17:04:36 +01:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <gpxe/tables.h>
|
2007-01-12 00:43:29 +01:00
|
|
|
#include <gpxe/list.h>
|
|
|
|
#include <gpxe/uaccess.h>
|
2007-05-01 02:11:34 +02:00
|
|
|
#include <gpxe/refcnt.h>
|
2007-01-12 00:43:29 +01:00
|
|
|
|
2007-08-02 21:18:32 +02:00
|
|
|
struct uri;
|
2007-01-12 00:43:29 +01:00
|
|
|
struct image_type;
|
2007-01-11 17:04:36 +01:00
|
|
|
|
|
|
|
/** An executable or loadable image */
|
|
|
|
struct image {
|
2007-05-01 02:11:34 +02:00
|
|
|
/** Reference count */
|
|
|
|
struct refcnt refcnt;
|
|
|
|
|
2007-01-12 00:43:29 +01:00
|
|
|
/** List of registered images */
|
|
|
|
struct list_head list;
|
2007-08-02 21:18:32 +02:00
|
|
|
|
|
|
|
/** URI of image */
|
|
|
|
struct uri *uri;
|
|
|
|
/** Name */
|
|
|
|
char name[16];
|
2007-01-12 09:58:16 +01:00
|
|
|
/** Flags */
|
|
|
|
unsigned int flags;
|
2007-01-12 00:43:29 +01:00
|
|
|
|
|
|
|
/** Command line to pass to image */
|
2007-08-02 21:18:32 +02:00
|
|
|
char *cmdline;
|
2007-01-11 17:04:36 +01:00
|
|
|
/** Raw file image */
|
2007-01-11 17:07:30 +01:00
|
|
|
userptr_t data;
|
2007-01-11 17:04:36 +01:00
|
|
|
/** Length of raw file image */
|
|
|
|
size_t len;
|
|
|
|
|
2007-01-12 00:43:29 +01:00
|
|
|
/** Image type, if known */
|
|
|
|
struct image_type *type;
|
2007-01-14 05:04:28 +01:00
|
|
|
/** Image type private data */
|
|
|
|
union {
|
|
|
|
physaddr_t phys;
|
|
|
|
userptr_t user;
|
2007-01-14 07:36:20 +01:00
|
|
|
unsigned long ul;
|
2007-01-14 05:04:28 +01:00
|
|
|
} priv;
|
2009-02-17 01:47:35 +01:00
|
|
|
|
|
|
|
/** Replacement image
|
|
|
|
*
|
|
|
|
* An image wishing to replace itself with another image (in a
|
|
|
|
* style similar to a Unix exec() call) should return from its
|
|
|
|
* exec() method with the replacement image set to point to
|
|
|
|
* the new image. The new image must already be in a suitable
|
2009-02-17 02:45:12 +01:00
|
|
|
* state for execution (i.e. loaded).
|
|
|
|
*
|
|
|
|
* If an image unregisters itself as a result of being
|
|
|
|
* executed, it must make sure that its replacement image (if
|
|
|
|
* any) is registered, otherwise the replacement is likely to
|
|
|
|
* be freed before it can be executed.
|
2009-02-17 01:47:35 +01:00
|
|
|
*/
|
|
|
|
struct image *replacement;
|
2007-01-11 17:04:36 +01:00
|
|
|
};
|
|
|
|
|
2007-01-12 07:03:02 +01:00
|
|
|
/** Image is loaded */
|
|
|
|
#define IMAGE_LOADED 0x0001
|
|
|
|
|
2007-01-11 17:04:36 +01:00
|
|
|
/** An executable or loadable image type */
|
|
|
|
struct image_type {
|
|
|
|
/** Name of this image type */
|
|
|
|
char *name;
|
2007-01-12 00:43:29 +01:00
|
|
|
/**
|
|
|
|
* Load image into memory
|
2007-01-11 17:04:36 +01:00
|
|
|
*
|
|
|
|
* @v image Executable/loadable image
|
|
|
|
* @ret rc Return status code
|
|
|
|
*
|
2007-01-12 09:15:25 +01:00
|
|
|
* Load the image into memory at the correct location as
|
|
|
|
* determined by the file format.
|
2007-01-11 18:06:25 +01:00
|
|
|
*
|
2007-01-12 00:43:29 +01:00
|
|
|
* If the file image is in the correct format, the method must
|
|
|
|
* update @c image->type to point to its own type (unless @c
|
|
|
|
* image->type is already set). This allows the autoloading
|
|
|
|
* code to disambiguate between "this is not my image format"
|
|
|
|
* and "there is something wrong with this image". In
|
|
|
|
* particular, setting @c image->type and then returning an
|
|
|
|
* error will cause image_autoload() to abort and return an
|
|
|
|
* error, rather than continuing to the next image type.
|
2007-01-11 17:04:36 +01:00
|
|
|
*/
|
|
|
|
int ( * load ) ( struct image *image );
|
2007-01-12 00:43:29 +01:00
|
|
|
/**
|
|
|
|
* Execute loaded image
|
|
|
|
*
|
|
|
|
* @v image Loaded image
|
|
|
|
* @ret rc Return status code
|
2009-02-17 01:47:35 +01:00
|
|
|
*
|
|
|
|
* Note that the image may be invalidated by the act of
|
|
|
|
* execution, i.e. an image is allowed to choose to unregister
|
|
|
|
* (and so potentially free) itself.
|
2007-01-12 00:43:29 +01:00
|
|
|
*/
|
|
|
|
int ( * exec ) ( struct image *image );
|
2007-01-11 17:04:36 +01:00
|
|
|
};
|
|
|
|
|
2007-01-12 09:10:35 +01:00
|
|
|
/**
|
|
|
|
* Multiboot image probe priority
|
|
|
|
*
|
|
|
|
* Multiboot images are also valid executables in another format
|
|
|
|
* (e.g. ELF), so we must perform the multiboot probe first.
|
|
|
|
*/
|
|
|
|
#define PROBE_MULTIBOOT 01
|
2007-01-11 17:04:36 +01:00
|
|
|
|
|
|
|
/**
|
2007-01-12 09:10:35 +01:00
|
|
|
* Normal image probe priority
|
|
|
|
*/
|
|
|
|
#define PROBE_NORMAL 02
|
|
|
|
|
|
|
|
/**
|
|
|
|
* PXE image probe priority
|
2007-01-11 17:04:36 +01:00
|
|
|
*
|
2007-01-12 09:10:35 +01:00
|
|
|
* PXE images have no signature checks, so will claim all image files.
|
|
|
|
* They must therefore be tried last in the probe order list.
|
2007-01-11 17:04:36 +01:00
|
|
|
*/
|
2007-01-12 09:10:35 +01:00
|
|
|
#define PROBE_PXE 03
|
|
|
|
|
|
|
|
/** An executable or loadable image type */
|
|
|
|
#define __image_type( probe_order ) \
|
|
|
|
__table ( struct image_type, image_types, probe_order )
|
2007-01-11 17:04:36 +01:00
|
|
|
|
2007-01-12 00:43:29 +01:00
|
|
|
extern struct list_head images;
|
|
|
|
|
|
|
|
/** Iterate over all registered images */
|
|
|
|
#define for_each_image( image ) \
|
|
|
|
list_for_each_entry ( (image), &images, list )
|
|
|
|
|
2007-06-28 18:55:29 +02:00
|
|
|
extern struct image * alloc_image ( void );
|
2007-08-02 21:18:32 +02:00
|
|
|
extern int image_set_uri ( struct image *image, struct uri *uri );
|
|
|
|
extern int image_set_cmdline ( struct image *image, const char *cmdline );
|
2007-01-12 00:43:29 +01:00
|
|
|
extern int register_image ( struct image *image );
|
|
|
|
extern void unregister_image ( struct image *image );
|
2007-01-12 10:46:10 +01:00
|
|
|
extern void promote_image ( struct image *image );
|
2007-01-12 07:03:02 +01:00
|
|
|
struct image * find_image ( const char *name );
|
2007-01-12 00:43:29 +01:00
|
|
|
extern int image_load ( struct image *image );
|
|
|
|
extern int image_autoload ( struct image *image );
|
|
|
|
extern int image_exec ( struct image *image );
|
2007-08-02 21:18:32 +02:00
|
|
|
extern int register_and_autoload_image ( struct image *image );
|
|
|
|
extern int register_and_autoexec_image ( struct image *image );
|
2007-01-12 00:43:29 +01:00
|
|
|
|
2007-05-01 02:11:34 +02:00
|
|
|
/**
|
|
|
|
* Increment reference count on an image
|
|
|
|
*
|
|
|
|
* @v image Image
|
|
|
|
* @ret image Image
|
|
|
|
*/
|
|
|
|
static inline struct image * image_get ( struct image *image ) {
|
|
|
|
ref_get ( &image->refcnt );
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Decrement reference count on an image
|
|
|
|
*
|
|
|
|
* @v image Image
|
|
|
|
*/
|
|
|
|
static inline void image_put ( struct image *image ) {
|
|
|
|
ref_put ( &image->refcnt );
|
|
|
|
}
|
|
|
|
|
2007-08-02 21:18:32 +02:00
|
|
|
/**
|
|
|
|
* Set image name
|
|
|
|
*
|
|
|
|
* @v image Image
|
|
|
|
* @v name New image name
|
|
|
|
* @ret rc Return status code
|
|
|
|
*/
|
|
|
|
static inline int image_set_name ( struct image *image, const char *name ) {
|
|
|
|
strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-01-11 17:04:36 +01:00
|
|
|
#endif /* _GPXE_IMAGE_H */
|