3cb6368e760821ba554e6ad679463c484aab93f7
[people/pcmattman/gpxe.git] / src / image / embedded.c
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 ))
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 = REF_INIT ( 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  */
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 };