--- include/grub/msdos_partition.h 2010-03-06 20:51:37.000000000 +0000 +++ include/grub/msdos_partition.h 2010-11-17 18:22:29.000000000 +0000 @@ -57,6 +57,7 @@ #define GRUB_PC_PARTITION_BSD_LABEL_SECTOR 1 #define GRUB_PC_PARTITION_BSD_LABEL_MAGIC 0x82564557 #define GRUB_PC_PARTITION_BSD_MAX_ENTRIES 8 +#define GRUB_PC_PARTITION_BSD_RAW_PART 2 /* BSD partition types. */ #define GRUB_PC_PARTITION_BSD_TYPE_UNUSED 0 --- partmap/msdos.c 2010-03-06 20:51:37.000000000 +0000 +++ partmap/msdos.c 2010-11-17 18:26:26.000000000 +0000 @@ -176,6 +176,8 @@ /* Check if this is a BSD partition. */ if (grub_msdos_partition_is_bsd (e->type)) { + grub_uint32_t slice_offset = 0, raw_offset = 0; + /* Check if the BSD label is within the DOS partition. */ if (p.len <= GRUB_PC_PARTITION_BSD_LABEL_SECTOR) { @@ -200,6 +202,15 @@ label.magic, p.index); continue; } + + /* Compensate for relative addressing in FreeBSD. */ + if (e->type == GRUB_PC_PARTITION_TYPE_FREEBSD + && GRUB_PC_PARTITION_BSD_RAW_PART < grub_cpu_to_le16 (label.num_partitions)) + { + slice_offset = p.start; + raw_offset = grub_le_to_cpu32 (label.entries[GRUB_PC_PARTITION_BSD_RAW_PART].offset); + } + for (pcdata.bsd_part = 0; pcdata.bsd_part < grub_cpu_to_le16 (label.num_partitions); pcdata.bsd_part++) @@ -207,7 +218,9 @@ struct grub_msdos_partition_bsd_entry *be = label.entries + pcdata.bsd_part; + if (grub_le_to_cpu32 (be->offset) < raw_offset) + continue; - p.start = grub_le_to_cpu32 (be->offset); + p.start = grub_le_to_cpu32 (be->offset) - raw_offset + slice_offset; p.len = grub_le_to_cpu32 (be->size); pcdata.bsd_type = be->fs_type;