diff options
Diffstat (limited to 'contrib/syslinux-4.02/gpxe/src/image/embedded.c')
-rw-r--r-- | contrib/syslinux-4.02/gpxe/src/image/embedded.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/gpxe/src/image/embedded.c b/contrib/syslinux-4.02/gpxe/src/image/embedded.c new file mode 100644 index 0000000..58a14ea --- /dev/null +++ b/contrib/syslinux-4.02/gpxe/src/image/embedded.c @@ -0,0 +1,101 @@ +/** @file + * + * Embedded image support + * + * Embedded images are images built into the gPXE binary and do not require + * fetching over the network. + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <string.h> +#include <gpxe/image.h> +#include <gpxe/uaccess.h> +#include <gpxe/init.h> + +/** + * Free embedded image + * + * @v refcnt Reference counter + */ +static void __attribute__ (( unused )) +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 ) { + int i; + struct image *image; + void *data; + int rc; + + /* Skip if we have no embedded images */ + if ( ! sizeof ( embedded_images ) ) + return; + + /* Fix up data pointers and register images */ + for ( i = 0 ; i < ( int ) ( 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, +}; |