util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h
grub_setup_SOURCES = gnulib/progname.c \
util/i386/pc/grub-setup.c util/hostdisk.c \
- util/misc.c util/getroot.c kern/device.c kern/disk.c \
- kern/err.c kern/misc.c kern/parser.c kern/partition.c \
- kern/file.c kern/list.c kern/fs.c kern/env.c fs/fshelp.c \
+ util/misc.c util/getroot.c kern/device.c kern/disk.c \
+ kern/err.c kern/misc.c kern/parser.c kern/partition.c \
+ kern/file.c kern/fs.c kern/env.c kern/list.c \
+ fs/fshelp.c \
\
- fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \
- fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
- fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \
- fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \
+ fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \
+ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
+ fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \
+ fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \
fs/befs.c fs/befs_be.c fs/tar.c \
\
- partmap/msdos.c partmap/gpt.c \
+ partmap/msdos.c partmap/bsdlabel.c partmap/gpt.c \
\
disk/raid.c disk/mdraid_linux.c disk/lvm.c \
- util/raid.c util/lvm.c \
+ util/raid.c util/lvm.c \
grub_setup_init.c
sbin_SCRIPTS += grub-install
fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \
fs/befs.c fs/befs_be.c fs/tar.c \
\
- partmap/amiga.c partmap/apple.c partmap/msdos.c \
- partmap/sun.c partmap/acorn.c \
+ partmap/amiga.c partmap/apple.c partmap/msdos.c \
+ partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \
\
disk/raid.c disk/mdraid_linux.c disk/lvm.c \
- util/raid.c util/lvm.c gnulib/progname.c \
+ util/raid.c util/lvm.c gnulib/progname.c \
grub_setup_init.c
# For grub-ofpathname.
const grub_partition_t partition));
char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition);
-int EXPORT_FUNC(grub_partition_map_iterate) (int (*hook) (const grub_partition_map_t partmap));
-void EXPORT_FUNC(grub_partition_map_register) (grub_partition_map_t partmap);
+extern grub_partition_map_t EXPORT_VAR(grub_partition_map_list);
-void EXPORT_FUNC(grub_partition_map_unregister) (grub_partition_map_t partmap);
+static inline void
+grub_partition_map_register (grub_partition_map_t partmap)
+{
+ grub_list_push (GRUB_AS_LIST_P (&grub_partition_map_list),
+ GRUB_AS_LIST (partmap));
+}
+
+static inline void
+grub_partition_map_unregister (grub_partition_map_t partmap)
+{
+ grub_list_remove (GRUB_AS_LIST_P (&grub_partition_map_list),
+ GRUB_AS_LIST (partmap));
+}
+
+#define FOR_PARTITION_MAPS(var) for (var = grub_partition_map_list; var; var = var->next)
- #ifdef GRUB_UTIL
- void grub_msdos_partition_map_init (void);
- void grub_msdos_partition_map_fini (void);
- void grub_amiga_partition_map_init (void);
- void grub_amiga_partition_map_fini (void);
- void grub_apple_partition_map_init (void);
- void grub_apple_partition_map_fini (void);
- void grub_sun_partition_map_init (void);
- void grub_sun_partition_map_fini (void);
- void grub_gpt_partition_map_init (void);
- void grub_gpt_partition_map_fini (void);
- void grub_apple_partition_map_init (void);
- void grub_apple_partition_map_fini (void);
- #endif
\f
static inline grub_disk_addr_t
grub_partition_get_start (const grub_partition_t p)
/* Partition map type. */
static struct grub_partition_map grub_acorn_partition_map =
{
- .name = "part_acorn",
+ .name = "acorn",
.iterate = acorn_partition_map_iterate,
- .probe = acorn_partition_map_probe,
- .get_name = acorn_partition_map_get_name
};
- GRUB_MOD_INIT(acorn_partition_map)
+ GRUB_MOD_INIT(part_acorn)
{
grub_partition_map_register (&grub_acorn_partition_map);
}
/* Partition map type. */
static struct grub_partition_map grub_amiga_partition_map =
{
- .name = "part_amiga",
+ .name = "amiga",
.iterate = amiga_partition_map_iterate,
- .probe = amiga_partition_map_probe,
- .get_name = amiga_partition_map_get_name
};
- GRUB_MOD_INIT(amiga_partition_map)
+ GRUB_MOD_INIT(part_amiga)
{
grub_partition_map_register (&grub_amiga_partition_map);
}
/* Partition map type. */
static struct grub_partition_map grub_apple_partition_map =
{
- .name = "part_apple",
+ .name = "apple",
.iterate = apple_partition_map_iterate,
- .probe = apple_partition_map_probe,
- .get_name = apple_partition_map_get_name
};
- GRUB_MOD_INIT(apple_partition_map)
+ GRUB_MOD_INIT(part_apple)
{
grub_partition_map_register (&grub_apple_partition_map);
}
--- /dev/null
- GRUB_MOD_INIT(bsd_partition_map)
+/* bsdlabel.c - Read BSD style partition tables. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2002,2004,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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/partition.h>
+#include <grub/bsdlabel.h>
+#include <grub/disk.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+#include <grub/dl.h>
+
+static struct grub_partition_map grub_bsdlabel_partition_map;
+\f
+
+static grub_err_t
+bsdlabel_partition_map_iterate (grub_disk_t disk,
+ int (*hook) (grub_disk_t disk,
+ const grub_partition_t partition))
+{
+ struct grub_partition_bsd_disk_label label;
+ struct grub_partition p;
+ grub_disk_addr_t delta = 0;
+ unsigned pos;
+
+ /* BSDLabel offsets are absolute even when it's embed inside partition. */
+ delta = grub_partition_get_start (disk->partition);
+
+ /* Read the BSD label. */
+ if (grub_disk_read (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR,
+ 0, sizeof (label), &label))
+ return grub_errno;
+
+ /* Check if it is valid. */
+ if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC))
+ return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
+
+ pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR
+ * GRUB_DISK_SECTOR_SIZE;
+
+ for (p.number = 0;
+ p.number < grub_cpu_to_le16 (label.num_partitions);
+ p.number++)
+ {
+ struct grub_partition_bsd_entry be;
+
+ p.offset = pos / GRUB_DISK_SECTOR_SIZE;
+ p.index = pos % GRUB_DISK_SECTOR_SIZE;
+
+ if (grub_disk_read (disk, p.offset, p.index, sizeof (be), &be))
+ return grub_errno;
+
+ p.start = grub_le_to_cpu32 (be.offset) - delta;
+ p.len = grub_le_to_cpu32 (be.size);
+ p.partmap = &grub_bsdlabel_partition_map;
+
+ if (be.fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED)
+ if (hook (disk, &p))
+ return grub_errno;
+
+ pos += sizeof (struct grub_partition_bsd_entry);
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+\f
+/* Partition map type. */
+static struct grub_partition_map grub_bsdlabel_partition_map =
+ {
+ .name = "bsd",
+ .iterate = bsdlabel_partition_map_iterate,
+ };
+
- GRUB_MOD_FINI(bsd_partition_map)
++GRUB_MOD_INIT(part_bsd)
+{
+ grub_partition_map_register (&grub_bsdlabel_partition_map);
+}
+
++GRUB_MOD_FINI(part_bsd)
+{
+ grub_partition_map_unregister (&grub_bsdlabel_partition_map);
+}
/* Partition map type. */
static struct grub_partition_map grub_gpt_partition_map =
{
- .name = "part_gpt",
+ .name = "gpt",
.iterate = gpt_partition_map_iterate,
- .probe = gpt_partition_map_probe,
- .get_name = gpt_partition_map_get_name
};
- GRUB_MOD_INIT(gpt_partition_map)
+ GRUB_MOD_INIT(part_gpt)
{
grub_partition_map_register (&grub_gpt_partition_map);
}
/* Partition map type. */
static struct grub_partition_map grub_msdos_partition_map =
{
- .name = "part_msdos",
+ .name = "msdos",
.iterate = pc_partition_map_iterate,
- .probe = pc_partition_map_probe,
- .get_name = pc_partition_map_get_name
};
- GRUB_MOD_INIT(pc_partition_map)
+ GRUB_MOD_INIT(part_msdos)
{
grub_partition_map_register (&grub_msdos_partition_map);
}
/* Partition map type. */
static struct grub_partition_map grub_sun_partition_map =
{
- .name = "part_sun",
+ .name = "sun",
.iterate = sun_partition_map_iterate,
- .probe = sun_partition_map_probe,
- .get_name = sun_partition_map_get_name
};
- GRUB_MOD_INIT(sun_partition_map)
+ GRUB_MOD_INIT(part_sun)
{
grub_partition_map_register (&grub_sun_partition_map);
}
return GRUB_ERR_NONE;
}
- GRUB_MOD_INIT (pcpart)
+ GRUB_MOD_INIT (msdospart)
{
- activate_table_handle = grub_parttool_register ("part_msdos",
+ activate_table_handle = grub_parttool_register ("msdos",
grub_pcpart_boot,
grub_pcpart_bootargs);
- type_table_handle = grub_parttool_register ("part_msdos",
+ type_table_handle = grub_parttool_register ("msdos",
grub_pcpart_type,
grub_pcpart_typeargs);
{
int is_partition = 0;
char dev[PATH_MAX];
+ grub_disk_addr_t part_start = 0;
+
+ part_start = grub_partition_get_start (disk->partition);
strcpy (dev, map[disk->id].device);
- if (disk->partition && sector >= disk->partition->start
+ if (disk->partition && sector >= part_start
&& strncmp (map[disk->id].device, "/dev/", 5) == 0)
- is_partition = linux_find_partition (dev, disk->partition->start);
+ is_partition = linux_find_partition (dev, part_start);
- /* Open the partition. */
- grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev);
- fd = open (dev, flags);
- if (fd < 0)
+ if (data->dev && strcmp (data->dev, dev) == 0 &&
+ data->access_mode == (flags & O_ACCMODE))
{
- grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s'", dev);
- return -1;
+ grub_dprintf ("hostdisk", "reusing open device `%s'\n", dev);
+ fd = data->fd;
+ }
+ else
+ {
+ free (data->dev);
+ if (data->fd != -1)
+ close (data->fd);
+
+ /* Open the partition. */
+ grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev);
+ fd = open (dev, flags);
+ if (fd < 0)
+ {
+ grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s'", dev);
+ return -1;
+ }
+
+ /* Flush the buffer cache to the physical disk.
+ XXX: This also empties the buffer cache. */
+ ioctl (fd, BLKFLSBUF, 0);
+
+ data->dev = xstrdup (dev);
+ data->access_mode = (flags & O_ACCMODE);
+ data->fd = fd;
}
-
- /* Flush the buffer cache to the physical disk.
- XXX: This also empties the buffer cache. */
- ioctl (fd, BLKFLSBUF, 0);
if (is_partition)
- sector -= disk->partition->start;
+ sector -= part_start;
}
#else /* ! __linux__ */
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
struct hd_geometry hdg;
int dos_part = -1;
int bsd_part = -1;
- auto int find_partition (grub_disk_t disk,
+ auto int find_partition (grub_disk_t dsk,
const grub_partition_t partition);
- int find_partition (grub_disk_t disk __attribute__ ((unused)),
+ int find_partition (grub_disk_t dsk __attribute__ ((unused)),
const grub_partition_t partition)
{
- struct grub_msdos_partition *pcdata = NULL;
-
- if (strcmp (partition->partmap->name, "part_msdos") == 0)
- pcdata = partition->data;
+ grub_disk_addr_t part_start = 0;
+ grub_util_info ("Partition %d starts from %lu",
+ partition->number, partition->start);
- if (pcdata)
- {
- if (pcdata->bsd_part < 0)
- grub_util_info ("DOS partition %d starts from %lu",
- pcdata->dos_part, partition->start);
- else
- grub_util_info ("BSD partition %d,%c starts from %lu",
- pcdata->dos_part, pcdata->bsd_part + 'a',
- partition->start);
- }
- else
- {
- grub_util_info ("Partition %d starts from %lu",
- partition->index, partition->start);
- }
+ part_start = grub_partition_get_start (partition);
- if (hdg.start == partition->start)
+ if (hdg.start == part_start)
{
- if (pcdata)
+ if (partition->parent)
{
- dos_part = pcdata->dos_part;
- bsd_part = pcdata->bsd_part;
+ dos_part = partition->parent->number;
+ bsd_part = partition->number;
}
else
{