1 /* appleloader.c - apple legacy boot loader. */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2008,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/loader.h>
24 #include <grub/misc.h>
25 #include <grub/efi/api.h>
26 #include <grub/efi/efi.h>
27 #include <grub/command.h>
28 #include <grub/i18n.h>
30 GRUB_MOD_LICENSE ("GPLv3+");
32 static grub_dl_t my_mod
;
34 static grub_efi_handle_t image_handle
;
35 static grub_efi_char16_t
*cmdline
;
38 grub_appleloader_unload (void)
40 grub_efi_boot_services_t
*b
;
42 b
= grub_efi_system_table
->boot_services
;
43 efi_call_1 (b
->unload_image
, image_handle
);
48 grub_dl_unref (my_mod
);
53 grub_appleloader_boot (void)
55 grub_efi_boot_services_t
*b
;
57 b
= grub_efi_system_table
->boot_services
;
58 efi_call_3 (b
->start_image
, image_handle
, 0, 0);
60 grub_appleloader_unload ();
65 struct piwg_full_device_path
67 struct grub_efi_memory_mapped_device_path comp1
;
68 struct grub_efi_piwg_device_path comp2
;
69 struct grub_efi_device_path end
;
72 #define MAKE_PIWG_PATH(st, en) \
77 .type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE, \
78 .subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE, \
79 .length = {sizeof (struct grub_efi_memory_mapped_device_path), 0} \
81 .memory_type = GRUB_EFI_MEMORY_MAPPED_IO, \
82 .start_address = st, \
88 .type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE, \
89 .subtype = GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE, \
90 .length = {sizeof (struct grub_efi_piwg_device_path), 0} \
92 .guid = {0x2B0585EB, 0xD8B8, 0x49A9, {0x8B, 0x8C, 0xE2, 0x1B, \
93 0x01, 0xAE, 0xF2, 0xB7}} \
97 .type = GRUB_EFI_END_DEVICE_PATH_TYPE, \
98 .subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE, \
99 .length = {sizeof (struct grub_efi_device_path), 0} \
103 /* early 2006 Core Duo / Core Solo models */
104 static struct piwg_full_device_path devpath_1
= MAKE_PIWG_PATH (0xffe00000,
107 /* mid-2006 Mac Pro (and probably other Core 2 models) */
108 static struct piwg_full_device_path devpath_2
= MAKE_PIWG_PATH (0xffe00000,
111 /* mid-2007 MBP ("Santa Rosa" based models) */
112 static struct piwg_full_device_path devpath_3
= MAKE_PIWG_PATH (0xffe00000,
116 static struct piwg_full_device_path devpath_4
= MAKE_PIWG_PATH (0xffc00000,
119 /* late-2008 MB/MBP (NVidia chipset) */
120 static struct piwg_full_device_path devpath_5
= MAKE_PIWG_PATH (0xffcb4000,
123 /* mid-2010 MB/MBP (NVidia chipset) */
124 static struct piwg_full_device_path devpath_6
= MAKE_PIWG_PATH (0xffcc4000,
127 static struct piwg_full_device_path devpath_7
= MAKE_PIWG_PATH (0xff981000,
133 grub_efi_device_path_t
*devpath
;
136 struct devdata devs
[] =
138 {"Core Duo/Solo", (grub_efi_device_path_t
*) &devpath_1
},
139 {"Mac Pro", (grub_efi_device_path_t
*) &devpath_2
},
140 {"MBP", (grub_efi_device_path_t
*) &devpath_3
},
141 {"MBA", (grub_efi_device_path_t
*) &devpath_4
},
142 {"MB NV", (grub_efi_device_path_t
*) &devpath_5
},
143 {"MB NV2", (grub_efi_device_path_t
*) &devpath_6
},
144 {"MBP2011", (grub_efi_device_path_t
*) &devpath_7
},
149 grub_cmd_appleloader (grub_command_t cmd
__attribute__ ((unused
)),
150 int argc
, char *argv
[])
152 grub_efi_boot_services_t
*b
;
153 grub_efi_loaded_image_t
*loaded_image
;
154 struct devdata
*pdev
;
156 grub_dl_ref (my_mod
);
158 /* Initialize some global variables. */
161 b
= grub_efi_system_table
->boot_services
;
163 for (pdev
= devs
; pdev
->devpath
; pdev
++)
164 if (efi_call_6 (b
->load_image
, 0, grub_efi_image_handle
, pdev
->devpath
,
165 NULL
, 0, &image_handle
) == GRUB_EFI_SUCCESS
)
170 grub_error (GRUB_ERR_BAD_OS
, "can't find model");
174 grub_dprintf ("appleload", "Model: %s\n", pdev
->model
);
176 loaded_image
= grub_efi_get_loaded_image (image_handle
);
179 grub_error (GRUB_ERR_BAD_OS
, "no loaded image available");
186 grub_efi_char16_t
*p16
;
188 for (i
= 0, len
= 0; i
< argc
; i
++)
189 len
+= grub_strlen (argv
[i
]) + 1;
191 len
*= sizeof (grub_efi_char16_t
);
192 cmdline
= p16
= grub_malloc (len
);
196 for (i
= 0; i
< argc
; i
++)
208 loaded_image
->load_options
= cmdline
;
209 loaded_image
->load_options_size
= len
;
212 grub_loader_set (grub_appleloader_boot
, grub_appleloader_unload
, 0);
218 grub_dl_unref (my_mod
);
222 static grub_command_t cmd
;
224 GRUB_MOD_INIT(appleloader
)
226 cmd
= grub_register_command ("appleloader", grub_cmd_appleloader
,
228 /* TRANSLATORS: This command is used on EFI to
229 switch to BIOS mode and boot the OS requiring
231 N_("Boot BIOS-based system."));
235 GRUB_MOD_FINI(appleloader
)
237 grub_unregister_command (cmd
);