176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifndef _GPXE_IMAGE_H 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define _GPXE_IMAGE_H 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @file 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Executable/loadable images 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1176d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( GPL2_OR_LATER ); 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/tables.h> 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/list.h> 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/uaccess.h> 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#include <gpxe/refcnt.h> 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct uri; 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct image_type; 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** An executable or loadable image */ 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct image { 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** Reference count */ 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct refcnt refcnt; 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** List of registered images */ 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct list_head list; 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** URI of image */ 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct uri *uri; 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** Name */ 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char name[16]; 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** Flags */ 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned int flags; 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** Command line to pass to image */ 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char *cmdline; 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** Raw file image */ 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman userptr_t data; 4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** Length of raw file image */ 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size_t len; 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** Image type, if known */ 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct image_type *type; 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** Image type private data */ 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman union { 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman physaddr_t phys; 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman userptr_t user; 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman unsigned long ul; 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman } priv; 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** Replacement image 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * An image wishing to replace itself with another image (in a 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * style similar to a Unix exec() call) should return from its 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * exec() method with the replacement image set to point to 5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * the new image. The new image must already be in a suitable 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * state for execution (i.e. loaded). 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * If an image unregisters itself as a result of being 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * executed, it must make sure that its replacement image (if 6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * any) is registered, otherwise the replacement is likely to 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * be freed before it can be executed. 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman struct image *replacement; 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Image is loaded */ 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define IMAGE_LOADED 0x0001 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** An executable or loadable image type */ 7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct image_type { 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** Name of this image type */ 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman char *name; 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Load image into memory 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v image Executable/loadable image 7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Load the image into memory at the correct location as 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * determined by the file format. 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * If the file image is in the correct format, the method must 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * update @c image->type to point to its own type (unless @c 8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * image->type is already set). This allows the autoloading 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * code to disambiguate between "this is not my image format" 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * and "there is something wrong with this image". In 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * particular, setting @c image->type and then returning an 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * error will cause image_autoload() to abort and return an 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * error, rather than continuing to the next image type. 9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int ( * load ) ( struct image *image ); 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman /** 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Execute loaded image 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v image Loaded image 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Note that the image may be invalidated by the act of 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * execution, i.e. an image is allowed to choose to unregister 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * (and so potentially free) itself. 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int ( * exec ) ( struct image *image ); 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman}; 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Multiboot image probe priority 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Multiboot images are also valid executables in another format 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * (e.g. ELF), so we must perform the multiboot probe first. 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PROBE_MULTIBOOT 01 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Normal image probe priority 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PROBE_NORMAL 02 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * PXE image probe priority 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * PXE images have no signature checks, so will claim all image files. 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * They must therefore be tried last in the probe order list. 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PROBE_PXE 03 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Executable or loadable image type table */ 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define IMAGE_TYPES __table ( struct image_type, "image_types" ) 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** An executable or loadable image type */ 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __image_type( probe_order ) __table_entry ( IMAGE_TYPES, probe_order ) 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern struct list_head images; 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** Iterate over all registered images */ 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define for_each_image( image ) \ 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman list_for_each_entry ( (image), &images, list ) 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Test for existence of images 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret existence Some images exist 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline int have_images ( void ) { 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ( ! list_empty ( &images ) ); 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern struct image * alloc_image ( void ); 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int image_set_uri ( struct image *image, struct uri *uri ); 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int image_set_cmdline ( struct image *image, const char *cmdline ); 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int register_image ( struct image *image ); 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void unregister_image ( struct image *image ); 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void promote_image ( struct image *image ); 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstruct image * find_image ( const char *name ); 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int image_load ( struct image *image ); 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int image_autoload ( struct image *image ); 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int image_exec ( struct image *image ); 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int register_and_autoload_image ( struct image *image ); 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern int register_and_autoexec_image ( struct image *image ); 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Increment reference count on an image 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v image Image 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret image Image 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline struct image * image_get ( struct image *image ) { 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ref_get ( &image->refcnt ); 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return image; 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Decrement reference count on an image 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v image Image 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline void image_put ( struct image *image ) { 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ref_put ( &image->refcnt ); 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Set image name 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v image Image 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v name New image name 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret rc Return status code 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline int image_set_name ( struct image *image, const char *name ) { 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) ); 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return 0; 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* _GPXE_IMAGE_H */ 195