Support Apple FAT binaries on non-Apple platforms.
* include/grub/macho.h (GRUB_MACHO_FAT_EFI_MAGIC): New define. * include/grub/i386/macho.h (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT): Likewise. * grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Parse Apple FAT binaries.
This commit is contained in:
parent
4dedb13f51
commit
3e4f356646
4 changed files with 61 additions and 3 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2013-01-10 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Support Apple FAT binaries on non-Apple platforms.
|
||||||
|
|
||||||
|
* include/grub/macho.h (GRUB_MACHO_FAT_EFI_MAGIC): New define.
|
||||||
|
* include/grub/i386/macho.h (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT):
|
||||||
|
Likewise.
|
||||||
|
* grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Parse
|
||||||
|
Apple FAT binaries.
|
||||||
|
|
||||||
2013-01-10 Vladimir Serbinenko <phcoder@gmail.com>
|
2013-01-10 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* grub-core/kern/disk.c (grub_disk_write): Fix sector number on 4K
|
* grub-core/kern/disk.c (grub_disk_write): Fix sector number on 4K
|
||||||
|
|
|
@ -35,6 +35,10 @@
|
||||||
#include <grub/command.h>
|
#include <grub/command.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
#include <grub/net.h>
|
#include <grub/net.h>
|
||||||
|
#if defined (__i386__) || defined (__x86_64__)
|
||||||
|
#include <grub/macho.h>
|
||||||
|
#include <grub/i386/macho.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
|
@ -198,6 +202,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||||
grub_efi_device_path_t *dp = 0;
|
grub_efi_device_path_t *dp = 0;
|
||||||
grub_efi_loaded_image_t *loaded_image;
|
grub_efi_loaded_image_t *loaded_image;
|
||||||
char *filename;
|
char *filename;
|
||||||
|
void *boot_image = 0;
|
||||||
grub_efi_handle_t dev_handle = 0;
|
grub_efi_handle_t dev_handle = 0;
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
|
@ -278,7 +283,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grub_file_read (file, (void *) ((grub_addr_t) address), size) != size)
|
boot_image = (void *) ((grub_addr_t) address);
|
||||||
|
if (grub_file_read (file, boot_image, size) != size)
|
||||||
{
|
{
|
||||||
if (grub_errno == GRUB_ERR_NONE)
|
if (grub_errno == GRUB_ERR_NONE)
|
||||||
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
||||||
|
@ -287,9 +293,45 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined (__i386__) || defined (__x86_64__)
|
||||||
|
if (size >= (grub_ssize_t) sizeof (struct grub_macho_fat_header))
|
||||||
|
{
|
||||||
|
struct grub_macho_fat_header *head = boot_image;
|
||||||
|
if (head->magic
|
||||||
|
== grub_cpu_to_le32_compile_time (GRUB_MACHO_FAT_EFI_MAGIC))
|
||||||
|
{
|
||||||
|
grub_uint32_t i;
|
||||||
|
struct grub_macho_fat_arch *archs
|
||||||
|
= (struct grub_macho_fat_arch *) (head + 1);
|
||||||
|
for (i = 0; i < grub_cpu_to_le32 (head->nfat_arch); i++)
|
||||||
|
{
|
||||||
|
if (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT (archs[i].cputype))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == grub_cpu_to_le32 (head->nfat_arch))
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_OS, "no compatible arch found");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (grub_cpu_to_le32 (archs[i].offset)
|
||||||
|
> ~grub_cpu_to_le32 (archs[i].size)
|
||||||
|
|| grub_cpu_to_le32 (archs[i].offset)
|
||||||
|
+ grub_cpu_to_le32 (archs[i].size)
|
||||||
|
> (grub_size_t) size)
|
||||||
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
||||||
|
filename);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
boot_image = (char *) boot_image + grub_cpu_to_le32 (archs[i].offset);
|
||||||
|
size = grub_cpu_to_le32 (archs[i].size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
|
status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
|
||||||
(void *) ((grub_addr_t) address), size,
|
boot_image, size,
|
||||||
&image_handle);
|
&image_handle);
|
||||||
if (status != GRUB_EFI_SUCCESS)
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
if (status == GRUB_EFI_OUT_OF_RESOURCES)
|
if (status == GRUB_EFI_OUT_OF_RESOURCES)
|
||||||
|
|
|
@ -23,6 +23,11 @@
|
||||||
|
|
||||||
#define GRUB_MACHO_CPUTYPE_IS_HOST32(x) ((x)==0x00000007)
|
#define GRUB_MACHO_CPUTYPE_IS_HOST32(x) ((x)==0x00000007)
|
||||||
#define GRUB_MACHO_CPUTYPE_IS_HOST64(x) ((x)==0x01000007)
|
#define GRUB_MACHO_CPUTYPE_IS_HOST64(x) ((x)==0x01000007)
|
||||||
|
#ifdef __x86_64__
|
||||||
|
#define GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT(x) ((x)==0x01000007)
|
||||||
|
#else
|
||||||
|
#define GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT(x) ((x)==0x00000007)
|
||||||
|
#endif
|
||||||
|
|
||||||
struct grub_macho_thread32
|
struct grub_macho_thread32
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,6 +27,7 @@ struct grub_macho_fat_header
|
||||||
grub_uint32_t nfat_arch;
|
grub_uint32_t nfat_arch;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
#define GRUB_MACHO_FAT_MAGIC 0xcafebabe
|
#define GRUB_MACHO_FAT_MAGIC 0xcafebabe
|
||||||
|
#define GRUB_MACHO_FAT_EFI_MAGIC 0x0ef1fab9
|
||||||
|
|
||||||
typedef grub_uint32_t grub_macho_cpu_type_t;
|
typedef grub_uint32_t grub_macho_cpu_type_t;
|
||||||
typedef grub_uint32_t grub_macho_cpu_subtype_t;
|
typedef grub_uint32_t grub_macho_cpu_subtype_t;
|
||||||
|
|
Loading…
Reference in a new issue