This is a long belated reply to an old thread: https://lists.gnu.org/archive/html/grub-devel/2014-01/msg00017.html
I just wanted to note that I made a quick implementation of this a while back for Linux's EFI-stub which may be useful to folks interested in this issue. Revisiting it now since the current 3.18-rc development tree has enough other fixes that using this trick with my particular laptop (MacBookPro11,3) is nearly practical. My current patch is certainly not suitable for upstream but my hunch is that handling quirks like this makes a lot more sense in Linux than GRUB. That would require GRUB to adopt launching Linux via the 'chainloader' command (admittedly I haven't tried this) or the currently unmerged 'linuxefi' command from Fedora: http://lists.gnu.org/archive/html/grub-devel/2014-01/msg00120.html The attached patch for Linux is against 3.18-rc4+ -- Michael Marineau
From 1f2fcbbca18176e2e6c862774428dad878bbac51 Mon Sep 17 00:00:00 2001 From: Michael Marineau <m...@marineau.org> Date: Sun, 30 Mar 2014 13:01:35 -0700 Subject: [PATCH] efi: Identify as OS X to EFI drivers before booting. This prevents the firmware from powering down the integrated graphics card on some recent 2013 Macbook Pro laptops. The trick was originally posted as a command for GRUB2 by Andreas Heider. http://lists.gnu.org/archive/html/grub-devel/2013-12/msg00442.html --- arch/x86/boot/compressed/eboot.c | 62 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 1acf605..419b368 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -1374,6 +1374,66 @@ free_mem_map: return status; } +#define APPLE_SET_OS_PROTOCOL_GUID \ + EFI_GUID(0xc5c5da95, 0x7d5c, 0x45e6, 0xb2, 0xf1, 0x3f, 0xd5, 0x2b, 0xb1, 0x00, 0x77) + +typedef struct { + u64 version; + void (*set_os_version) (const char *os_version); + void (*set_os_vendor) (const char *os_vendor); +} apple_set_os_interface_t; + +static efi_status_t apple_set_os() +{ + apple_set_os_interface_t *set_os; + efi_guid_t set_os_guid = APPLE_SET_OS_PROTOCOL_GUID; + efi_status_t status; + void **handles; + unsigned long i, nr_handles, size = 0; + + status = efi_call_early(locate_handle, EFI_LOCATE_BY_PROTOCOL, + &set_os_guid, NULL, &size, handles); + + if (status == EFI_BUFFER_TOO_SMALL) { + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, + size, &handles); + + if (status != EFI_SUCCESS) + return status; + + status = efi_call_early(locate_handle, EFI_LOCATE_BY_PROTOCOL, + &set_os_guid, NULL, &size, handles); + } + + if (status != EFI_SUCCESS) + goto free_handle; + + nr_handles = size / sizeof(void *); + for (i = 0; i < nr_handles; i++) { + void *h = handles[i]; + + status = efi_call_early(handle_protocol, h, + &set_os_guid, &set_os); + + if (status != EFI_SUCCESS || !set_os) + continue; + + if (set_os->version > 0) { + efi_early->call((unsigned long)set_os->set_os_version, + "Mac OS X 10.9"); + } + + if (set_os->version >= 2) { + efi_early->call((unsigned long)set_os->set_os_vendor, + "Apple Inc."); + } + } + +free_handle: + efi_call_early(free_pool, handles); + return status; +} + /* * On success we return a pointer to a boot_params structure, and NULL * on failure. @@ -1445,6 +1505,8 @@ struct boot_params *efi_main(struct efi_config *c, hdr->code32_start = bzimage_addr; } + apple_set_os(); + status = exit_boot(boot_params, handle, is64); if (status != EFI_SUCCESS) { efi_printk(sys_table, "exit_boot() failed!\n"); -- 2.0.4
_______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel