1 /* dfly.c - Read DragonFly BSD disklabel64. */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2013 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <grub/disk.h>
21 #include <grub/misc.h>
23 #include <grub/partition.h>
25 GRUB_MOD_LICENSE ("GPLv3+");
27 static struct grub_partition_map grub_dfly_partition_map
;
29 #define GRUB_PARTITION_DISKLABEL64_HEADER_SIZE 200
31 /* Full entry is 64 bytes however we really care only
32 about offset and size which are in first 16 bytes.
33 Avoid using too much stack. */
34 #define GRUB_PARTITION_DISKLABEL64_ENTRY_SIZE 64
35 struct grub_partition_disklabel64_entry
37 grub_uint64_t boffset
;
41 /* Full entry is 200 bytes however we really care only
42 about magic and number of partitions which are in first 16 bytes.
43 Avoid using too much stack. */
44 struct grub_partition_disklabel64
47 #define GRUB_DISKLABEL64_MAGIC ((grub_uint32_t)0xc4464c59)
50 grub_uint32_t npartitions
;
54 dfly_partition_map_iterate (grub_disk_t disk
,
55 grub_partition_iterate_hook_t hook
,
58 struct grub_partition part
;
60 struct grub_partition_disklabel64 label
;
62 part
.partmap
= &grub_dfly_partition_map
;
64 if (grub_disk_read (disk
, 1, 0, sizeof (label
), &label
))
67 if (label
.magic
!= grub_cpu_to_le32_compile_time (GRUB_DISKLABEL64_MAGIC
))
69 grub_dprintf ("partition",
70 "bad magic (found 0x%x; wanted 0x%x)\n",
71 (unsigned int) grub_le_to_cpu32 (label
.magic
),
72 (unsigned int) GRUB_DISKLABEL64_MAGIC
);
73 return grub_error (GRUB_ERR_BAD_PART_TABLE
, "disklabel64 not found");
76 pos
= GRUB_PARTITION_DISKLABEL64_HEADER_SIZE
+ GRUB_DISK_SECTOR_SIZE
;
79 partno
< grub_le_to_cpu32 (label
.npartitions
); ++partno
)
81 grub_disk_addr_t sector
= pos
>> GRUB_DISK_SECTOR_BITS
;
82 grub_off_t offset
= pos
& (GRUB_DISK_SECTOR_SIZE
- 1);
83 struct grub_partition_disklabel64_entry dpart
;
85 pos
+= GRUB_PARTITION_DISKLABEL64_ENTRY_SIZE
;
86 if (grub_disk_read (disk
, sector
, offset
, sizeof (dpart
), &dpart
))
89 grub_dprintf ("partition",
90 "partition %2d: offset 0x%llx, "
93 (unsigned long long) grub_le_to_cpu64 (dpart
.boffset
),
94 (unsigned long long) grub_le_to_cpu64 (dpart
.bsize
));
96 /* Is partition initialized? */
100 part
.number
= partno
;
101 part
.start
= grub_le_to_cpu64 (dpart
.boffset
) >> GRUB_DISK_SECTOR_BITS
;
102 part
.len
= grub_le_to_cpu64 (dpart
.bsize
) >> GRUB_DISK_SECTOR_BITS
;
104 /* This is counter-intuitive, but part.offset and sector have
105 * the same type, and offset (NOT part.offset) is guaranteed
106 * to fit into part.index. */
107 part
.offset
= sector
;
110 if (hook (disk
, &part
, hook_data
))
114 return GRUB_ERR_NONE
;
117 /* Partition map type. */
118 static struct grub_partition_map grub_dfly_partition_map
=
121 .iterate
= dfly_partition_map_iterate
,
124 GRUB_MOD_INIT(part_dfly
)
126 grub_partition_map_register (&grub_dfly_partition_map
);
129 GRUB_MOD_FINI(part_dfly
)
131 grub_partition_map_unregister (&grub_dfly_partition_map
);