#ifndef _GPXE_IMAGE_H #define _GPXE_IMAGE_H /** * @file * * Executable/loadable images * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include #include struct uri; struct image_type; /** An executable or loadable image */ struct image { /** Reference count */ struct refcnt refcnt; /** List of registered images */ struct list_head list; /** URI of image */ struct uri *uri; /** Name */ char name[16]; /** Flags */ unsigned int flags; /** Command line to pass to image */ char *cmdline; /** Raw file image */ userptr_t data; /** Length of raw file image */ size_t len; /** Image type, if known */ struct image_type *type; /** Image type private data */ union { physaddr_t phys; userptr_t user; unsigned long ul; } priv; /** 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 * 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. */ struct image *replacement; }; /** Image is loaded */ #define IMAGE_LOADED 0x0001 /** An executable or loadable image type */ struct image_type { /** Name of this image type */ char *name; /** * Load image into memory * * @v image Executable/loadable image * @ret rc Return status code * * Load the image into memory at the correct location as * determined by the file format. * * 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. */ int ( * load ) ( struct image *image ); /** * Execute loaded image * * @v image Loaded image * @ret rc Return status code * * 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. */ int ( * exec ) ( struct image *image ); }; /** * 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 /** * Normal image probe priority */ #define PROBE_NORMAL 02 /** * PXE image probe priority * * PXE images have no signature checks, so will claim all image files. * They must therefore be tried last in the probe order list. */ #define PROBE_PXE 03 /** Executable or loadable image type table */ #define IMAGE_TYPES __table ( struct image_type, "image_types" ) /** An executable or loadable image type */ #define __image_type( probe_order ) __table_entry ( IMAGE_TYPES, probe_order ) extern struct list_head images; /** Iterate over all registered images */ #define for_each_image( image ) \ list_for_each_entry ( (image), &images, list ) /** * Test for existence of images * * @ret existence Some images exist */ static inline int have_images ( void ) { return ( ! list_empty ( &images ) ); } extern struct image * alloc_image ( void ); extern int image_set_uri ( struct image *image, struct uri *uri ); 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 ); extern void promote_image ( struct image *image ); struct image * find_image ( const char *name ); extern int image_load ( struct image *image ); extern int image_autoload ( struct image *image ); extern int image_exec ( struct image *image ); extern int register_and_autoload_image ( struct image *image ); extern int register_and_autoexec_image ( struct image *image ); /** * 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 ); } /** * 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; } #endif /* _GPXE_IMAGE_H */