• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 
19 FILE_LICENCE ( GPL2_OR_LATER );
20 
21 #include <errno.h>
22 #include <gpxe/efi/efi.h>
23 #include <gpxe/image.h>
24 #include <gpxe/features.h>
25 
26 FEATURE ( FEATURE_IMAGE, "EFI", DHCP_EB_FEATURE_EFI, 1 );
27 
28 struct image_type efi_image_type __image_type ( PROBE_NORMAL );
29 
30 /**
31  * Execute EFI image
32  *
33  * @v image		EFI image
34  * @ret rc		Return status code
35  */
efi_image_exec(struct image * image)36 static int efi_image_exec ( struct image *image ) {
37 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
38 	EFI_HANDLE handle;
39 	UINTN exit_data_size;
40 	CHAR16 *exit_data;
41 	EFI_STATUS efirc;
42 
43 	/* Attempt loading image */
44 	if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, NULL,
45 				       user_to_virt ( image->data, 0 ),
46 				       image->len, &handle ) ) != 0 ) {
47 		/* Not an EFI image */
48 		DBGC ( image, "EFIIMAGE %p could not load: %s\n",
49 		       image, efi_strerror ( efirc ) );
50 		return -ENOEXEC;
51 	}
52 
53 	/* Start the image */
54 	if ( ( efirc = bs->StartImage ( handle, &exit_data_size,
55 					&exit_data ) ) != 0 ) {
56 		DBGC ( image, "EFIIMAGE %p returned with status %s\n",
57 		       image, efi_strerror ( efirc ) );
58 		goto done;
59 	}
60 
61  done:
62 	/* Unload the image.  We can't leave it loaded, because we
63 	 * have no "unload" operation.
64 	 */
65 	bs->UnloadImage ( handle );
66 
67 	return EFIRC_TO_RC ( efirc );
68 }
69 
70 /**
71  * Load EFI image into memory
72  *
73  * @v image		EFI file
74  * @ret rc		Return status code
75  */
efi_image_load(struct image * image)76 static int efi_image_load ( struct image *image ) {
77 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
78 	EFI_HANDLE handle;
79 	EFI_STATUS efirc;
80 
81 	/* Attempt loading image */
82 	if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, NULL,
83 				       user_to_virt ( image->data, 0 ),
84 				       image->len, &handle ) ) != 0 ) {
85 		/* Not an EFI image */
86 		DBGC ( image, "EFIIMAGE %p could not load: %s\n",
87 		       image, efi_strerror ( efirc ) );
88 		return -ENOEXEC;
89 	}
90 
91 	/* This is an EFI image */
92 	if ( ! image->type )
93 		image->type = &efi_image_type;
94 
95 	/* Unload the image.  We can't leave it loaded, because we
96 	 * have no "unload" operation.
97 	 */
98 	bs->UnloadImage ( handle );
99 
100 	return 0;
101 }
102 
103 /** EFI image type */
104 struct image_type efi_image_type __image_type ( PROBE_NORMAL ) = {
105 	.name = "EFI",
106 	.load = efi_image_load,
107 	.exec = efi_image_exec,
108 };
109