Implement better integration with Mac firmware.
This commit is contained in:
parent
1f032575bb
commit
b8765fa082
15 changed files with 835 additions and 39 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
2013-12-17 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Implement better integration with Mac firmware.
|
||||||
|
|
||||||
2013-12-17 Vladimir Serbinenko <phcoder@gmail.com>
|
2013-12-17 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* grub-core/loader/multiboot_mbi2.c: Implement special value for
|
* grub-core/loader/multiboot_mbi2.c: Implement special value for
|
||||||
|
|
|
@ -62,6 +62,7 @@ library = {
|
||||||
common_nodist = grub_script.tab.h;
|
common_nodist = grub_script.tab.h;
|
||||||
|
|
||||||
common = grub-core/commands/blocklist.c;
|
common = grub-core/commands/blocklist.c;
|
||||||
|
common = grub-core/commands/macbless.c;
|
||||||
common = grub-core/commands/xnu_uuid.c;
|
common = grub-core/commands/xnu_uuid.c;
|
||||||
common = grub-core/commands/testload.c;
|
common = grub-core/commands/testload.c;
|
||||||
common = grub-core/commands/ls.c;
|
common = grub-core/commands/ls.c;
|
||||||
|
@ -401,6 +402,21 @@ program = {
|
||||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
program = {
|
||||||
|
name = grub-macbless;
|
||||||
|
installdir = sbin;
|
||||||
|
mansection = 1;
|
||||||
|
common = util/grub-macbless.c;
|
||||||
|
common = grub-core/osdep/init.c;
|
||||||
|
common = grub-core/kern/emu/argp_common.c;
|
||||||
|
|
||||||
|
ldadd = libgrubmods.a;
|
||||||
|
ldadd = libgrubgcry.a;
|
||||||
|
ldadd = libgrubkern.a;
|
||||||
|
ldadd = grub-core/gnulib/libgnu.a;
|
||||||
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
||||||
|
};
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
common = util/grub.d/README;
|
common = util/grub.d/README;
|
||||||
installdir = grubconf;
|
installdir = grubconf;
|
||||||
|
@ -585,6 +601,9 @@ program = {
|
||||||
common = grub-core/osdep/blocklist.c;
|
common = grub-core/osdep/blocklist.c;
|
||||||
common = grub-core/osdep/config.c;
|
common = grub-core/osdep/config.c;
|
||||||
common = util/config.c;
|
common = util/config.c;
|
||||||
|
common = util/render-label.c;
|
||||||
|
common = grub-core/kern/emu/hostfs.c;
|
||||||
|
common = grub-core/disk/host.c;
|
||||||
|
|
||||||
common = util/resolve.c;
|
common = util/resolve.c;
|
||||||
enable = noemu;
|
enable = noemu;
|
||||||
|
|
4
docs/man/grub-macbless.h2m
Normal file
4
docs/man/grub-macbless.h2m
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[NAME]
|
||||||
|
grub-macbless \- bless a mac file/directory
|
||||||
|
[SEE ALSO]
|
||||||
|
.BR grub-install (1)
|
|
@ -1450,6 +1450,11 @@ module = {
|
||||||
common = fs/zfs/zfsinfo.c;
|
common = fs/zfs/zfsinfo.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = macbless;
|
||||||
|
common = commands/macbless.c;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = pxe;
|
name = pxe;
|
||||||
i386_pc = net/drivers/i386/pc/pxe.c;
|
i386_pc = net/drivers/i386/pc/pxe.c;
|
||||||
|
|
234
grub-core/commands/macbless.c
Normal file
234
grub-core/commands/macbless.c
Normal file
|
@ -0,0 +1,234 @@
|
||||||
|
/* hfspbless.c - set the hfs+ boot directory. */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2003,2005,2007,2008,2009,2012,2013 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <grub/command.h>
|
||||||
|
#include <grub/fs.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <grub/device.h>
|
||||||
|
#include <grub/disk.h>
|
||||||
|
#include <grub/hfsplus.h>
|
||||||
|
#include <grub/hfs.h>
|
||||||
|
#include <grub/partition.h>
|
||||||
|
#include <grub/file.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/err.h>
|
||||||
|
|
||||||
|
struct find_node_context
|
||||||
|
{
|
||||||
|
grub_uint64_t inode_found;
|
||||||
|
char *dirname;
|
||||||
|
enum
|
||||||
|
{ NONE, FILE, DIR } found;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
find_inode (const char *filename,
|
||||||
|
const struct grub_dirhook_info *info, void *data)
|
||||||
|
{
|
||||||
|
struct find_node_context *ctx = data;
|
||||||
|
if (!info->inodeset)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((grub_strcmp (ctx->dirname, filename) == 0
|
||||||
|
|| (info->case_insensitive
|
||||||
|
&& grub_strcasecmp (ctx->dirname, filename) == 0)))
|
||||||
|
{
|
||||||
|
ctx->inode_found = info->inode;
|
||||||
|
ctx->found = info->dir ? DIR : FILE;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_mac_bless_inode (grub_device_t dev, grub_uint64_t inode, int is_dir,
|
||||||
|
int intel)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct grub_hfs_sblock hfs;
|
||||||
|
struct grub_hfsplus_volheader hfsplus;
|
||||||
|
} volheader;
|
||||||
|
grub_disk_addr_t embedded_offset;
|
||||||
|
|
||||||
|
if (intel && is_dir)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
"can't bless a directory for mactel");
|
||||||
|
if (!intel && !is_dir)
|
||||||
|
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||||
|
"can't bless a file for mac PPC");
|
||||||
|
|
||||||
|
/* Read the bootblock. */
|
||||||
|
err = grub_disk_read (dev->disk, GRUB_HFSPLUS_SBLOCK, 0, sizeof (volheader),
|
||||||
|
(char *) &volheader);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
embedded_offset = 0;
|
||||||
|
if (grub_be_to_cpu16 (volheader.hfs.magic) == GRUB_HFS_MAGIC)
|
||||||
|
{
|
||||||
|
int extent_start;
|
||||||
|
int ablk_size;
|
||||||
|
int ablk_start;
|
||||||
|
|
||||||
|
/* See if there's an embedded HFS+ filesystem. */
|
||||||
|
if (grub_be_to_cpu16 (volheader.hfs.embed_sig) != GRUB_HFSPLUS_MAGIC)
|
||||||
|
{
|
||||||
|
if (intel)
|
||||||
|
volheader.hfs.intel_bootfile = grub_be_to_cpu32 (inode);
|
||||||
|
else
|
||||||
|
volheader.hfs.ppc_bootdir = grub_be_to_cpu32 (inode);
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the offset needed to translate HFS+ sector numbers. */
|
||||||
|
extent_start =
|
||||||
|
grub_be_to_cpu16 (volheader.hfs.embed_extent.first_block);
|
||||||
|
ablk_size = grub_be_to_cpu32 (volheader.hfs.blksz);
|
||||||
|
ablk_start = grub_be_to_cpu16 (volheader.hfs.first_block);
|
||||||
|
embedded_offset = (ablk_start
|
||||||
|
+ extent_start
|
||||||
|
* (ablk_size >> GRUB_DISK_SECTOR_BITS));
|
||||||
|
|
||||||
|
err =
|
||||||
|
grub_disk_read (dev->disk, embedded_offset + GRUB_HFSPLUS_SBLOCK, 0,
|
||||||
|
sizeof (volheader), (char *) &volheader);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((grub_be_to_cpu16 (volheader.hfsplus.magic) != GRUB_HFSPLUS_MAGIC)
|
||||||
|
&& (grub_be_to_cpu16 (volheader.hfsplus.magic) != GRUB_HFSPLUSX_MAGIC))
|
||||||
|
return grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem");
|
||||||
|
if (intel)
|
||||||
|
volheader.hfsplus.intel_bootfile = grub_be_to_cpu32 (inode);
|
||||||
|
else
|
||||||
|
volheader.hfsplus.ppc_bootdir = grub_be_to_cpu32 (inode);
|
||||||
|
|
||||||
|
return grub_disk_write (dev->disk, embedded_offset + GRUB_HFSPLUS_SBLOCK, 0,
|
||||||
|
sizeof (volheader), (char *) &volheader);
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_err_t
|
||||||
|
grub_mac_bless_file (grub_device_t dev, const char *path_in, int intel)
|
||||||
|
{
|
||||||
|
grub_fs_t fs;
|
||||||
|
|
||||||
|
char *path, *tail;
|
||||||
|
struct find_node_context ctx;
|
||||||
|
|
||||||
|
fs = grub_fs_probe (dev);
|
||||||
|
if (!fs || (grub_strcmp (fs->name, "hfsplus") != 0
|
||||||
|
&& grub_strcmp (fs->name, "hfs") != 0))
|
||||||
|
return grub_error (GRUB_ERR_BAD_FS, "no suitable FS found");
|
||||||
|
|
||||||
|
path = grub_strdup (path_in);
|
||||||
|
if (!path)
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
tail = path + grub_strlen (path) - 1;
|
||||||
|
|
||||||
|
/* Remove trailing '/'. */
|
||||||
|
while (tail != path && *tail == '/')
|
||||||
|
*(tail--) = 0;
|
||||||
|
|
||||||
|
tail = grub_strrchr (path, '/');
|
||||||
|
ctx.found = 0;
|
||||||
|
|
||||||
|
if (tail)
|
||||||
|
{
|
||||||
|
*tail = 0;
|
||||||
|
ctx.dirname = tail + 1;
|
||||||
|
|
||||||
|
(fs->dir) (dev, *path == 0 ? "/" : path, find_inode, &ctx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ctx.dirname = path + 1;
|
||||||
|
(fs->dir) (dev, "/", find_inode, &ctx);
|
||||||
|
}
|
||||||
|
if (!ctx.found)
|
||||||
|
{
|
||||||
|
grub_free (path);
|
||||||
|
return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file `%s' not found"),
|
||||||
|
path_in);
|
||||||
|
}
|
||||||
|
grub_free (path);
|
||||||
|
|
||||||
|
return grub_mac_bless_inode (dev, ctx.inode_found, (ctx.found == DIR),
|
||||||
|
intel);
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
grub_cmd_macbless (grub_command_t cmd, int argc, char **args)
|
||||||
|
{
|
||||||
|
char *device_name;
|
||||||
|
char *path = 0;
|
||||||
|
grub_device_t dev;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
if (argc != 1)
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
|
||||||
|
device_name = grub_file_get_device_name (args[0]);
|
||||||
|
dev = grub_device_open (device_name);
|
||||||
|
|
||||||
|
path = grub_strchr (args[0], ')');
|
||||||
|
if (!path)
|
||||||
|
path = args[0];
|
||||||
|
else
|
||||||
|
path = path + 1;
|
||||||
|
|
||||||
|
if (!path || *path == 0 || !device_name)
|
||||||
|
{
|
||||||
|
if (dev)
|
||||||
|
grub_device_close (dev);
|
||||||
|
|
||||||
|
grub_free (device_name);
|
||||||
|
grub_free (path);
|
||||||
|
|
||||||
|
return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
|
||||||
|
}
|
||||||
|
|
||||||
|
err = grub_mac_bless_file (dev, path, cmd->name[3] == 't');
|
||||||
|
|
||||||
|
grub_device_close (dev);
|
||||||
|
grub_free (device_name);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_command_t cmd, cmd_ppc;
|
||||||
|
|
||||||
|
GRUB_MOD_INIT(macbless)
|
||||||
|
{
|
||||||
|
cmd = grub_register_command ("mactelbless", grub_cmd_macbless,
|
||||||
|
N_("FILE"),
|
||||||
|
N_
|
||||||
|
("Bless FILE of HFS or HFS+ partition for intel macs."));
|
||||||
|
cmd_ppc =
|
||||||
|
grub_register_command ("macppcbless", grub_cmd_macbless, N_("DIR"),
|
||||||
|
N_
|
||||||
|
("Bless DIR of HFS or HFS+ partition for PPC macs."));
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_FINI(macbless)
|
||||||
|
{
|
||||||
|
grub_unregister_command (cmd);
|
||||||
|
grub_unregister_command (cmd_ppc);
|
||||||
|
}
|
|
@ -1229,14 +1229,18 @@ grub_hfs_dir_hook (struct grub_hfs_record *rec, void *hook_arg)
|
||||||
{
|
{
|
||||||
info.dir = 1;
|
info.dir = 1;
|
||||||
info.mtimeset = 1;
|
info.mtimeset = 1;
|
||||||
|
info.inodeset = 1;
|
||||||
info.mtime = grub_be_to_cpu32 (drec->mtime) - 2082844800;
|
info.mtime = grub_be_to_cpu32 (drec->mtime) - 2082844800;
|
||||||
|
info.inode = grub_be_to_cpu32 (drec->dirid);
|
||||||
return ctx->hook (fname, &info, ctx->hook_data);
|
return ctx->hook (fname, &info, ctx->hook_data);
|
||||||
}
|
}
|
||||||
if (frec->type == GRUB_HFS_FILETYPE_FILE)
|
if (frec->type == GRUB_HFS_FILETYPE_FILE)
|
||||||
{
|
{
|
||||||
info.dir = 0;
|
info.dir = 0;
|
||||||
info.mtimeset = 1;
|
info.mtimeset = 1;
|
||||||
|
info.inodeset = 1;
|
||||||
info.mtime = grub_be_to_cpu32 (frec->mtime) - 2082844800;
|
info.mtime = grub_be_to_cpu32 (frec->mtime) - 2082844800;
|
||||||
|
info.inode = grub_be_to_cpu32 (frec->fileid);
|
||||||
return ctx->hook (fname, &info, ctx->hook_data);
|
return ctx->hook (fname, &info, ctx->hook_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,11 +34,6 @@
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
#define GRUB_HFSPLUS_MAGIC 0x482B
|
|
||||||
#define GRUB_HFSPLUSX_MAGIC 0x4858
|
|
||||||
#define GRUB_HFSPLUS_SBLOCK 2
|
|
||||||
|
|
||||||
|
|
||||||
/* The type of node. */
|
/* The type of node. */
|
||||||
enum grub_hfsplus_btnode_type
|
enum grub_hfsplus_btnode_type
|
||||||
{
|
{
|
||||||
|
@ -919,6 +914,8 @@ grub_hfsplus_dir_iter (const char *filename,
|
||||||
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
|
||||||
info.mtimeset = 1;
|
info.mtimeset = 1;
|
||||||
info.mtime = node->mtime;
|
info.mtime = node->mtime;
|
||||||
|
info.inodeset = 1;
|
||||||
|
info.inode = node->fileid;
|
||||||
info.case_insensitive = !! (filetype & GRUB_FSHELP_CASE_INSENSITIVE);
|
info.case_insensitive = !! (filetype & GRUB_FSHELP_CASE_INSENSITIVE);
|
||||||
grub_free (node);
|
grub_free (node);
|
||||||
return ctx->hook (filename, &info, ctx->hook_data);
|
return ctx->hook (filename, &info, ctx->hook_data);
|
||||||
|
|
|
@ -38,7 +38,9 @@ struct grub_dirhook_info
|
||||||
unsigned dir:1;
|
unsigned dir:1;
|
||||||
unsigned mtimeset:1;
|
unsigned mtimeset:1;
|
||||||
unsigned case_insensitive:1;
|
unsigned case_insensitive:1;
|
||||||
|
unsigned inodeset:1;
|
||||||
grub_int32_t mtime;
|
grub_int32_t mtime;
|
||||||
|
grub_uint64_t inode;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*grub_fs_dir_hook_t) (const char *filename,
|
typedef int (*grub_fs_dir_hook_t) (const char *filename,
|
||||||
|
|
|
@ -50,11 +50,20 @@ struct grub_hfs_sblock
|
||||||
/* A pascal style string that holds the volumename. */
|
/* A pascal style string that holds the volumename. */
|
||||||
grub_uint8_t volname[28];
|
grub_uint8_t volname[28];
|
||||||
|
|
||||||
grub_uint8_t unused5[52];
|
grub_uint8_t unused5[28];
|
||||||
|
|
||||||
|
grub_uint32_t ppc_bootdir;
|
||||||
|
grub_uint32_t intel_bootfile;
|
||||||
|
/* Folder opened when disk is mounted. Unused by GRUB. */
|
||||||
|
grub_uint32_t showfolder;
|
||||||
|
grub_uint32_t os9folder;
|
||||||
|
grub_uint8_t unused6[4];
|
||||||
|
grub_uint32_t osxfolder;
|
||||||
|
|
||||||
grub_uint64_t num_serial;
|
grub_uint64_t num_serial;
|
||||||
grub_uint16_t embed_sig;
|
grub_uint16_t embed_sig;
|
||||||
struct grub_hfs_extent embed_extent;
|
struct grub_hfs_extent embed_extent;
|
||||||
grub_uint8_t unused6[4];
|
grub_uint8_t unused7[4];
|
||||||
grub_hfs_datarecord_t extent_recs;
|
grub_hfs_datarecord_t extent_recs;
|
||||||
grub_uint32_t catalog_size;
|
grub_uint32_t catalog_size;
|
||||||
grub_hfs_datarecord_t catalog_recs;
|
grub_hfs_datarecord_t catalog_recs;
|
||||||
|
|
|
@ -1,7 +1,28 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2005,2006,2007,2008,2009,2012,2013 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <grub/types.h>
|
#include <grub/types.h>
|
||||||
#include <grub/disk.h>
|
#include <grub/disk.h>
|
||||||
|
|
||||||
|
#define GRUB_HFSPLUS_MAGIC 0x482B
|
||||||
|
#define GRUB_HFSPLUSX_MAGIC 0x4858
|
||||||
|
#define GRUB_HFSPLUS_SBLOCK 2
|
||||||
|
|
||||||
/* A HFS+ extent. */
|
/* A HFS+ extent. */
|
||||||
struct grub_hfsplus_extent
|
struct grub_hfsplus_extent
|
||||||
{
|
{
|
||||||
|
@ -30,7 +51,16 @@ struct grub_hfsplus_volheader
|
||||||
grub_uint32_t utime;
|
grub_uint32_t utime;
|
||||||
grub_uint8_t unused2[16];
|
grub_uint8_t unused2[16];
|
||||||
grub_uint32_t blksize;
|
grub_uint32_t blksize;
|
||||||
grub_uint8_t unused3[60];
|
grub_uint8_t unused3[36];
|
||||||
|
|
||||||
|
grub_uint32_t ppc_bootdir;
|
||||||
|
grub_uint32_t intel_bootfile;
|
||||||
|
/* Folder opened when disk is mounted. Unused by GRUB. */
|
||||||
|
grub_uint32_t showfolder;
|
||||||
|
grub_uint32_t os9folder;
|
||||||
|
grub_uint8_t unused4[4];
|
||||||
|
grub_uint32_t osxfolder;
|
||||||
|
|
||||||
grub_uint64_t num_serial;
|
grub_uint64_t num_serial;
|
||||||
struct grub_hfsplus_forkdata allocations_file;
|
struct grub_hfsplus_forkdata allocations_file;
|
||||||
struct grub_hfsplus_forkdata extents_file;
|
struct grub_hfsplus_forkdata extents_file;
|
||||||
|
@ -216,3 +246,8 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
|
||||||
struct grub_hfsplus_key_internal *keyb),
|
struct grub_hfsplus_key_internal *keyb),
|
||||||
struct grub_hfsplus_btnode **matchnode,
|
struct grub_hfsplus_btnode **matchnode,
|
||||||
grub_off_t *keyoffset);
|
grub_off_t *keyoffset);
|
||||||
|
grub_err_t
|
||||||
|
grub_mac_bless_inode (grub_device_t dev, grub_uint64_t inode, int is_dir,
|
||||||
|
int intel);
|
||||||
|
grub_err_t
|
||||||
|
grub_mac_bless_file (grub_device_t dev, const char *path_in, int intel);
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <grub/gpt_partition.h>
|
#include <grub/gpt_partition.h>
|
||||||
#include <grub/emu/config.h>
|
#include <grub/emu/config.h>
|
||||||
#include <grub/util/ofpath.h>
|
#include <grub/util/ofpath.h>
|
||||||
|
#include <grub/hfsplus.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ static int allow_floppy = 0;
|
||||||
static int force_file_id = 0;
|
static int force_file_id = 0;
|
||||||
static char *disk_module = NULL;
|
static char *disk_module = NULL;
|
||||||
static char *efidir = NULL;
|
static char *efidir = NULL;
|
||||||
|
static char *macppcdir = NULL;
|
||||||
static int force = 0;
|
static int force = 0;
|
||||||
static int have_abstractions = 0;
|
static int have_abstractions = 0;
|
||||||
static int have_cryptodisk = 0;
|
static int have_cryptodisk = 0;
|
||||||
|
@ -68,6 +70,10 @@ static int have_load_cfg = 0;
|
||||||
static FILE * load_cfg_f = NULL;
|
static FILE * load_cfg_f = NULL;
|
||||||
static char *load_cfg;
|
static char *load_cfg;
|
||||||
static int install_bootsector = 1;
|
static int install_bootsector = 1;
|
||||||
|
static char *label_font;
|
||||||
|
static char *label_color;
|
||||||
|
static char *label_bgcolor;
|
||||||
|
static char *product_version;
|
||||||
static int add_rs_codes = 1;
|
static int add_rs_codes = 1;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -96,6 +102,11 @@ enum
|
||||||
OPTION_DISK_MODULE,
|
OPTION_DISK_MODULE,
|
||||||
OPTION_NO_BOOTSECTOR,
|
OPTION_NO_BOOTSECTOR,
|
||||||
OPTION_NO_RS_CODES,
|
OPTION_NO_RS_CODES,
|
||||||
|
OPTION_MACPPC_DIRECTORY,
|
||||||
|
OPTION_LABEL_FONT,
|
||||||
|
OPTION_LABEL_COLOR,
|
||||||
|
OPTION_LABEL_BGCOLOR,
|
||||||
|
OPTION_PRODUCT_VERSION
|
||||||
};
|
};
|
||||||
|
|
||||||
static int fs_probe = 1;
|
static int fs_probe = 1;
|
||||||
|
@ -119,6 +130,25 @@ argp_parser (int key, char *arg, struct argp_state *state)
|
||||||
install_bootsector = 0;
|
install_bootsector = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case OPTION_PRODUCT_VERSION:
|
||||||
|
free (product_version);
|
||||||
|
product_version = xstrdup (arg);
|
||||||
|
return 0;
|
||||||
|
case OPTION_LABEL_FONT:
|
||||||
|
free (label_font);
|
||||||
|
label_font = xstrdup (arg);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case OPTION_LABEL_COLOR:
|
||||||
|
free (label_color);
|
||||||
|
label_color = xstrdup (arg);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case OPTION_LABEL_BGCOLOR:
|
||||||
|
free (label_bgcolor);
|
||||||
|
label_bgcolor = xstrdup (arg);
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Accept and ignore for compatibility. */
|
/* Accept and ignore for compatibility. */
|
||||||
case OPTION_FONT:
|
case OPTION_FONT:
|
||||||
case OPTION_MKRELPATH:
|
case OPTION_MKRELPATH:
|
||||||
|
@ -138,6 +168,11 @@ argp_parser (int key, char *arg, struct argp_state *state)
|
||||||
bootdir = xstrdup (arg);
|
bootdir = xstrdup (arg);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case OPTION_MACPPC_DIRECTORY:
|
||||||
|
free (macppcdir);
|
||||||
|
macppcdir = xstrdup (arg);
|
||||||
|
return 0;
|
||||||
|
|
||||||
case OPTION_EFI_DIRECTORY:
|
case OPTION_EFI_DIRECTORY:
|
||||||
free (efidir);
|
free (efidir);
|
||||||
efidir = xstrdup (arg);
|
efidir = xstrdup (arg);
|
||||||
|
@ -255,9 +290,15 @@ static struct argp_option options[] = {
|
||||||
N_("the installation device is removable. "
|
N_("the installation device is removable. "
|
||||||
"This option is only available on EFI."), 2},
|
"This option is only available on EFI."), 2},
|
||||||
{"bootloader-id", OPTION_BOOTLOADER_ID, N_("ID"), 0,
|
{"bootloader-id", OPTION_BOOTLOADER_ID, N_("ID"), 0,
|
||||||
N_("the ID of bootloader. This option is only available on EFI."), 2},
|
N_("the ID of bootloader. This option is only available on EFI and Macs."), 2},
|
||||||
{"efi-directory", OPTION_EFI_DIRECTORY, N_("DIR"), 0,
|
{"efi-directory", OPTION_EFI_DIRECTORY, N_("DIR"), 0,
|
||||||
N_("use DIR as the EFI System Partition root."), 2},
|
N_("use DIR as the EFI System Partition root."), 2},
|
||||||
|
{"macppc-directory", OPTION_MACPPC_DIRECTORY, N_("DIR"), 0,
|
||||||
|
N_("use DIR for PPC MAC install."), 2},
|
||||||
|
{"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2},
|
||||||
|
{"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2},
|
||||||
|
{"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2},
|
||||||
|
{"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2},
|
||||||
{0, 0, 0, 0, 0, 0}
|
{0, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -697,6 +738,63 @@ is_prep_empty (grub_device_t dev)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bless (grub_device_t dev, const char *path, int x86)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
grub_util_info ("blessing %s", path);
|
||||||
|
|
||||||
|
if (stat (path, &st) < 0)
|
||||||
|
grub_util_error (N_("cannot stat `%s': %s"),
|
||||||
|
path, strerror (errno));
|
||||||
|
|
||||||
|
err = grub_mac_bless_inode (dev, st.st_ino, S_ISDIR (st.st_mode), x86);
|
||||||
|
if (err)
|
||||||
|
grub_util_error ("%s", grub_errmsg);
|
||||||
|
grub_util_info ("blessed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fill_core_services (const char *core_services)
|
||||||
|
{
|
||||||
|
char *label;
|
||||||
|
FILE *f;
|
||||||
|
char *label_text;
|
||||||
|
char *label_string = xasprintf ("%s %s", bootloader_id, product_version);
|
||||||
|
char *sysv_plist;
|
||||||
|
|
||||||
|
label = grub_util_path_concat (2, core_services, ".disk_label");
|
||||||
|
grub_util_info ("rendering label %s", label_string);
|
||||||
|
grub_util_render_label (label_font, label_bgcolor ? : "white",
|
||||||
|
label_color ? : "black", label_string, label);
|
||||||
|
grub_util_info ("label rendered");
|
||||||
|
free (label);
|
||||||
|
label_text = grub_util_path_concat (2, core_services, ".disk_label.contentDetails");
|
||||||
|
f = grub_util_fopen (label_text, "wb");
|
||||||
|
fprintf (f, "%s\n", label_string);
|
||||||
|
fclose (f);
|
||||||
|
free (label_string);
|
||||||
|
free (label_text);
|
||||||
|
|
||||||
|
sysv_plist = grub_util_path_concat (2, core_services, "SystemVersion.plist");
|
||||||
|
f = grub_util_fopen (sysv_plist, "wb");
|
||||||
|
fprintf (f,
|
||||||
|
"<plist version=\"1.0\">\n"
|
||||||
|
"<dict>\n"
|
||||||
|
" <key>ProductBuildVersion</key>\n"
|
||||||
|
" <string></string>\n"
|
||||||
|
" <key>ProductName</key>\n"
|
||||||
|
" <string>%s</string>\n"
|
||||||
|
" <key>ProductVersion</key>\n"
|
||||||
|
" <string>%s</string>\n"
|
||||||
|
"</dict>\n"
|
||||||
|
"</plist>\n", bootloader_id, product_version);
|
||||||
|
fclose (f);
|
||||||
|
free (sysv_plist);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -714,8 +812,14 @@ main (int argc, char *argv[])
|
||||||
char **efidir_device_names = NULL;
|
char **efidir_device_names = NULL;
|
||||||
grub_device_t efidir_grub_dev = NULL;
|
grub_device_t efidir_grub_dev = NULL;
|
||||||
char *efidir_grub_devname;
|
char *efidir_grub_devname;
|
||||||
|
int efidir_is_mac = 0;
|
||||||
|
int is_prep = 0;
|
||||||
|
const char *pkgdatadir;
|
||||||
|
|
||||||
grub_util_host_init (&argc, &argv);
|
grub_util_host_init (&argc, &argv);
|
||||||
|
product_version = xstrdup (PACKAGE_VERSION);
|
||||||
|
pkgdatadir = grub_util_get_pkgdatadir ();
|
||||||
|
label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2");
|
||||||
|
|
||||||
argp_parse (&argp, argc, argv, 0, 0, 0);
|
argp_parse (&argp, argc, argv, 0, 0, 0);
|
||||||
|
|
||||||
|
@ -800,9 +904,12 @@ main (int argc, char *argv[])
|
||||||
if (!install_device)
|
if (!install_device)
|
||||||
grub_util_error ("%s", _("install device isn't specified"));
|
grub_util_error ("%s", _("install device isn't specified"));
|
||||||
break;
|
break;
|
||||||
|
case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
|
||||||
|
if (install_device)
|
||||||
|
is_prep = 1;
|
||||||
|
break;
|
||||||
case GRUB_INSTALL_PLATFORM_MIPS_ARC:
|
case GRUB_INSTALL_PLATFORM_MIPS_ARC:
|
||||||
case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
|
case GRUB_INSTALL_PLATFORM_MIPSEL_ARC:
|
||||||
case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
|
|
||||||
break;
|
break;
|
||||||
case GRUB_INSTALL_PLATFORM_I386_EFI:
|
case GRUB_INSTALL_PLATFORM_I386_EFI:
|
||||||
case GRUB_INSTALL_PLATFORM_X86_64_EFI:
|
case GRUB_INSTALL_PLATFORM_X86_64_EFI:
|
||||||
|
@ -850,6 +957,9 @@ main (int argc, char *argv[])
|
||||||
/* Initialize all modules. */
|
/* Initialize all modules. */
|
||||||
grub_init_all ();
|
grub_init_all ();
|
||||||
grub_gcry_init_all ();
|
grub_gcry_init_all ();
|
||||||
|
grub_hostfs_init ();
|
||||||
|
grub_host_init ();
|
||||||
|
|
||||||
switch (platform)
|
switch (platform)
|
||||||
{
|
{
|
||||||
case GRUB_INSTALL_PLATFORM_I386_EFI:
|
case GRUB_INSTALL_PLATFORM_I386_EFI:
|
||||||
|
@ -927,7 +1037,13 @@ main (int argc, char *argv[])
|
||||||
if (! fs)
|
if (! fs)
|
||||||
grub_util_error ("%s", grub_errmsg);
|
grub_util_error ("%s", grub_errmsg);
|
||||||
|
|
||||||
if (grub_strcmp (fs->name, "fat") != 0)
|
efidir_is_mac = 0;
|
||||||
|
|
||||||
|
if (grub_strcmp (fs->name, "hfs") == 0
|
||||||
|
|| grub_strcmp (fs->name, "hfsplus") == 0)
|
||||||
|
efidir_is_mac = 1;
|
||||||
|
|
||||||
|
if (!efidir_is_mac && grub_strcmp (fs->name, "fat") != 0)
|
||||||
grub_util_error (_("%s doesn't look like an EFI partition.\n"), efidir);
|
grub_util_error (_("%s doesn't look like an EFI partition.\n"), efidir);
|
||||||
|
|
||||||
/* The EFI specification requires that an EFI System Partition must
|
/* The EFI specification requires that an EFI System Partition must
|
||||||
|
@ -1001,6 +1117,76 @@ main (int argc, char *argv[])
|
||||||
grub_install_mkdir_p (efidir);
|
grub_install_mkdir_p (efidir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (platform == GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275)
|
||||||
|
{
|
||||||
|
int is_guess = 0;
|
||||||
|
if (!macppcdir)
|
||||||
|
{
|
||||||
|
char *d;
|
||||||
|
|
||||||
|
is_guess = 1;
|
||||||
|
d = grub_util_path_concat (2, bootdir, "macppc");
|
||||||
|
if (!grub_util_is_directory (d))
|
||||||
|
{
|
||||||
|
free (d);
|
||||||
|
d = grub_util_path_concat (2, bootdir, "efi");
|
||||||
|
}
|
||||||
|
/* Find the Mac HFS(+) System Partition. */
|
||||||
|
if (!grub_util_is_directory (d))
|
||||||
|
{
|
||||||
|
free (d);
|
||||||
|
d = grub_util_path_concat (2, bootdir, "EFI");
|
||||||
|
}
|
||||||
|
if (!grub_util_is_directory (d))
|
||||||
|
{
|
||||||
|
free (d);
|
||||||
|
d = 0;
|
||||||
|
}
|
||||||
|
if (d)
|
||||||
|
macppcdir = d;
|
||||||
|
}
|
||||||
|
if (macppcdir)
|
||||||
|
{
|
||||||
|
char **macppcdir_device_names = NULL;
|
||||||
|
grub_device_t macppcdir_grub_dev = NULL;
|
||||||
|
char *macppcdir_grub_devname;
|
||||||
|
grub_fs_t fs;
|
||||||
|
|
||||||
|
macppcdir_device_names = grub_guess_root_devices (macppcdir);
|
||||||
|
if (!macppcdir_device_names || !macppcdir_device_names[0])
|
||||||
|
grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
|
||||||
|
macppcdir);
|
||||||
|
|
||||||
|
for (curdev = macppcdir_device_names; *curdev; curdev++)
|
||||||
|
grub_util_pull_device (*curdev);
|
||||||
|
|
||||||
|
macppcdir_grub_devname = grub_util_get_grub_dev (macppcdir_device_names[0]);
|
||||||
|
if (!macppcdir_grub_devname)
|
||||||
|
grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
|
||||||
|
macppcdir_device_names[0]);
|
||||||
|
|
||||||
|
macppcdir_grub_dev = grub_device_open (macppcdir_grub_devname);
|
||||||
|
if (! macppcdir_grub_dev)
|
||||||
|
grub_util_error ("%s", grub_errmsg);
|
||||||
|
|
||||||
|
fs = grub_fs_probe (macppcdir_grub_dev);
|
||||||
|
if (! fs)
|
||||||
|
grub_util_error ("%s", grub_errmsg);
|
||||||
|
|
||||||
|
if (grub_strcmp (fs->name, "hfs") != 0
|
||||||
|
&& grub_strcmp (fs->name, "hfsplus") != 0
|
||||||
|
&& !is_guess)
|
||||||
|
grub_util_error (_("%s is neither hfs nor hfsplue"),
|
||||||
|
macppcdir);
|
||||||
|
if (grub_strcmp (fs->name, "hfs") == 0
|
||||||
|
|| grub_strcmp (fs->name, "hfsplus") == 0)
|
||||||
|
{
|
||||||
|
install_device = macppcdir_device_names[0];
|
||||||
|
is_prep = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
grub_install_copy_files (grub_install_source_directory,
|
grub_install_copy_files (grub_install_source_directory,
|
||||||
grubdir, platform);
|
grubdir, platform);
|
||||||
|
|
||||||
|
@ -1491,8 +1677,59 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
|
case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
|
||||||
|
if (macppcdir)
|
||||||
|
{
|
||||||
|
char *core_services = grub_util_path_concat (4, macppcdir,
|
||||||
|
"System", "Library",
|
||||||
|
"CoreServices");
|
||||||
|
char *mach_kernel = grub_util_path_concat (2, macppcdir,
|
||||||
|
"mach_kernel");
|
||||||
|
char *grub_elf, *bootx;
|
||||||
|
FILE *f;
|
||||||
|
grub_device_t ins_dev;
|
||||||
|
char *grub_chrp = grub_util_path_concat (2,
|
||||||
|
grub_install_source_directory,
|
||||||
|
"grub.chrp");
|
||||||
|
|
||||||
|
grub_install_mkdir_p (core_services);
|
||||||
|
|
||||||
|
bootx = grub_util_path_concat (2, core_services, "BootX");
|
||||||
|
grub_install_copy_file (grub_chrp, bootx, 1);
|
||||||
|
|
||||||
|
grub_elf = grub_util_path_concat (2, core_services, "grub.elf");
|
||||||
|
grub_install_copy_file (imgfile, grub_elf, 1);
|
||||||
|
|
||||||
|
f = grub_util_fopen (mach_kernel, "r+");
|
||||||
|
if (!f)
|
||||||
|
grub_util_error ("Can't create file: %s", strerror (errno));
|
||||||
|
fclose (f);
|
||||||
|
|
||||||
|
fill_core_services (core_services);
|
||||||
|
|
||||||
|
ins_dev = grub_device_open (install_drive);
|
||||||
|
|
||||||
|
bless (ins_dev, core_services, 0);
|
||||||
|
|
||||||
|
if (update_nvram)
|
||||||
|
{
|
||||||
|
const char *dev;
|
||||||
|
int partno;
|
||||||
|
|
||||||
|
partno = ins_dev->disk->partition
|
||||||
|
? ins_dev->disk->partition->number + 1 : 0;
|
||||||
|
dev = grub_util_get_os_disk (install_device);
|
||||||
|
grub_install_register_ieee1275 (0, dev, partno,
|
||||||
|
"\\\\BootX");
|
||||||
|
}
|
||||||
|
grub_device_close (ins_dev);
|
||||||
|
free (grub_elf);
|
||||||
|
free (bootx);
|
||||||
|
free (mach_kernel);
|
||||||
|
free (grub_chrp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
/* If a install device is defined, copy the core.elf to PReP partition. */
|
/* If a install device is defined, copy the core.elf to PReP partition. */
|
||||||
if (install_device && install_device[0])
|
if (is_prep && install_device && install_device[0])
|
||||||
{
|
{
|
||||||
grub_device_t ins_dev;
|
grub_device_t ins_dev;
|
||||||
ins_dev = grub_device_open (install_drive);
|
ins_dev = grub_device_open (install_drive);
|
||||||
|
@ -1512,28 +1749,24 @@ main (int argc, char *argv[])
|
||||||
s);
|
s);
|
||||||
}
|
}
|
||||||
grub_device_close (ins_dev);
|
grub_device_close (ins_dev);
|
||||||
|
if (update_nvram)
|
||||||
|
grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device),
|
||||||
|
0, NULL);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
/* fallthrough. */
|
/* fallthrough. */
|
||||||
case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
|
case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
|
||||||
if (update_nvram)
|
if (update_nvram)
|
||||||
{
|
{
|
||||||
if (platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275
|
const char *dev;
|
||||||
|| !install_device
|
char *relpath;
|
||||||
|| install_device[0] == '\0')
|
int partno;
|
||||||
{
|
relpath = grub_make_system_path_relative_to_its_root (imgfile);
|
||||||
const char *dev;
|
partno = grub_dev->disk->partition
|
||||||
char *relpath;
|
? grub_dev->disk->partition->number + 1 : 0;
|
||||||
int partno;
|
dev = grub_util_get_os_disk (grub_devices[0]);
|
||||||
relpath = grub_make_system_path_relative_to_its_root (imgfile);
|
grub_install_register_ieee1275 (0, dev,
|
||||||
partno = grub_dev->disk->partition
|
partno, relpath);
|
||||||
? grub_dev->disk->partition->number + 1 : 0;
|
|
||||||
dev = grub_util_get_os_disk (grub_devices[0]);
|
|
||||||
grub_install_register_ieee1275 (0, dev,
|
|
||||||
partno, relpath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device),
|
|
||||||
0, NULL);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GRUB_INSTALL_PLATFORM_MIPS_ARC:
|
case GRUB_INSTALL_PLATFORM_MIPS_ARC:
|
||||||
|
@ -1541,14 +1774,59 @@ main (int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GRUB_INSTALL_PLATFORM_I386_EFI:
|
case GRUB_INSTALL_PLATFORM_I386_EFI:
|
||||||
{
|
if (!efidir_is_mac)
|
||||||
char *dst = grub_util_path_concat (2, efidir, "grub.efi");
|
{
|
||||||
/* For old macs. Suggested by Peter Jones. */
|
char *dst = grub_util_path_concat (2, efidir, "grub.efi");
|
||||||
grub_install_copy_file (imgfile, dst, 1);
|
/* For old macs. Suggested by Peter Jones. */
|
||||||
free (dst);
|
grub_install_copy_file (imgfile, dst, 1);
|
||||||
}
|
free (dst);
|
||||||
|
}
|
||||||
|
|
||||||
case GRUB_INSTALL_PLATFORM_X86_64_EFI:
|
case GRUB_INSTALL_PLATFORM_X86_64_EFI:
|
||||||
|
if (efidir_is_mac)
|
||||||
|
{
|
||||||
|
char *boot_efi;
|
||||||
|
char *core_services = grub_util_path_concat (4, efidir,
|
||||||
|
"System", "Library",
|
||||||
|
"CoreServices");
|
||||||
|
char *mach_kernel = grub_util_path_concat (2, efidir,
|
||||||
|
"mach_kernel");
|
||||||
|
FILE *f;
|
||||||
|
grub_device_t ins_dev;
|
||||||
|
|
||||||
|
grub_install_mkdir_p (core_services);
|
||||||
|
|
||||||
|
boot_efi = grub_util_path_concat (2, core_services, "boot.efi");
|
||||||
|
grub_install_copy_file (imgfile, boot_efi, 1);
|
||||||
|
|
||||||
|
f = grub_util_fopen (mach_kernel, "r+");
|
||||||
|
if (!f)
|
||||||
|
grub_util_error ("Can't create file: %s", strerror (errno));
|
||||||
|
fclose (f);
|
||||||
|
|
||||||
|
fill_core_services(core_services);
|
||||||
|
|
||||||
|
ins_dev = grub_device_open (install_drive);
|
||||||
|
|
||||||
|
bless (ins_dev, boot_efi, 1);
|
||||||
|
if (!removable && update_nvram)
|
||||||
|
{
|
||||||
|
char * efidir_disk;
|
||||||
|
int efidir_part;
|
||||||
|
|
||||||
|
/* Try to make this image bootable using the EFI Boot Manager, if available. */
|
||||||
|
efidir_disk = grub_util_get_os_disk (efidir_device_names[0]);
|
||||||
|
efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1;
|
||||||
|
grub_install_register_efi (efidir_disk, efidir_part,
|
||||||
|
"\\System\\Library\\CoreServices",
|
||||||
|
efi_distributor);
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_device_close (ins_dev);
|
||||||
|
free (boot_efi);
|
||||||
|
free (mach_kernel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case GRUB_INSTALL_PLATFORM_ARM_EFI:
|
case GRUB_INSTALL_PLATFORM_ARM_EFI:
|
||||||
case GRUB_INSTALL_PLATFORM_ARM64_EFI:
|
case GRUB_INSTALL_PLATFORM_ARM64_EFI:
|
||||||
case GRUB_INSTALL_PLATFORM_IA64_EFI:
|
case GRUB_INSTALL_PLATFORM_IA64_EFI:
|
||||||
|
|
199
util/grub-macbless.c
Normal file
199
util/grub-macbless.c
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
/* grub-probe.c - probe device information for a given path */
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <grub/types.h>
|
||||||
|
#include <grub/emu/misc.h>
|
||||||
|
#include <grub/util/misc.h>
|
||||||
|
#include <grub/device.h>
|
||||||
|
#include <grub/disk.h>
|
||||||
|
#include <grub/file.h>
|
||||||
|
#include <grub/fs.h>
|
||||||
|
#include <grub/partition.h>
|
||||||
|
#include <grub/msdos_partition.h>
|
||||||
|
#include <grub/emu/hostdisk.h>
|
||||||
|
#include <grub/emu/getroot.h>
|
||||||
|
#include <grub/term.h>
|
||||||
|
#include <grub/env.h>
|
||||||
|
#include <grub/diskfilter.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/crypto.h>
|
||||||
|
#include <grub/cryptodisk.h>
|
||||||
|
#include <grub/hfsplus.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#define _GNU_SOURCE 1
|
||||||
|
#include <argp.h>
|
||||||
|
|
||||||
|
#include "progname.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
bless (const char *path, int x86)
|
||||||
|
{
|
||||||
|
char *drive_name = NULL;
|
||||||
|
char **devices;
|
||||||
|
char *grub_path = NULL;
|
||||||
|
char *filebuf_via_grub = NULL, *filebuf_via_sys = NULL;
|
||||||
|
grub_device_t dev = NULL;
|
||||||
|
grub_err_t err;
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
grub_path = canonicalize_file_name (path);
|
||||||
|
|
||||||
|
if (stat (grub_path, &st) < 0)
|
||||||
|
grub_util_error (N_("cannot stat `%s': %s"),
|
||||||
|
grub_path, strerror (errno));
|
||||||
|
|
||||||
|
devices = grub_guess_root_devices (grub_path);
|
||||||
|
|
||||||
|
if (! devices || !devices[0])
|
||||||
|
grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), path);
|
||||||
|
|
||||||
|
drive_name = grub_util_get_grub_dev (devices[0]);
|
||||||
|
if (! drive_name)
|
||||||
|
grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
|
||||||
|
devices[0]);
|
||||||
|
|
||||||
|
grub_util_info ("opening %s", drive_name);
|
||||||
|
dev = grub_device_open (drive_name);
|
||||||
|
if (! dev)
|
||||||
|
grub_util_error ("%s", grub_errmsg);
|
||||||
|
|
||||||
|
err = grub_mac_bless_inode (dev, st.st_ino, S_ISDIR (st.st_mode), x86);
|
||||||
|
if (err)
|
||||||
|
grub_util_error ("%s", grub_errmsg);
|
||||||
|
free (grub_path);
|
||||||
|
free (filebuf_via_grub);
|
||||||
|
free (filebuf_via_sys);
|
||||||
|
free (drive_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct argp_option options[] = {
|
||||||
|
{"x86", 'x', 0, 0,
|
||||||
|
N_("bless for x86-based macs"), 0},
|
||||||
|
{"ppc", 'p', 0, 0,
|
||||||
|
N_("bless for ppc-based macs"), 0},
|
||||||
|
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
|
||||||
|
{ 0, 0, 0, 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct arguments
|
||||||
|
{
|
||||||
|
char *arg;
|
||||||
|
int ppc;
|
||||||
|
};
|
||||||
|
|
||||||
|
static error_t
|
||||||
|
argp_parser (int key, char *arg, struct argp_state *state)
|
||||||
|
{
|
||||||
|
/* Get the input argument from argp_parse, which we
|
||||||
|
know is a pointer to our arguments structure. */
|
||||||
|
struct arguments *arguments = state->input;
|
||||||
|
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case 'v':
|
||||||
|
verbosity++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'x':
|
||||||
|
arguments->ppc = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
arguments->ppc = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARGP_KEY_NO_ARGS:
|
||||||
|
fprintf (stderr, "%s", _("No path or device is specified.\n"));
|
||||||
|
argp_usage (state);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARGP_KEY_ARG:
|
||||||
|
if (arguments->arg)
|
||||||
|
{
|
||||||
|
fprintf (stderr, _("Unknown extra argument `%s'."), arg);
|
||||||
|
fprintf (stderr, "\n");
|
||||||
|
return ARGP_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
arguments->arg = xstrdup (arg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return ARGP_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct argp argp = {
|
||||||
|
options, argp_parser, N_("--ppc PATH|--x86 FILE"),
|
||||||
|
N_("Mac-style bless on HFS or HFS+"),
|
||||||
|
NULL, NULL, NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct arguments arguments;
|
||||||
|
|
||||||
|
grub_util_host_init (&argc, &argv);
|
||||||
|
|
||||||
|
/* Check for options. */
|
||||||
|
memset (&arguments, 0, sizeof (struct arguments));
|
||||||
|
if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbosity > 1)
|
||||||
|
grub_env_set ("debug", "all");
|
||||||
|
|
||||||
|
/* Initialize the emulated biosdisk driver. */
|
||||||
|
grub_util_biosdisk_init (NULL);
|
||||||
|
|
||||||
|
/* Initialize all modules. */
|
||||||
|
grub_init_all ();
|
||||||
|
grub_gcry_init_all ();
|
||||||
|
|
||||||
|
grub_lvm_fini ();
|
||||||
|
grub_mdraid09_fini ();
|
||||||
|
grub_mdraid1x_fini ();
|
||||||
|
grub_diskfilter_fini ();
|
||||||
|
grub_diskfilter_init ();
|
||||||
|
grub_mdraid09_init ();
|
||||||
|
grub_mdraid1x_init ();
|
||||||
|
grub_lvm_init ();
|
||||||
|
|
||||||
|
/* Do it. */
|
||||||
|
bless (arguments.arg, !arguments.ppc);
|
||||||
|
|
||||||
|
/* Free resources. */
|
||||||
|
grub_gcry_fini_all ();
|
||||||
|
grub_fini_all ();
|
||||||
|
grub_util_biosdisk_fini ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -24,6 +24,7 @@
|
||||||
#include <grub/util/misc.h>
|
#include <grub/util/misc.h>
|
||||||
#include <grub/emu/exec.h>
|
#include <grub/emu/exec.h>
|
||||||
#include <grub/emu/config.h>
|
#include <grub/emu/config.h>
|
||||||
|
#include <grub/emu/hostdisk.h>
|
||||||
#include <argp.h>
|
#include <argp.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -378,6 +379,10 @@ main (int argc, char *argv[])
|
||||||
if (!output_image)
|
if (!output_image)
|
||||||
grub_util_error ("%s", _("output file must be specified"));
|
grub_util_error ("%s", _("output file must be specified"));
|
||||||
|
|
||||||
|
grub_init_all ();
|
||||||
|
grub_hostfs_init ();
|
||||||
|
grub_host_init ();
|
||||||
|
|
||||||
xorriso_push (xorriso);
|
xorriso_push (xorriso);
|
||||||
xorriso_push ("-as");
|
xorriso_push ("-as");
|
||||||
xorriso_push ("mkisofs");
|
xorriso_push ("mkisofs");
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <grub/gfxmenu_view.h>
|
#include <grub/gfxmenu_view.h>
|
||||||
#include <grub/color.h>
|
#include <grub/color.h>
|
||||||
#include <grub/util/install.h>
|
#include <grub/util/install.h>
|
||||||
|
#include <grub/emu/hostdisk.h>
|
||||||
|
|
||||||
#define _GNU_SOURCE 1
|
#define _GNU_SOURCE 1
|
||||||
|
|
||||||
|
@ -166,6 +167,10 @@ main (int argc, char *argv[])
|
||||||
fclose (in);
|
fclose (in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grub_init_all ();
|
||||||
|
grub_hostfs_init ();
|
||||||
|
grub_host_init ();
|
||||||
|
|
||||||
grub_util_render_label (arguments.font,
|
grub_util_render_label (arguments.font,
|
||||||
arguments.bgcolor,
|
arguments.bgcolor,
|
||||||
arguments.fgcolor,
|
arguments.fgcolor,
|
||||||
|
|
|
@ -167,10 +167,6 @@ grub_util_render_label (const char *label_font,
|
||||||
fontfull = xasprintf ("(host)/%s", t);
|
fontfull = xasprintf ("(host)/%s", t);
|
||||||
free (t);
|
free (t);
|
||||||
|
|
||||||
grub_init_all ();
|
|
||||||
grub_hostfs_init ();
|
|
||||||
grub_host_init ();
|
|
||||||
|
|
||||||
grub_font_loader_init ();
|
grub_font_loader_init ();
|
||||||
font = grub_font_load (fontfull);
|
font = grub_font_load (fontfull);
|
||||||
if (!font)
|
if (!font)
|
||||||
|
|
Loading…
Reference in a new issue