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