1#ifndef _GPXE_IMAGE_H
2#define _GPXE_IMAGE_H
3
4/**
5 * @file
6 *
7 * Executable/loadable images
8 *
9 */
10
11FILE_LICENCE ( GPL2_OR_LATER );
12
13#include <gpxe/tables.h>
14#include <gpxe/list.h>
15#include <gpxe/uaccess.h>
16#include <gpxe/refcnt.h>
17
18struct uri;
19struct image_type;
20
21/** An executable or loadable image */
22struct image {
23	/** Reference count */
24	struct refcnt refcnt;
25
26	/** List of registered images */
27	struct list_head list;
28
29	/** URI of image */
30	struct uri *uri;
31	/** Name */
32	char name[16];
33	/** Flags */
34	unsigned int flags;
35
36	/** Command line to pass to image */
37	char *cmdline;
38	/** Raw file image */
39	userptr_t data;
40	/** Length of raw file image */
41	size_t len;
42
43	/** Image type, if known */
44	struct image_type *type;
45	/** Image type private data */
46	union {
47		physaddr_t phys;
48		userptr_t user;
49		unsigned long ul;
50	} priv;
51
52	/** Replacement image
53	 *
54	 * An image wishing to replace itself with another image (in a
55	 * style similar to a Unix exec() call) should return from its
56	 * exec() method with the replacement image set to point to
57	 * the new image.  The new image must already be in a suitable
58	 * state for execution (i.e. loaded).
59	 *
60	 * If an image unregisters itself as a result of being
61	 * executed, it must make sure that its replacement image (if
62	 * any) is registered, otherwise the replacement is likely to
63	 * be freed before it can be executed.
64	 */
65	struct image *replacement;
66};
67
68/** Image is loaded */
69#define IMAGE_LOADED 0x0001
70
71/** An executable or loadable image type */
72struct image_type {
73	/** Name of this image type */
74	char *name;
75	/**
76	 * Load image into memory
77	 *
78	 * @v image		Executable/loadable image
79	 * @ret rc		Return status code
80	 *
81	 * Load the image into memory at the correct location as
82	 * determined by the file format.
83	 *
84	 * If the file image is in the correct format, the method must
85	 * update @c image->type to point to its own type (unless @c
86	 * image->type is already set).  This allows the autoloading
87	 * code to disambiguate between "this is not my image format"
88	 * and "there is something wrong with this image".  In
89	 * particular, setting @c image->type and then returning an
90	 * error will cause image_autoload() to abort and return an
91	 * error, rather than continuing to the next image type.
92	 */
93	int ( * load ) ( struct image *image );
94	/**
95	 * Execute loaded image
96	 *
97	 * @v image		Loaded image
98	 * @ret rc		Return status code
99	 *
100	 * Note that the image may be invalidated by the act of
101	 * execution, i.e. an image is allowed to choose to unregister
102	 * (and so potentially free) itself.
103	 */
104	int ( * exec ) ( struct image *image );
105};
106
107/**
108 * Multiboot image probe priority
109 *
110 * Multiboot images are also valid executables in another format
111 * (e.g. ELF), so we must perform the multiboot probe first.
112 */
113#define PROBE_MULTIBOOT	01
114
115/**
116 * Normal image probe priority
117 */
118#define PROBE_NORMAL 02
119
120/**
121 * PXE image probe priority
122 *
123 * PXE images have no signature checks, so will claim all image files.
124 * They must therefore be tried last in the probe order list.
125 */
126#define PROBE_PXE 03
127
128/** Executable or loadable image type table */
129#define IMAGE_TYPES __table ( struct image_type, "image_types" )
130
131/** An executable or loadable image type */
132#define __image_type( probe_order ) __table_entry ( IMAGE_TYPES, probe_order )
133
134extern struct list_head images;
135
136/** Iterate over all registered images */
137#define for_each_image( image ) \
138	list_for_each_entry ( (image), &images, list )
139
140/**
141 * Test for existence of images
142 *
143 * @ret existence	Some images exist
144 */
145static inline int have_images ( void ) {
146	return ( ! list_empty ( &images ) );
147}
148
149extern struct image * alloc_image ( void );
150extern int image_set_uri ( struct image *image, struct uri *uri );
151extern int image_set_cmdline ( struct image *image, const char *cmdline );
152extern int register_image ( struct image *image );
153extern void unregister_image ( struct image *image );
154extern void promote_image ( struct image *image );
155struct image * find_image ( const char *name );
156extern int image_load ( struct image *image );
157extern int image_autoload ( struct image *image );
158extern int image_exec ( struct image *image );
159extern int register_and_autoload_image ( struct image *image );
160extern int register_and_autoexec_image ( struct image *image );
161
162/**
163 * Increment reference count on an image
164 *
165 * @v image		Image
166 * @ret image		Image
167 */
168static inline struct image * image_get ( struct image *image ) {
169	ref_get ( &image->refcnt );
170	return image;
171}
172
173/**
174 * Decrement reference count on an image
175 *
176 * @v image		Image
177 */
178static inline void image_put ( struct image *image ) {
179	ref_put ( &image->refcnt );
180}
181
182/**
183 * Set image name
184 *
185 * @v image		Image
186 * @v name		New image name
187 * @ret rc		Return status code
188 */
189static inline int image_set_name ( struct image *image, const char *name ) {
190	strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) );
191	return 0;
192}
193
194#endif /* _GPXE_IMAGE_H */
195