iPXE
embedded.c
Go to the documentation of this file.
00001 /** @file
00002  *
00003  * Embedded image support
00004  *
00005  * Embedded images are images built into the iPXE binary and do not require
00006  * fetching over the network.
00007  */
00008 
00009 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00010 
00011 #include <string.h>
00012 #include <ipxe/image.h>
00013 #include <ipxe/uaccess.h>
00014 #include <ipxe/init.h>
00015 
00016 /* Raw image data for all embedded images */
00017 #undef EMBED
00018 #define EMBED( _index, _path, _name )                                   \
00019         extern char embedded_image_ ## _index ## _data[];               \
00020         extern char embedded_image_ ## _index ## _len[];                \
00021         __asm__ ( ".section \".rodata\", \"a\", " PROGBITS "\n\t"       \
00022                   "\nembedded_image_" #_index "_data:\n\t"              \
00023                   ".incbin \"" _path "\"\n\t"                           \
00024                   "\nembedded_image_" #_index "_end:\n\t"               \
00025                   ".equ embedded_image_" #_index "_len, "               \
00026                         "( embedded_image_" #_index "_end - "           \
00027                         "  embedded_image_" #_index "_data )\n\t"       \
00028                   ".previous\n\t" );
00029 EMBED_ALL
00030 
00031 /* Image structures for all embedded images */
00032 #undef EMBED
00033 #define EMBED( _index, _path, _name ) {                                 \
00034         .refcnt = REF_INIT ( ref_no_free ),                             \
00035         .name = _name,                                                  \
00036         .data = ( userptr_t ) ( embedded_image_ ## _index ## _data ),   \
00037         .len = ( size_t ) embedded_image_ ## _index ## _len,            \
00038 },
00039 static struct image embedded_images[] = {
00040         EMBED_ALL
00041 };
00042 
00043 /**
00044  * Register all embedded images
00045  */
00046 static void embedded_init ( void ) {
00047         int i;
00048         struct image *image;
00049         void *data;
00050         int rc;
00051 
00052         /* Skip if we have no embedded images */
00053         if ( ! sizeof ( embedded_images ) )
00054                 return;
00055 
00056         /* Fix up data pointers and register images */
00057         for ( i = 0 ; i < ( int ) ( sizeof ( embedded_images ) /
00058                                     sizeof ( embedded_images[0] ) ) ; i++ ) {
00059                 image = &embedded_images[i];
00060 
00061                 /* virt_to_user() cannot be used in a static
00062                  * initialiser, so we cast the pointer to a userptr_t
00063                  * in the initialiser and fix it up here.  (This will
00064                  * actually be a no-op on most platforms.)
00065                  */
00066                 data = ( ( void * ) image->data );
00067                 image->data = virt_to_user ( data );
00068 
00069                 DBG ( "Embedded image \"%s\": %zd bytes at %p\n",
00070                       image->name, image->len, data );
00071 
00072                 if ( ( rc = register_image ( image ) ) != 0 ) {
00073                         DBG ( "Could not register embedded image \"%s\": "
00074                               "%s\n", image->name, strerror ( rc ) );
00075                         return;
00076                 }
00077         }
00078 
00079         /* Select the first image */
00080         image = &embedded_images[0];
00081         if ( ( rc = image_select ( image ) ) != 0 ) {
00082                 DBG ( "Could not select embedded image \"%s\": %s\n",
00083                       image->name, strerror ( rc ) );
00084                 return;
00085         }
00086 }
00087 
00088 /** Embedded image initialisation function */
00089 struct init_fn embedded_init_fn __init_fn ( INIT_LATE ) = {
00090         .initialise = embedded_init,
00091 };