=== modified file 'Makefile.util.def'
--- Makefile.util.def 2011-11-13 11:48:39 +0000
+++ Makefile.util.def 2011-11-28 13:00:11 +0000
@@ -43,6 +43,7 @@
common_nodist = grub_script.tab.h;
common = grub-core/commands/blocklist.c;
+ common = grub-core/commands/macbless.c;
common = grub-core/commands/xnu_uuid.c;
common = grub-core/commands/testload.c;
common = grub-core/commands/ls.c;
@@ -705,3 +706,16 @@
ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
};
+
+program = {
+ name = grub-mactelbless;
+ installdir = sbin;
+ mansection = 1;
+ common = util/grub-mactelbless.c;
+
+ ldadd = libgrubmods.a;
+ ldadd = libgrubgcry.a;
+ ldadd = libgrubkern.a;
+ ldadd = grub-core/gnulib/libgnu.a;
+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
+};
=== added file 'docs/man/grub-mactelbless.h2m'
--- docs/man/grub-mactelbless.h2m 1970-01-01 00:00:00 +0000
+++ docs/man/grub-mactelbless.h2m 2011-11-28 10:47:58 +0000
@@ -0,0 +1,4 @@
+[NAME]
+grub-mactelbless \- Mactel-style HFS+ bless.
+[SEE ALSO]
+.BR grub-install (1)
=== modified file 'grub-core/Makefile.core.def'
--- grub-core/Makefile.core.def 2011-11-13 21:59:46 +0000
+++ grub-core/Makefile.core.def 2011-11-28 10:18:32 +0000
@@ -1148,6 +1148,11 @@
};
module = {
+ name = macbless;
+ common = commands/macbless.c;
+};
+
+module = {
name = pxe;
i386_pc = net/drivers/i386/pc/pxe.c;
enable = i386_pc;
=== added file 'grub-core/commands/macbless.c'
--- grub-core/commands/macbless.c 1970-01-01 00:00:00 +0000
+++ grub-core/commands/macbless.c 2011-11-28 12:10:25 +0000
@@ -0,0 +1,220 @@
+/* hfspbless.c - set the hfs+ boot directory. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2003,2005,2007,2008,2009 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 .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static grub_uint64_t inode_found;
+static char *dirname;
+static enum { NONE, FILE, DIR } found;
+
+static int find_inode (const char *filename,
+ const struct grub_dirhook_info *info)
+{ if (! info->inodeset)
+ return 0;
+
+ if ((grub_strcmp (dirname, filename) == 0
+ || (info->case_insensitive && grub_strcasecmp (dirname, filename) == 0)))
+ {
+ inode_found = info->inode;
+ 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;
+
+ /* 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)
+ {
+ return grub_error (GRUB_ERR_BAD_FS, "not a HFS+");
+ }
+
+ /* 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;
+ }
+
+ /* Make sure this is an HFS+ filesystem. XXX: Do we really support
+ HFX? */
+ 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)
+ {
+ if (is_dir)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ "can't bless a directory for mactel");
+ volheader.hfsplus.intel_bootfile = grub_be_to_cpu32 (inode);
+ }
+ else
+ {
+ if (!is_dir)
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+ "can't bless a file for mac PPC");
+ 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;
+
+ fs = grub_fs_probe (dev);
+ if (! fs || grub_strcmp (fs->name, "hfsplus") != 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, '/');
+ found = 0;
+
+ if (tail)
+ {
+ *tail = 0;
+ dirname = tail + 1;
+
+ (fs->dir) (dev, *path == 0 ? "/" : path, find_inode);
+ }
+ else
+ {
+ dirname = path + 1;
+ (fs->dir) (dev, "/", find_inode);
+ }
+ if (! found)
+ {
+ grub_free (path);
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, "%s not found\n", path_in);
+ }
+ grub_free (path);
+ }
+
+ return grub_mac_bless_inode (dev, inode_found, (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, "directory or file required");
+ device_name = grub_file_get_device_name (args[0]);
+ dev = grub_device_open (device_name);
+
+ path = grub_strchr (args[0], ')');
+ if (! path)
+ path = dirname;
+ 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,
+ "FILE",
+ "Bless FILE of HFS+ partition for intel macs.");
+ cmd_ppc = grub_register_command ("macppcbless", grub_cmd_macbless,
+ "DIRECTORY",
+ "Bless DIRECTORY of HFS+ partition for PPC macs.");
+}
+
+GRUB_MOD_FINI(macbless)
+{
+ grub_unregister_command (cmd);
+ grub_unregister_command (cmd_ppc);
+}
=== modified file 'grub-core/fs/hfsplus.c'
--- grub-core/fs/hfsplus.c 2011-10-25 22:32:17 +0000
+++ grub-core/fs/hfsplus.c 2011-11-28 09:54:23 +0000
@@ -28,155 +28,11 @@
#include
#include
#include
+#include
#include
GRUB_MOD_LICENSE ("GPLv3+");
-#define GRUB_HFSPLUS_MAGIC 0x482B
-#define GRUB_HFSPLUSX_MAGIC 0x4858
-#define GRUB_HFSPLUS_SBLOCK 2
-
-/* A HFS+ extent. */
-struct grub_hfsplus_extent
-{
- /* The first block of a file on disk. */
- grub_uint32_t start;
- /* The amount of blocks described by this extent. */
- grub_uint32_t count;
-} __attribute__ ((packed));
-
-/* The descriptor of a fork. */
-struct grub_hfsplus_forkdata
-{
- grub_uint64_t size;
- grub_uint32_t clumpsize;
- grub_uint32_t blocks;
- struct grub_hfsplus_extent extents[8];
-} __attribute__ ((packed));
-
-/* The HFS+ Volume Header. */
-struct grub_hfsplus_volheader
-{
- grub_uint16_t magic;
- grub_uint16_t version;
- grub_uint32_t attributes;
- grub_uint8_t unused1[12];
- grub_uint32_t utime;
- grub_uint8_t unused2[16];
- grub_uint32_t blksize;
- grub_uint8_t unused3[60];
- grub_uint64_t num_serial;
- struct grub_hfsplus_forkdata allocations_file;
- struct grub_hfsplus_forkdata extents_file;
- struct grub_hfsplus_forkdata catalog_file;
- struct grub_hfsplus_forkdata attrib_file;
- struct grub_hfsplus_forkdata startup_file;
-} __attribute__ ((packed));
-
-/* The type of node. */
-enum grub_hfsplus_btnode_type
- {
- GRUB_HFSPLUS_BTNODE_TYPE_LEAF = -1,
- GRUB_HFSPLUS_BTNODE_TYPE_INDEX = 0,
- GRUB_HFSPLUS_BTNODE_TYPE_HEADER = 1,
- GRUB_HFSPLUS_BTNODE_TYPE_MAP = 2,
- };
-
-struct grub_hfsplus_btnode
-{
- grub_uint32_t next;
- grub_uint32_t prev;
- grub_int8_t type;
- grub_uint8_t height;
- grub_uint16_t count;
- grub_uint16_t unused;
-} __attribute__ ((packed));
-
-/* The header of a HFS+ B+ Tree. */
-struct grub_hfsplus_btheader
-{
- grub_uint16_t depth;
- grub_uint32_t root;
- grub_uint32_t leaf_records;
- grub_uint32_t first_leaf_node;
- grub_uint32_t last_leaf_node;
- grub_uint16_t nodesize;
- grub_uint16_t keysize;
- grub_uint32_t total_nodes;
- grub_uint32_t free_nodes;
- grub_uint16_t reserved1;
- grub_uint32_t clump_size; /* ignored */
- grub_uint8_t btree_type;
- grub_uint8_t key_compare;
- grub_uint32_t attributes;
-} __attribute__ ((packed));
-
-/* The on disk layout of a catalog key. */
-struct grub_hfsplus_catkey
-{
- grub_uint16_t keylen;
- grub_uint32_t parent;
- grub_uint16_t namelen;
- grub_uint16_t name[30];
-} __attribute__ ((packed));
-
-/* The on disk layout of an extent overflow file key. */
-struct grub_hfsplus_extkey
-{
- grub_uint16_t keylen;
- grub_uint8_t type;
- grub_uint8_t unused;
- grub_uint32_t fileid;
- grub_uint32_t start;
-} __attribute__ ((packed));
-
-struct grub_hfsplus_key
-{
- union
- {
- struct grub_hfsplus_extkey extkey;
- struct grub_hfsplus_catkey catkey;
- grub_uint16_t keylen;
- };
-} __attribute__ ((packed));
-
-struct grub_hfsplus_catfile
-{
- grub_uint16_t type;
- grub_uint16_t flags;
- grub_uint32_t reserved;
- grub_uint32_t fileid;
- grub_uint8_t unused1[4];
- grub_uint32_t mtime;
- grub_uint8_t unused2[22];
- grub_uint16_t mode;
- grub_uint8_t unused3[44];
- struct grub_hfsplus_forkdata data;
- struct grub_hfsplus_forkdata resource;
-} __attribute__ ((packed));
-
-/* Filetype information as used in inodes. */
-#define GRUB_HFSPLUS_FILEMODE_MASK 0170000
-#define GRUB_HFSPLUS_FILEMODE_REG 0100000
-#define GRUB_HFSPLUS_FILEMODE_DIRECTORY 0040000
-#define GRUB_HFSPLUS_FILEMODE_SYMLINK 0120000
-
-/* Some pre-defined file IDs. */
-#define GRUB_HFSPLUS_FILEID_ROOTDIR 2
-#define GRUB_HFSPLUS_FILEID_OVERFLOW 3
-#define GRUB_HFSPLUS_FILEID_CATALOG 4
-
-enum grub_hfsplus_filetype
- {
- GRUB_HFSPLUS_FILETYPE_DIR = 1,
- GRUB_HFSPLUS_FILETYPE_REG = 2,
- GRUB_HFSPLUS_FILETYPE_DIR_THREAD = 3,
- GRUB_HFSPLUS_FILETYPE_REG_THREAD = 4
- };
-
-#define GRUB_HFSPLUSX_BINARYCOMPARE 0xBC
-#define GRUB_HFSPLUSX_CASEFOLDING 0xCF
-
/* Internal representation of a catalog key. */
struct grub_hfsplus_catkey_internal
{
@@ -948,6 +804,8 @@
info.dir = ((filetype & GRUB_FSHELP_TYPE_MASK) == GRUB_FSHELP_DIR);
info.mtimeset = 1;
info.mtime = node->mtime;
+ info.inodeset = 1;
+ info.inode = node->fileid;
info.case_insensitive = !! (filetype & GRUB_FSHELP_CASE_INSENSITIVE);
grub_free (node);
return hook (filename, &info);
=== modified file 'include/grub/fs.h'
--- include/grub/fs.h 2011-11-05 13:47:25 +0000
+++ include/grub/fs.h 2011-11-28 09:51:39 +0000
@@ -38,7 +38,9 @@
unsigned dir:1;
unsigned mtimeset:1;
unsigned case_insensitive:1;
+ unsigned inodeset:1;
grub_int32_t mtime;
+ grub_uint64_t inode;
};
/* Filesystem descriptor. */
=== added file 'include/grub/hfsplus.h'
--- include/grub/hfsplus.h 1970-01-01 00:00:00 +0000
+++ include/grub/hfsplus.h 2011-11-28 10:55:39 +0000
@@ -0,0 +1,182 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2005,2006,2007,2008,2009 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 .
+ */
+
+#ifndef GRUB_HFSPLUS_HEADER
+#define GRUB_HFSPLUS_HEADER 1
+
+#include
+
+#define GRUB_HFSPLUS_MAGIC 0x482B
+#define GRUB_HFSPLUSX_MAGIC 0x4858
+#define GRUB_HFSPLUS_SBLOCK 2
+
+/* A HFS+ extent. */
+struct grub_hfsplus_extent
+{
+ /* The first block of a file on disk. */
+ grub_uint32_t start;
+ /* The amount of blocks described by this extent. */
+ grub_uint32_t count;
+} __attribute__ ((packed));
+
+/* The descriptor of a fork. */
+struct grub_hfsplus_forkdata
+{
+ grub_uint64_t size;
+ grub_uint32_t clumpsize;
+ grub_uint32_t blocks;
+ struct grub_hfsplus_extent extents[8];
+} __attribute__ ((packed));
+
+/* The HFS+ Volume Header. */
+struct grub_hfsplus_volheader
+{
+ grub_uint16_t magic;
+ grub_uint16_t version;
+ grub_uint32_t attributes;
+ grub_uint8_t unused1[12];
+ grub_uint32_t utime;
+ grub_uint8_t unused2[16];
+ grub_uint32_t blksize;
+ 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;
+ struct grub_hfsplus_forkdata allocations_file;
+ struct grub_hfsplus_forkdata extents_file;
+ struct grub_hfsplus_forkdata catalog_file;
+ struct grub_hfsplus_forkdata attrib_file;
+ struct grub_hfsplus_forkdata startup_file;
+} __attribute__ ((packed));
+
+/* The type of node. */
+enum grub_hfsplus_btnode_type
+ {
+ GRUB_HFSPLUS_BTNODE_TYPE_LEAF = -1,
+ GRUB_HFSPLUS_BTNODE_TYPE_INDEX = 0,
+ GRUB_HFSPLUS_BTNODE_TYPE_HEADER = 1,
+ GRUB_HFSPLUS_BTNODE_TYPE_MAP = 2,
+ };
+
+struct grub_hfsplus_btnode
+{
+ grub_uint32_t next;
+ grub_uint32_t prev;
+ grub_int8_t type;
+ grub_uint8_t height;
+ grub_uint16_t count;
+ grub_uint16_t unused;
+} __attribute__ ((packed));
+
+/* The header of a HFS+ B+ Tree. */
+struct grub_hfsplus_btheader
+{
+ grub_uint16_t depth;
+ grub_uint32_t root;
+ grub_uint32_t leaf_records;
+ grub_uint32_t first_leaf_node;
+ grub_uint32_t last_leaf_node;
+ grub_uint16_t nodesize;
+ grub_uint16_t keysize;
+ grub_uint32_t total_nodes;
+ grub_uint32_t free_nodes;
+ grub_uint16_t reserved1;
+ grub_uint32_t clump_size; /* ignored */
+ grub_uint8_t btree_type;
+ grub_uint8_t key_compare;
+ grub_uint32_t attributes;
+} __attribute__ ((packed));
+
+/* The on disk layout of a catalog key. */
+struct grub_hfsplus_catkey
+{
+ grub_uint16_t keylen;
+ grub_uint32_t parent;
+ grub_uint16_t namelen;
+ grub_uint16_t name[30];
+} __attribute__ ((packed));
+
+/* The on disk layout of an extent overflow file key. */
+struct grub_hfsplus_extkey
+{
+ grub_uint16_t keylen;
+ grub_uint8_t type;
+ grub_uint8_t unused;
+ grub_uint32_t fileid;
+ grub_uint32_t start;
+} __attribute__ ((packed));
+
+struct grub_hfsplus_key
+{
+ union
+ {
+ struct grub_hfsplus_extkey extkey;
+ struct grub_hfsplus_catkey catkey;
+ grub_uint16_t keylen;
+ };
+} __attribute__ ((packed));
+
+struct grub_hfsplus_catfile
+{
+ grub_uint16_t type;
+ grub_uint16_t flags;
+ grub_uint32_t reserved;
+ grub_uint32_t fileid;
+ grub_uint8_t unused1[4];
+ grub_uint32_t mtime;
+ grub_uint8_t unused2[22];
+ grub_uint16_t mode;
+ grub_uint8_t unused3[44];
+ struct grub_hfsplus_forkdata data;
+ struct grub_hfsplus_forkdata resource;
+} __attribute__ ((packed));
+
+/* Filetype information as used in inodes. */
+#define GRUB_HFSPLUS_FILEMODE_MASK 0170000
+#define GRUB_HFSPLUS_FILEMODE_REG 0100000
+#define GRUB_HFSPLUS_FILEMODE_DIRECTORY 0040000
+#define GRUB_HFSPLUS_FILEMODE_SYMLINK 0120000
+
+/* Some pre-defined file IDs. */
+#define GRUB_HFSPLUS_FILEID_ROOTDIR 2
+#define GRUB_HFSPLUS_FILEID_OVERFLOW 3
+#define GRUB_HFSPLUS_FILEID_CATALOG 4
+
+enum grub_hfsplus_filetype
+ {
+ GRUB_HFSPLUS_FILETYPE_DIR = 1,
+ GRUB_HFSPLUS_FILETYPE_REG = 2,
+ GRUB_HFSPLUS_FILETYPE_DIR_THREAD = 3,
+ GRUB_HFSPLUS_FILETYPE_REG_THREAD = 4
+ };
+
+#define GRUB_HFSPLUSX_BINARYCOMPARE 0xBC
+#define GRUB_HFSPLUSX_CASEFOLDING 0xCF
+
+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);
+
+#endif
=== modified file 'util/grub-install.in'
--- util/grub-install.in 2011-11-12 20:12:52 +0000
+++ util/grub-install.in 2011-11-28 13:19:10 +0000
@@ -38,6 +38,7 @@
self="`basename $0`"
grub_setup="${sbindir}/`echo grub-setup | sed ${transform}`"
+grub_mactelbless="${sbindir}/`echo grub-mactelbless | sed ${transform}`"
grub_mkimage="${bindir}/`echo grub-mkimage | sed ${transform}`"
grub_mkdevicemap="${sbindir}/`echo grub-mkdevicemap | sed ${transform}`"
grub_probe="${sbindir}/`echo grub-probe | sed ${transform}`"
@@ -78,6 +79,8 @@
disk_module=native
fi
+install_ok=false
+
# Usage: usage
# Print the usage.
usage () {
@@ -150,6 +153,9 @@
allow_floppy=""
+efidir=
+macteldir=
+
# Check the arguments.
while test $# -gt 0
do
@@ -186,6 +192,16 @@
--boot-directory=*)
bootdir="`echo "$option" | sed 's/--boot-directory=//'`" ;;
+ --efi-directory)
+ efidir="`argument $option "$@"`"; shift;;
+ --efi-directory=*)
+ efidir="`echo "$option" | sed 's/--efi-directory=//'`" ;;
+
+ --mactel-directory)
+ macteldir="`argument $option "$@"`"; shift;;
+ --mactel-directory=*)
+ macteldir="`echo "$option" | sed 's/--mactel-directory=//'`" ;;
+
--grub-setup)
grub_setup="`argument "$option" "$@"`"; shift;;
--grub-setup=*)
@@ -329,27 +345,20 @@
if [ x"$platform" = xefi ]; then
# Find the EFI System Partition.
- efidir=
- if test -d "${bootdir}/efi"; then
- install_device="`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${bootdir}/efi"`"
+ if test -z "$efidir" && test -d "${bootdir}/efi"; then
+ install_device="`"$grub_probe" --target=device --device-map=/dev/null "${bootdir}/efi"`"
# Is it a mount point?
- if test "x$install_device" != "x`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${bootdir}"`"; then
+ if test "x$install_device" != "x`"$grub_probe" --target=device --device-map=/dev/null "${bootdir}"`"; then
efidir="${bootdir}/efi"
fi
- elif test -d "${bootdir}/EFI"; then
- install_device="`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${bootdir}/EFI"`"
+ elif test -z "$efidir" && test -d "${bootdir}/EFI"; then
+ install_device="`"$grub_probe" --target=device --device-map=/dev/null "${bootdir}/EFI"`"
# Is it a mount point?
- if test "x$install_device" != "x`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${bootdir}"`"; then
+ if test "x$install_device" != "x`"$grub_probe" --target=device --device-map=/dev/null "${bootdir}"`"; then
efidir="${bootdir}/EFI"
fi
- elif test -n "$rootdir" && test "x$rootdir" != "x/"; then
- # The EFI System Partition may have been given directly using
- # --root-directory.
- install_device="`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${rootdir}"`"
- # Is it a mount point?
- if test "x$install_device" != "x`"$grub_mkdevicemap" --device-map=/dev/stdout | "$grub_probe" --target=device --device-map=/dev/stdin "${rootdir}/.."`"; then
- efidir="${rootdir}"
- fi
+ elif test -n "$efidir"; then
+ install_device="`"$grub_probe" --target=device --device-map=/dev/null "${bootdir}/efi"`"
fi
if test -n "$efidir"; then
@@ -378,9 +387,6 @@
efi_file=BOOTIA32.EFI ;;
x86_64)
efi_file=BOOTX64.EFI ;;
- # GRUB does not yet support these architectures, but they're defined
- # by the specification so we include them here to ease future
- # expansion.
ia64)
efi_file=BOOTIA64.EFI ;;
esac
@@ -392,9 +398,6 @@
efi_file=grubia32.efi ;;
x86_64)
efi_file=grubx64.efi ;;
- # GRUB does not yet support these architectures, but they're defined
- # by the specification so we include them here to ease future
- # expansion.
ia64)
efi_file=grubia64.efi ;;
*)
@@ -405,12 +408,33 @@
fi
efidir="$efidir/EFI/$efi_distributor"
mkdir -p "$efidir" || exit 1
- else
- # We don't know what's going on. Fall back to traditional
- # (non-specification-compliant) behaviour.
- efidir="$grubdir"
- efi_distributor=
- efi_file=grub.efi
+ fi
+
+ if test -z "$macteldir" && test -d "${bootdir}/mactel"; then
+ mactel_device="`"$grub_probe" --target=device --device-map=/dev/null "${bootdir}/mactel"`"
+ # Is it a mount point?
+ if test "x$mactel_device" != "x`"$grub_probe" --target=device --device-map=/dev/null "${bootdir}"`"; then
+ macteldir="${bootdir}/mactel"
+ fi
+ elif test -z "$macteldir" && test -d "${bootdir}/MACTEL"; then
+ mactel_device="`"$grub_probe" --target=device --device-map=/dev/null "${bootdir}/MACTEL"`"
+ # Is it a mount point?
+ if test "x$mactel_device" != "x`"$grub_probe" --target=device --device-map=/dev/null "${bootdir}"`"; then
+ macteldir="${bootdir}/MACTEL"
+ fi
+ elif test -n "$macteldir"; then
+ mactel_device="`"$grub_probe" --target=device --device-map=/dev/null "${bootdir}/mactel"`"
+ fi
+
+ if test -n "$macteldir"; then
+ mactel_fs=`"$grub_probe" --target=fs "--device-map=${device_map}" "${macteldir}"`
+ if test "x$mactel_fs" = xhfsplus; then :; else
+ echo "${macteldir} doesn't look like an MACTEL partition." 1>&2
+ macteldir=
+ fi
+ fi
+ if test -n "$macteldir" ; then
+ mkdir -p "$macteldir/System/Library/CoreServices" || exit 1
fi
fi
@@ -521,73 +545,79 @@
relative_grubdir=/
fi
-prefix_drive=
-config_opt=
-
-rm -f "${grubdir}/load.cfg"
-
-if [ "x${debug_image}" != x ]; then
- echo "set debug='${debug_image}'" >> "${grubdir}/load.cfg"
- config_opt="-c ${grubdir}/load.cfg "
-fi
-
-if [ "x${devabstraction_module}" = "x" ] ; then
- if [ x"${install_device}" != x ]; then
- if echo "${install_device}" | grep -qx "(.*)" ; then
- install_drive="${install_device}"
- else
- install_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${install_device}"`" || exit 1
- fi
- install_drive="`echo "${install_drive}" | sed -e s/,[a-z0-9,]*//g`"
+create_image () {
+ create_image_install_device="$1"
+ output_image="$2"
+ prefix_drive=
+ config_opt=
+
+ rm -f "${grubdir}/load.cfg"
+
+ if [ "x${debug_image}" != x ]; then
+ echo "set debug='${debug_image}'" >> "${grubdir}/load.cfg"
+ config_opt="-c ${grubdir}/load.cfg "
fi
- grub_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"`" || exit 1
-
- # Strip partition number
- grub_partition="`echo "${grub_drive}" | sed -e 's/^[^,]*[,)]//; s/)$//'`"
- grub_drive="`echo "${grub_drive}" | sed -e s/,[a-z0-9,]*//g`"
- if ([ "x$disk_module" != x ] && [ "x$disk_module" != xbiosdisk ]) || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]); then
- # generic method (used on coreboot and ata mod)
- uuid="`"$grub_probe" --device-map="${device_map}" --target=fs_uuid --device "${grub_device}"`"
- if [ "x${uuid}" = "x" ] ; then
- if [ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]; then
- echo "UUID needed with $platform, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
- elif [ "$disk_module" = ata ]; then
- echo "UUID needed with ata mod, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
- else
- echo "UUID needed with cross-disk installs, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
- fi
-
- exit 1
- fi
-
- echo "search.fs_uuid ${uuid} root " >> "${grubdir}/load.cfg"
- echo 'set prefix=($root)'"${relative_grubdir}" >> "${grubdir}/load.cfg"
- config_opt="-c ${grubdir}/load.cfg "
- modules="$modules search_fs_uuid"
+
+ if [ "x${devabstraction_module}" = "x" ] ; then
+ if [ x"${create_image_install_device}" != x ]; then
+ if echo "${create_image_install_device}" | grep -qx "(.*)" ; then
+ install_drive="${create_image_install_device}"
+ else
+ install_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${create_image_install_device}"`" || exit 1
+ fi
+ install_drive="`echo "${install_drive}" | sed -e s/,[a-z0-9,]*//g`"
+ fi
+ grub_drive="`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"`" || exit 1
+
+ # Strip partition number
+ grub_partition="`echo "${grub_drive}" | sed -e 's/^[^,]*[,)]//; s/)$//'`"
+ grub_drive="`echo "${grub_drive}" | sed -e s/,[a-z0-9,]*//g`"
+ if ([ "x$disk_module" != x ] && [ "x$disk_module" != xbiosdisk ]) || [ "x${grub_drive}" != "x${install_drive}" ] || ([ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]); then
+ # generic method (used on coreboot and ata mod)
+ uuid="`"$grub_probe" --device-map="${device_map}" --target=fs_uuid --device "${grub_device}"`"
+ if [ "x${uuid}" = "x" ] ; then
+ if [ "x$platform" != xefi ] && [ "x$platform" != xpc ] && [ x"${platform}" != x"ieee1275" ]; then
+ echo "UUID needed with $platform, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
+ elif [ "$disk_module" = ata ]; then
+ echo "UUID needed with ata mod, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
+ else
+ echo "UUID needed with cross-disk installs, but the filesystem containing ${grubdir} does not support UUIDs." 1>&2
+ fi
+
+ exit 1
+ fi
+
+ echo "search.fs_uuid ${uuid} root " >> "${grubdir}/load.cfg"
+ echo 'set prefix=($root)'"${relative_grubdir}" >> "${grubdir}/load.cfg"
+ config_opt="-c ${grubdir}/load.cfg "
+ modules="$modules search_fs_uuid"
+ else
+ # we need to hardcode the partition number in the core image's prefix.
+ if [ x"$grub_partition" = x ]; then
+ prefix_drive="()"
+ else
+ prefix_drive="(,$grub_partition)"
+ fi
+ fi
else
- # we need to hardcode the partition number in the core image's prefix.
- if [ x"$grub_partition" = x ]; then
- prefix_drive="()"
- else
- prefix_drive="(,$grub_partition)"
+ if [ x$GRUB_CRYPTODISK_ENABLE = xy ]; then
+ for uuid in "`"${grub_probe}" --device "${grub_device}" --target=cryptodisk_uuid`"; do
+ echo "cryptomount -u $uuid" >> "${grubdir}/load.cfg"
+ done
+ config_opt="-c ${grubdir}/load.cfg "
fi
- fi
-else
- if [ x$GRUB_CRYPTODISK_ENABLE = xy ]; then
- for uuid in "`"${grub_probe}" --device "${grub_device}" --target=cryptodisk_uuid`"; do
- echo "cryptomount -u $uuid" >> "${grubdir}/load.cfg"
- done
- config_opt="-c ${grubdir}/load.cfg "
- fi
-
- prefix_drive=`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"` || exit 1
-fi
-
-case "${target_cpu}-${platform}" in
- sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;;
- mipsel-loongson) mkimage_target=mipsel-loongson-elf ;;
- *) mkimage_target="${target_cpu}-${platform}" ;;
-esac
+
+ prefix_drive=`"$grub_probe" --device-map="${device_map}" --target=drive --device "${grub_device}"` || exit 1
+ fi
+
+ case "${target_cpu}-${platform}" in
+ sparc64-ieee1275) mkimage_target=sparc64-ieee1275-raw ;;
+ mipsel-loongson) mkimage_target=mipsel-loongson-elf ;;
+ *) mkimage_target="${target_cpu}-${platform}" ;;
+ esac
+
+ "$grub_mkimage" ${config_opt} -d "${pkglibdir}" -O ${mkimage_target} --output="$output_image" --prefix="${prefix_drive}${relative_grubdir}" $modules || exit 1
+}
case "${target_cpu}-${platform}" in
i386-efi | x86_64-efi) imgext=efi ;;
@@ -596,8 +626,8 @@
*) imgext=img ;;
esac
+create_image "$install_device" "${grubdir}/core.${imgext}"
-"$grub_mkimage" ${config_opt} -d "${pkglibdir}" -O ${mkimage_target} --output="${grubdir}/core.${imgext}" --prefix="${prefix_drive}${relative_grubdir}" $modules || exit 1
# Backward-compatibility kludges
if [ "${target_cpu}-${platform}" = "mipsel-loongson" ]; then
@@ -608,12 +638,12 @@
"$grub_mkimage" ${config_opt} -d "${pkglibdir}" -O ${mkimage_target} --output="${grubdir}/grub.efi" --prefix="" $modules || exit 1
fi
-
# Perform the platform-dependent install
if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] ; then
# Now perform the installation.
"$grub_setup" ${allow_floppy} ${setup_verbose} ${setup_force} --directory="${grubdir}" \
--device-map="${device_map}" "${install_device}" || exit 1
+ install_ok=true
elif [ "${target_cpu}-${platform}" = "i386-ieee1275" ] || [ "${target_cpu}-${platform}" = "powerpc-ieee1275" ]; then
if [ x"$update_nvram" = xyes ]; then
ofpathname="`which ofpathname`"
@@ -649,11 +679,12 @@
echo " setenv boot-device $boot_device"
exit 1
}
+ install_ok=true
fi
elif [ x"${target_cpu}-${platform}" = xmips-arc ]; then
dvhtool -d "${install_device}" --unix-to-vh "{grubdir}/core.${imgext}" grub
echo "You will have to set SystemPartition and OSLoader manually."
-elif [ x"$platform" = xefi ]; then
+elif [ x"$platform" = xefi ] && [ -n "$efidir" ]; then
cp "${grubdir}/core.${imgext}" "${efidir}/${efi_file}"
# For old macs. Suggested by Peter Jones.
if [ x$target_cpu = xi386 ]; then
@@ -662,6 +693,9 @@
# Try to make this image bootable using the EFI Boot Manager, if available.
efibootmgr="`which efibootmgr`"
+ if test "$removable" = yes ; then
+ install_ok=true
+ fi
if test "$removable" = no && test -n "$efi_distributor" && \
test -n "$efibootmgr"; then
# On Linux, we need the efivars kernel modules.
@@ -689,11 +723,34 @@
efidir_disk="$(echo "$clean_devmap" | grep "^$(echo "$efidir_drive" | sed 's/,[^)]*//')" | cut -f2)"
efidir_part="$(echo "$efidir_drive" | sed 's/^([^,]*,[^0-9]*//; s/[^0-9].*//')"
efibootmgr $efi_quiet -c -d "$efidir_disk" -p "$efidir_part" -w \
- -L "$bootloader_id" -l "\\EFI\\$efi_distributor\\$efi_file"
+ -L "$bootloader_id" -l "\\EFI\\$efi_distributor\\$efi_file" && install_ok=true
fi
fi
fi
+if ([ "${target_cpu}-${platform}" = "i386-efi" ] || [ "${target_cpu}-${platform}" = "x86_64-efi" ] ) && [ -n "$macteldir" ]; then
+ create_image "$mactel_device" "${macteldir}/System/Library/CoreServices/boot.efi"
+ touch "${macteldir}/mach_kernel"
+ cat > "${macteldir}/System/Library/CoreServices/SystemVersion.plist" <
+
+ ProductBuildVersion
+
+ ProductName
+ ${bootloader_id}
+ ProductVersion
+ ${PACKAGE_NAME} ${PACKAGE_VERSION}
+
+
+EOF
+ "$grub_mactelbless" "${macteldir}/System/Library/CoreServices/boot.efi"
+ install_ok=true
+fi
+
+if [ x"$install_ok" != "xtrue" ]; then
+ echo "Unable to perform platform-specific install. Consult your platform manual to finish installing using ${grubdir}/core.${imgext} image"
+fi
+
echo "Installation finished. No error reported."
# Bye.
=== added file 'util/grub-mactelbless.c'
--- util/grub-mactelbless.c 1970-01-01 00:00:00 +0000
+++ util/grub-mactelbless.c 2011-11-28 12:57:01 +0000
@@ -0,0 +1,214 @@
+/* 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 .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define _GNU_SOURCE 1
+#include
+
+#include "progname.h"
+
+static void
+bless (const char *path)
+{
+ char *drive_name = NULL;
+ char *device_name;
+ char *grub_path = NULL;
+ char *filebuf_via_grub = NULL, *filebuf_via_sys = NULL;
+ grub_device_t dev = NULL;
+ grub_fs_t fs;
+ grub_err_t err;
+ struct stat st;
+
+ grub_path = canonicalize_file_name (path);
+
+ if (stat (grub_path, &st) < 0)
+ grub_util_error ("Can't stat %s: %s", grub_path, strerror (errno));
+
+ device_name = grub_guess_root_device (grub_path);
+
+ if (! device_name)
+ grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), path);
+
+ drive_name = grub_util_get_grub_dev (device_name);
+ if (! drive_name)
+ grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
+ device_name);
+
+ 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), 1);
+ if (err)
+ grub_util_error ("%s", _(grub_errmsg));
+ free (grub_path);
+ free (filebuf_via_grub);
+ free (filebuf_via_sys);
+ free (drive_name);
+}
+
+static struct option options[] =
+ {
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'V'},
+ {"verbose", no_argument, 0, 'v'},
+ {0, 0, 0, 0}
+ };
+
+static void
+usage (int status)
+{
+ if (status)
+ fprintf (stderr,
+ _("Try `%s --help' for more information.\n"), program_name);
+ else
+ printf (_("\
+Usage: %s FILE\n\
+\n\
+Mactel-style bless a FILE on HFS+.\n\
+\n\
+ -h, --help display this message and exit\n\
+ -V, --version print version information and exit\n\
+ -v, --verbose print verbose messages\n\
+\n\
+Report bugs to <%s>.\n\
+"), program_name,
+ DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT);
+
+ exit (status);
+}
+
+int
+main (int argc, char *argv[])
+{
+ char *dev_map = 0;
+ char *argument;
+
+ set_program_name (argv[0]);
+
+ grub_util_init_nls ();
+
+ /* Check for options. */
+ while (1)
+ {
+ int c = getopt_long (argc, argv, "dm:t:hVv", options, 0);
+
+ if (c == -1)
+ break;
+ else
+ switch (c)
+ {
+ case 'm':
+ if (dev_map)
+ free (dev_map);
+
+ dev_map = xstrdup (optarg);
+ break;
+
+ case 'h':
+ usage (0);
+ break;
+
+ case 'V':
+ printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
+ return 0;
+
+ case 'v':
+ verbosity++;
+ break;
+
+ default:
+ usage (1);
+ break;
+ }
+ }
+
+ if (verbosity > 1)
+ grub_env_set ("debug", "all");
+
+ /* Obtain ARGUMENT. */
+ if (optind >= argc)
+ {
+ fprintf (stderr, _("No path or device is specified.\n"));
+ usage (1);
+ }
+
+ if (optind + 1 != argc)
+ {
+ fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]);
+ usage (1);
+ }
+
+ argument = argv[optind];
+
+ /* Initialize the emulated biosdisk driver. */
+ grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP);
+
+ /* Initialize all modules. */
+ grub_init_all ();
+ grub_gcry_init_all ();
+
+ grub_lvm_fini ();
+ grub_mdraid09_fini ();
+ grub_mdraid1x_fini ();
+ grub_raid_fini ();
+ grub_raid_init ();
+ grub_mdraid09_init ();
+ grub_mdraid1x_init ();
+ grub_lvm_init ();
+
+ /* Do it. */
+ bless (argument);
+
+ /* Free resources. */
+ grub_gcry_fini_all ();
+ grub_fini_all ();
+ grub_util_biosdisk_fini ();
+
+ free (dev_map);
+
+ return 0;
+}