summaryrefslogtreecommitdiffstats
path: root/qemu/roms/ipxe/src/include/ipxe/image.h
blob: 6abd7a2d2f226d192e7a770c9bf70de7bf633a99 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#ifndef _IPXE_IMAGE_H
#define _IPXE_IMAGE_H

/**
 * @file
 *
 * Executable images
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <ipxe/tables.h>
#include <ipxe/list.h>
#include <ipxe/uaccess.h>
#include <ipxe/refcnt.h>

struct uri;
struct pixel_buffer;
struct image_type;

/** An executable 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;
	/** 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;

	/** 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.
	 *
	 * 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 registered */
#define IMAGE_REGISTERED 0x00001

/** Image is selected for execution */
#define IMAGE_SELECTED 0x0002

/** Image is trusted */
#define IMAGE_TRUSTED 0x0004

/** Image will be automatically unregistered after execution */
#define IMAGE_AUTO_UNREGISTER 0x0008

/** An executable image type */
struct image_type {
	/** Name of this image type */
	char *name;
	/**
	 * Probe image
	 *
	 * @v image		Image
	 * @ret rc		Return status code
	 *
	 * Return success if the image is of this image type.
	 */
	int ( * probe ) ( struct image *image );
	/**
	 * Execute image
	 *
	 * @v image		Image
	 * @ret rc		Return status code
	 */
	int ( * exec ) ( struct image *image );
	/**
	 * Create pixel buffer from image
	 *
	 * @v image		Image
	 * @v pixbuf		Pixel buffer to fill in
	 * @ret rc		Return status code
	 */
	int ( * pixbuf ) ( struct image *image, struct pixel_buffer **pixbuf );
};

/**
 * 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 image type table */
#define IMAGE_TYPES __table ( struct image_type, "image_types" )

/** An executable image type */
#define __image_type( probe_order ) __table_entry ( IMAGE_TYPES, probe_order )

extern struct list_head images;
extern struct image *current_image;

/** Iterate over all registered images */
#define for_each_image( image ) \
	list_for_each_entry ( (image), &images, list )

/** Iterate over all registered images, safe against deletion */
#define for_each_image_safe( image, tmp ) \
	list_for_each_entry_safe ( (image), (tmp), &images, list )

/**
 * Test for existence of images
 *
 * @ret existence	Some images exist
 */
static inline int have_images ( void ) {
	return ( ! list_empty ( &images ) );
}

/**
 * Retrieve first image
 *
 * @ret image		Image, or NULL
 */
static inline struct image * first_image ( void ) {
	return list_first_entry ( &images, struct image, list );
}

extern struct image * alloc_image ( struct uri *uri );
extern int image_set_name ( struct image *image, const char *name );
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_exec ( struct image *image );
extern int image_replace ( struct image *replacement );
extern int image_select ( struct image *image );
extern struct image * image_find_selected ( void );
extern int image_set_trust ( int require_trusted, int permanent );
extern int image_pixbuf ( struct image *image, struct pixel_buffer **pixbuf );

/**
 * 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 );
}

/**
 * Clear image command line
 *
 * @v image		Image
 */
static inline void image_clear_cmdline ( struct image *image ) {
	image_set_cmdline ( image, NULL );
}

/**
 * Set image as trusted
 *
 * @v image		Image
 */
static inline void image_trust ( struct image *image ) {
	image->flags |= IMAGE_TRUSTED;
}

/**
 * Set image as untrusted
 *
 * @v image		Image
 */
static inline void image_untrust ( struct image *image ) {
	image->flags &= ~IMAGE_TRUSTED;
}

#endif /* _IPXE_IMAGE_H */