Home | History | Annotate | Download | only in image
      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 = { .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  */
     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