=== modified file 'include/grub/bsdlabel.h' --- include/grub/bsdlabel.h 2010-02-06 17:43:37 +0000 +++ include/grub/bsdlabel.h 2010-05-18 22:05:09 +0000 @@ -63,6 +63,8 @@ #define GRUB_PC_PARTITION_OPENBSD_TYPE_NTFS 18 #define GRUB_PC_PARTITION_OPENBSD_TYPE_RAID 19 +#define GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION 2 + /* The BSD partition entry. */ struct grub_partition_bsd_entry { === modified file 'partmap/bsdlabel.c' --- partmap/bsdlabel.c 2010-03-26 14:44:13 +0000 +++ partmap/bsdlabel.c 2010-05-18 22:13:37 +0000 @@ -37,9 +37,6 @@ 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)) @@ -49,15 +46,36 @@ if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC)) return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature"); + /* A kludge to determine a base of be.offset. */ + if (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION + < grub_cpu_to_le16 (label.num_partitions)) + { + struct grub_partition_bsd_entry whole_disk_be; + + pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR + * GRUB_DISK_SECTOR_SIZE + sizeof (struct grub_partition_bsd_entry) + * GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION; + + if (grub_disk_read (disk, pos / GRUB_DISK_SECTOR_SIZE, + pos % GRUB_DISK_SECTOR_SIZE, sizeof (whole_disk_be), + &whole_disk_be)) + return grub_errno; + + delta = grub_le_to_cpu32 (whole_disk_be.offset); + } + 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++) + p.number++, pos += sizeof (struct grub_partition_bsd_entry)) { struct grub_partition_bsd_entry be; + if (p.number == GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION) + continue; + p.offset = pos / GRUB_DISK_SECTOR_SIZE; p.index = pos % GRUB_DISK_SECTOR_SIZE; @@ -68,11 +86,9 @@ 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 (p.len != 0) if (hook (disk, &p)) return grub_errno; - - pos += sizeof (struct grub_partition_bsd_entry); } return GRUB_ERR_NONE;