1 /** @file
2 *
3 * Embedded image support
4 *
5 * Embedded images are images built into the gPXE binary and do not require
6 * fetching over the network.
7 */
8
9 FILE_LICENCE ( GPL2_OR_LATER );
10
11 #include <string.h>
12 #include <gpxe/image.h>
13 #include <gpxe/uaccess.h>
14 #include <gpxe/init.h>
15
16 /**
17 * Free embedded image
18 *
19 * @v refcnt Reference counter
20 */
21 static void __attribute__ (( unused ))
embedded_image_free(struct refcnt * refcnt __unused)22 embedded_image_free ( struct refcnt *refcnt __unused ) {
23 /* Do nothing */
24 }
25
26 /* Raw image data for all embedded images */
27 #undef EMBED
28 #define EMBED( _index, _path, _name ) \
29 extern char embedded_image_ ## _index ## _data[]; \
30 extern char embedded_image_ ## _index ## _len[]; \
31 __asm__ ( ".section \".rodata\", \"a\", @progbits\n\t" \
32 "\nembedded_image_" #_index "_data:\n\t" \
33 ".incbin \"" _path "\"\n\t" \
34 "\nembedded_image_" #_index "_end:\n\t" \
35 ".equ embedded_image_" #_index "_len, " \
36 "( embedded_image_" #_index "_end - " \
37 " embedded_image_" #_index "_data )\n\t" \
38 ".previous\n\t" );
39 EMBED_ALL
40
41 /* Image structures for all embedded images */
42 #undef EMBED
43 #define EMBED( _index, _path, _name ) { \
44 .refcnt = { .free = embedded_image_free, }, \
45 .name = _name, \
46 .data = ( userptr_t ) ( embedded_image_ ## _index ## _data ), \
47 .len = ( size_t ) embedded_image_ ## _index ## _len, \
48 },
49 static struct image embedded_images[] = {
50 EMBED_ALL
51 };
52
53 /**
54 * Register all embedded images
55 */
embedded_init(void)56 static void embedded_init ( void ) {
57 int i;
58 struct image *image;
59 void *data;
60 int rc;
61
62 /* Skip if we have no embedded images */
63 if ( ! sizeof ( embedded_images ) )
64 return;
65
66 /* Fix up data pointers and register images */
67 for ( i = 0 ; i < ( int ) ( sizeof ( embedded_images ) /
68 sizeof ( embedded_images[0] ) ) ; i++ ) {
69 image = &embedded_images[i];
70
71 /* virt_to_user() cannot be used in a static
72 * initialiser, so we cast the pointer to a userptr_t
73 * in the initialiser and fix it up here. (This will
74 * actually be a no-op on most platforms.)
75 */
76 data = ( ( void * ) image->data );
77 image->data = virt_to_user ( data );
78
79 DBG ( "Embedded image \"%s\": %zd bytes at %p\n",
80 image->name, image->len, data );
81
82 if ( ( rc = register_image ( image ) ) != 0 ) {
83 DBG ( "Could not register embedded image \"%s\": "
84 "%s\n", image->name, strerror ( rc ) );
85 return;
86 }
87 }
88
89 /* Load the first image */
90 image = &embedded_images[0];
91 if ( ( rc = image_autoload ( image ) ) != 0 ) {
92 DBG ( "Could not load embedded image \"%s\": %s\n",
93 image->name, strerror ( rc ) );
94 return;
95 }
96 }
97
98 /** Embedded image initialisation function */
99 struct init_fn embedded_init_fn __init_fn ( INIT_NORMAL ) = {
100 .initialise = embedded_init,
101 };
102