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
|
/** @file
*
* Embedded image support
*
* Embedded images are images built into the gPXE binary and do not require
* fetching over the network.
*/
#include <string.h>
#include <gpxe/image.h>
#include <gpxe/uaccess.h>
#include <gpxe/init.h>
/**
* Free embedded image
*
* @v refcnt Reference counter
*/
static void embedded_image_free ( struct refcnt *refcnt __unused ) {
/* Do nothing */
}
/* Raw image data for all embedded images */
#undef EMBED
#define EMBED( _index, _path, _name ) \
extern char embedded_image_ ## _index ## _data[]; \
extern char embedded_image_ ## _index ## _len[]; \
__asm__ ( ".section \".rodata\", \"a\", @progbits\n\t" \
"\nembedded_image_" #_index "_data:\n\t" \
".incbin \"" _path "\"\n\t" \
"\nembedded_image_" #_index "_end:\n\t" \
".equ embedded_image_" #_index "_len, " \
"( embedded_image_" #_index "_end - " \
" embedded_image_" #_index "_data )\n\t" \
".previous\n\t" );
EMBED_ALL
/* Image structures for all embedded images */
#undef EMBED
#define EMBED( _index, _path, _name ) { \
.refcnt = { .free = embedded_image_free, }, \
.name = _name, \
.data = ( userptr_t ) ( embedded_image_ ## _index ## _data ), \
.len = ( size_t ) embedded_image_ ## _index ## _len, \
},
static struct image embedded_images[] = {
EMBED_ALL
};
/**
* Register all embedded images
*/
static void embedded_init ( void ) {
unsigned int i;
struct image *image;
void *data;
int rc;
/* Fix up data pointers and register images */
for ( i = 0 ; i < ( sizeof ( embedded_images ) /
sizeof ( embedded_images[0] ) ) ; i++ ) {
image = &embedded_images[i];
/* virt_to_user() cannot be used in a static
* initialiser, so we cast the pointer to a userptr_t
* in the initialiser and fix it up here. (This will
* actually be a no-op on most platforms.)
*/
data = ( ( void * ) image->data );
image->data = virt_to_user ( data );
DBG ( "Embedded image \"%s\": %zd bytes at %p\n",
image->name, image->len, data );
if ( ( rc = register_image ( image ) ) != 0 ) {
DBG ( "Could not register embedded image \"%s\": "
"%s\n", image->name, strerror ( rc ) );
return;
}
}
/* Load the first image */
image = &embedded_images[0];
if ( ( rc = image_autoload ( image ) ) != 0 ) {
DBG ( "Could not load embedded image \"%s\": %s\n",
image->name, strerror ( rc ) );
return;
}
}
/** Embedded image initialisation function */
struct init_fn embedded_init_fn __init_fn ( INIT_NORMAL ) = {
.initialise = embedded_init,
};
|