fix several issues with nested labels
This commit is contained in:
parent
c8e7bf5ff7
commit
56a4b23d37
7 changed files with 140 additions and 13 deletions
|
@ -89,6 +89,9 @@ library = {
|
||||||
common = grub-core/partmap/msdos.c;
|
common = grub-core/partmap/msdos.c;
|
||||||
common = grub-core/partmap/sun.c;
|
common = grub-core/partmap/sun.c;
|
||||||
common = grub-core/partmap/sunpc.c;
|
common = grub-core/partmap/sunpc.c;
|
||||||
|
common = grub-core/partmap/bsdlabel.c;
|
||||||
|
common = grub-core/partmap/netbsdlabel.c;
|
||||||
|
common = grub-core/partmap/openbsdlabel.c;
|
||||||
common = grub-core/script/function.c;
|
common = grub-core/script/function.c;
|
||||||
common = grub-core/script/lexer.c;
|
common = grub-core/script/lexer.c;
|
||||||
common = grub-core/script/main.c;
|
common = grub-core/script/main.c;
|
||||||
|
|
|
@ -1208,6 +1208,16 @@ module = {
|
||||||
common = partmap/bsdlabel.c;
|
common = partmap/bsdlabel.c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = part_netbsd;
|
||||||
|
common = partmap/netbsdlabel.c;
|
||||||
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = part_openbsd;
|
||||||
|
common = partmap/openbsdlabel.c;
|
||||||
|
};
|
||||||
|
|
||||||
module = {
|
module = {
|
||||||
name = part_sunpc;
|
name = part_sunpc;
|
||||||
common = partmap/sunpc.c;
|
common = partmap/sunpc.c;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
|
#include <grub/msdos_partition.h>
|
||||||
|
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
#include <grub/util/misc.h>
|
#include <grub/util/misc.h>
|
||||||
|
@ -32,7 +33,7 @@ static struct grub_partition_map grub_bsdlabel_partition_map;
|
||||||
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
bsdlabel_partition_map_iterate (grub_disk_t disk,
|
iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd,
|
||||||
int (*hook) (grub_disk_t disk,
|
int (*hook) (grub_disk_t disk,
|
||||||
const grub_partition_t partition))
|
const grub_partition_t partition))
|
||||||
{
|
{
|
||||||
|
@ -42,22 +43,27 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
|
||||||
unsigned pos;
|
unsigned pos;
|
||||||
|
|
||||||
/* Read the BSD label. */
|
/* Read the BSD label. */
|
||||||
if (grub_disk_read (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR,
|
if (grub_disk_read (disk, sector, 0, sizeof (label), &label))
|
||||||
0, sizeof (label), &label))
|
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
/* Check if it is valid. */
|
/* Check if it is valid. */
|
||||||
if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC))
|
if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC))
|
||||||
|
{
|
||||||
|
grub_dprintf ("partition",
|
||||||
|
"bad signature (found 0x%08x, expected 0x%08x)\n",
|
||||||
|
label.magic,
|
||||||
|
grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC));
|
||||||
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
|
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
|
||||||
|
}
|
||||||
|
|
||||||
/* A kludge to determine a base of be.offset. */
|
/* A kludge to determine a base of be.offset. */
|
||||||
if (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION
|
if (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION
|
||||||
< grub_cpu_to_le16 (label.num_partitions))
|
< grub_cpu_to_le16 (label.num_partitions) && freebsd)
|
||||||
{
|
{
|
||||||
struct grub_partition_bsd_entry whole_disk_be;
|
struct grub_partition_bsd_entry whole_disk_be;
|
||||||
|
|
||||||
pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR
|
pos = sizeof (label) + sector * GRUB_DISK_SECTOR_SIZE
|
||||||
* GRUB_DISK_SECTOR_SIZE + sizeof (struct grub_partition_bsd_entry)
|
+ sizeof (struct grub_partition_bsd_entry)
|
||||||
* GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION;
|
* GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION;
|
||||||
|
|
||||||
if (grub_disk_read (disk, pos / GRUB_DISK_SECTOR_SIZE,
|
if (grub_disk_read (disk, pos / GRUB_DISK_SECTOR_SIZE,
|
||||||
|
@ -68,8 +74,10 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
|
||||||
delta = grub_le_to_cpu32 (whole_disk_be.offset);
|
delta = grub_le_to_cpu32 (whole_disk_be.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR
|
pos = sizeof (label) + sector * GRUB_DISK_SECTOR_SIZE;
|
||||||
* GRUB_DISK_SECTOR_SIZE;
|
|
||||||
|
grub_dprintf ("partition", "bsdlabel with %d partitions detected\n",
|
||||||
|
grub_cpu_to_le16 (label.num_partitions));
|
||||||
|
|
||||||
for (p.number = 0;
|
for (p.number = 0;
|
||||||
p.number < grub_cpu_to_le16 (label.num_partitions);
|
p.number < grub_cpu_to_le16 (label.num_partitions);
|
||||||
|
@ -124,24 +132,112 @@ bsdlabel_partition_map_iterate (grub_disk_t disk,
|
||||||
if (hook (disk, &p))
|
if (hook (disk, &p))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined (NETBSDLABEL) && !defined (OPENBSDLABEL)
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
bsdlabel_partition_map_iterate (grub_disk_t disk,
|
||||||
|
int (*hook) (grub_disk_t disk,
|
||||||
|
const grub_partition_t partition))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos")
|
||||||
|
== 0 && disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_FREEBSD)
|
||||||
|
{
|
||||||
|
grub_dprintf ("partition", "FreeBSD embedded iterating\n");
|
||||||
|
return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 1,
|
||||||
|
hook);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (disk->partition
|
||||||
|
&& (grub_strcmp (disk->partition->partmap->name, "msdos") == 0
|
||||||
|
|| grub_strcmp (disk->partition->partmap->name, "bsd") == 0
|
||||||
|
|| grub_strcmp (disk->partition->partmap->name, "netbsd") == 0
|
||||||
|
|| grub_strcmp (disk->partition->partmap->name, "openbsd") == 0))
|
||||||
|
{
|
||||||
|
grub_dprintf ("partition", "no embedded iterating\n");
|
||||||
|
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
return iterate_real (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, hook);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifdef OPENBSDLABEL
|
||||||
|
#define GRUB_PC_PARTITION_TYPE_BSD GRUB_PC_PARTITION_TYPE_OPENBSD
|
||||||
|
#else
|
||||||
|
#define GRUB_PC_PARTITION_TYPE_BSD GRUB_PC_PARTITION_TYPE_NETBSD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
bsdlabel_partition_map_iterate (grub_disk_t disk,
|
||||||
|
int (*hook) (grub_disk_t disk,
|
||||||
|
const grub_partition_t partition))
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
|
||||||
|
if (disk->partition && grub_strcmp (disk->partition->partmap->name, "msdos")
|
||||||
|
== 0)
|
||||||
|
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
|
||||||
|
|
||||||
|
{
|
||||||
|
struct grub_msdos_partition_mbr mbr;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
err = grub_disk_read (disk, 0, 0, sizeof (mbr), &mbr);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE (mbr.entries); i++)
|
||||||
|
if (mbr.entries[i].type == GRUB_PC_PARTITION_TYPE_BSD)
|
||||||
|
{
|
||||||
|
err = iterate_real (disk, mbr.entries[i].start
|
||||||
|
+ GRUB_PC_PARTITION_BSD_LABEL_SECTOR, 0, hook);
|
||||||
|
if (err != GRUB_ERR_BAD_PART_TABLE)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no bsdlabel found");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Partition map type. */
|
/* Partition map type. */
|
||||||
static struct grub_partition_map grub_bsdlabel_partition_map =
|
static struct grub_partition_map grub_bsdlabel_partition_map =
|
||||||
{
|
{
|
||||||
|
#if defined (OPENBSDLABEL)
|
||||||
|
.name = "openbsd",
|
||||||
|
#elif defined (NETBSDLABEL)
|
||||||
|
.name = "netbsd",
|
||||||
|
#else
|
||||||
.name = "bsd",
|
.name = "bsd",
|
||||||
|
#endif
|
||||||
.iterate = bsdlabel_partition_map_iterate,
|
.iterate = bsdlabel_partition_map_iterate,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined (OPENBSDLABEL)
|
||||||
|
GRUB_MOD_INIT(part_openbsd)
|
||||||
|
#elif defined (NETBSDLABEL)
|
||||||
|
GRUB_MOD_INIT(part_netbsd)
|
||||||
|
#else
|
||||||
GRUB_MOD_INIT(part_bsd)
|
GRUB_MOD_INIT(part_bsd)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
grub_partition_map_register (&grub_bsdlabel_partition_map);
|
grub_partition_map_register (&grub_bsdlabel_partition_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined (OPENBSDLABEL)
|
||||||
|
GRUB_MOD_FINI(part_openbsd)
|
||||||
|
#elif defined (NETBSDLABEL)
|
||||||
|
GRUB_MOD_FINI(part_netbsd)
|
||||||
|
#else
|
||||||
GRUB_MOD_FINI(part_bsd)
|
GRUB_MOD_FINI(part_bsd)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
grub_partition_map_unregister (&grub_bsdlabel_partition_map);
|
grub_partition_map_unregister (&grub_bsdlabel_partition_map);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,15 @@ pc_partition_map_iterate (grub_disk_t disk,
|
||||||
int labeln = 0;
|
int labeln = 0;
|
||||||
grub_disk_addr_t lastaddr;
|
grub_disk_addr_t lastaddr;
|
||||||
grub_disk_addr_t ext_offset;
|
grub_disk_addr_t ext_offset;
|
||||||
|
grub_disk_addr_t delta = 0;
|
||||||
|
|
||||||
|
if (disk->partition && disk->partition->partmap == &grub_msdos_partition_map)
|
||||||
|
{
|
||||||
|
if (disk->partition->msdostype == GRUB_PC_PARTITION_TYPE_LINUX_MINIX)
|
||||||
|
delta = disk->partition->offset;
|
||||||
|
else
|
||||||
|
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no embedding supported");
|
||||||
|
}
|
||||||
|
|
||||||
p.offset = 0;
|
p.offset = 0;
|
||||||
ext_offset = 0;
|
ext_offset = 0;
|
||||||
|
@ -81,8 +90,9 @@ pc_partition_map_iterate (grub_disk_t disk,
|
||||||
{
|
{
|
||||||
e = mbr.entries + p.index;
|
e = mbr.entries + p.index;
|
||||||
|
|
||||||
p.start = p.offset + grub_le_to_cpu32 (e->start);
|
p.start = p.offset + grub_le_to_cpu32 (e->start) - delta;
|
||||||
p.len = grub_le_to_cpu32 (e->length);
|
p.len = grub_le_to_cpu32 (e->length);
|
||||||
|
p.msdostype = e->type;
|
||||||
|
|
||||||
grub_dprintf ("partition",
|
grub_dprintf ("partition",
|
||||||
"partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n",
|
"partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n",
|
||||||
|
|
2
grub-core/partmap/netbsdlabel.c
Normal file
2
grub-core/partmap/netbsdlabel.c
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#define NETBSDLABEL 1
|
||||||
|
#include "bsdlabel.c"
|
2
grub-core/partmap/openbsdlabel.c
Normal file
2
grub-core/partmap/openbsdlabel.c
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#define OPENBSDLABEL 1
|
||||||
|
#include "bsdlabel.c"
|
|
@ -65,6 +65,10 @@ struct grub_partition
|
||||||
|
|
||||||
/* The type partition map. */
|
/* The type partition map. */
|
||||||
grub_partition_map_t partmap;
|
grub_partition_map_t partmap;
|
||||||
|
|
||||||
|
/* The type of partition whne it's on MSDOS.
|
||||||
|
Used for embedding detection. */
|
||||||
|
grub_uint8_t msdostype;
|
||||||
};
|
};
|
||||||
|
|
||||||
grub_partition_t EXPORT_FUNC(grub_partition_probe) (struct grub_disk *disk,
|
grub_partition_t EXPORT_FUNC(grub_partition_probe) (struct grub_disk *disk,
|
||||||
|
|
Loading…
Add table
Reference in a new issue