1 /* Load runtime image of EFIemu. Functions common to 32/64-bit mode */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2009 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <grub/file.h>
23 #include <grub/misc.h>
24 #include <grub/efiemu/efiemu.h>
25 #include <grub/cpu/efiemu.h>
27 /* Are we in 32 or 64-bit mode?*/
28 static grub_efiemu_mode_t grub_efiemu_mode
= GRUB_EFIEMU_NOTLOADED
;
29 /* Runtime ELF file */
30 static grub_ssize_t efiemu_core_size
;
31 static void *efiemu_core
= 0;
32 /* Linked list of segments */
33 static grub_efiemu_segment_t efiemu_segments
= 0;
35 /* equivalent to sizeof (grub_efi_uintn_t) but taking the mode into account*/
37 grub_efiemu_sizeof_uintn_t (void)
39 if (grub_efiemu_mode
== GRUB_EFIEMU32
)
41 if (grub_efiemu_mode
== GRUB_EFIEMU64
)
46 /* Check the header and set mode */
48 grub_efiemu_check_header (void *ehdr
, grub_size_t size
,
49 grub_efiemu_mode_t
*mode
)
51 /* Check the magic numbers. */
52 if ((*mode
== GRUB_EFIEMU_NOTLOADED
|| *mode
== GRUB_EFIEMU32
)
53 && grub_efiemu_check_header32 (ehdr
,size
))
55 *mode
= GRUB_EFIEMU32
;
58 if ((*mode
== GRUB_EFIEMU_NOTLOADED
|| *mode
== GRUB_EFIEMU64
)
59 && grub_efiemu_check_header64 (ehdr
,size
))
61 *mode
= GRUB_EFIEMU64
;
64 return grub_error (GRUB_ERR_BAD_OS
, "invalid ELF magic");
69 grub_efiemu_unload_segs (grub_efiemu_segment_t seg
)
71 grub_efiemu_segment_t segn
;
72 for (; seg
; seg
= segn
)
75 grub_efiemu_mm_return_request (seg
->handle
);
83 grub_efiemu_loadcore_unload(void)
85 switch (grub_efiemu_mode
)
88 grub_efiemu_loadcore_unload32 ();
92 grub_efiemu_loadcore_unload64 ();
99 grub_efiemu_mode
= GRUB_EFIEMU_NOTLOADED
;
101 grub_free (efiemu_core
);
104 grub_efiemu_unload_segs (efiemu_segments
);
107 grub_efiemu_free_syms ();
109 return GRUB_ERR_NONE
;
112 /* Load runtime file and do some initial preparations */
114 grub_efiemu_loadcore_init (grub_file_t file
)
118 efiemu_core_size
= grub_file_size (file
);
120 efiemu_core
= grub_malloc (efiemu_core_size
);
124 if (grub_file_read (file
, efiemu_core
, efiemu_core_size
)
125 != (int) efiemu_core_size
)
127 grub_free (efiemu_core
);
132 if (grub_efiemu_check_header (efiemu_core
, efiemu_core_size
,
135 grub_free (efiemu_core
);
137 return GRUB_ERR_BAD_MODULE
;
140 switch (grub_efiemu_mode
)
143 if ((err
= grub_efiemu_loadcore_init32 (efiemu_core
, efiemu_core_size
,
146 grub_free (efiemu_core
);
148 grub_efiemu_mode
= GRUB_EFIEMU_NOTLOADED
;
154 if ((err
= grub_efiemu_loadcore_init64 (efiemu_core
, efiemu_core_size
,
157 grub_free (efiemu_core
);
159 grub_efiemu_mode
= GRUB_EFIEMU_NOTLOADED
;
165 return grub_error (GRUB_ERR_BAD_OS
, "unknown EFI runtime");
167 return GRUB_ERR_NONE
;
171 grub_efiemu_loadcore_load (void)
174 switch (grub_efiemu_mode
)
177 if ((err
= grub_efiemu_loadcore_load32 (efiemu_core
, efiemu_core_size
,
179 grub_efiemu_loadcore_unload ();
182 if ((err
= grub_efiemu_loadcore_load64 (efiemu_core
, efiemu_core_size
,
184 grub_efiemu_loadcore_unload ();
187 return grub_error (GRUB_ERR_BAD_OS
, "unknown EFI runtime");