]>
Commit | Line | Data |
---|---|---|
8906c3dd VS |
1 | /* |
2 | * GRUB -- GRand Unified Bootloader | |
3 | * Copyright (C) 2002,2005,2006,2007,2011 Free Software Foundation, Inc. | |
4 | * | |
5 | * GRUB is free software: you can redistribute it and/or modify | |
6 | * it under the terms of the GNU General Public License as published by | |
7 | * the Free Software Foundation, either version 3 of the License, or | |
8 | * (at your option) any later version. | |
9 | * | |
10 | * GRUB is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with GRUB. If not, see <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | ||
19 | #include <grub/partition.h> | |
20 | #include <grub/disk.h> | |
21 | #include <grub/mm.h> | |
22 | #include <grub/misc.h> | |
23 | #include <grub/dl.h> | |
24 | #include <grub/symbol.h> | |
25 | #include <grub/types.h> | |
26 | #include <grub/err.h> | |
27 | ||
28 | GRUB_MOD_LICENSE ("GPLv3+"); | |
29 | ||
30 | #define DVH_MAGIC 0x0be5a941 | |
31 | ||
32 | struct grub_dvh_partition_descriptor | |
33 | { | |
34 | grub_uint32_t length; | |
35 | grub_uint32_t start; | |
36 | grub_uint32_t type; | |
7e47e27b | 37 | } GRUB_PACKED; |
8906c3dd VS |
38 | |
39 | struct grub_dvh_block | |
40 | { | |
41 | grub_uint32_t magic; | |
42 | grub_uint8_t unused[308]; | |
43 | struct grub_dvh_partition_descriptor parts[16]; | |
44 | grub_uint32_t checksum; | |
45 | grub_uint32_t unused2; | |
7e47e27b | 46 | } GRUB_PACKED; |
8906c3dd VS |
47 | |
48 | static struct grub_partition_map grub_dvh_partition_map; | |
49 | ||
50 | /* Verify checksum (true=ok). */ | |
51 | static int | |
85c85365 | 52 | grub_dvh_is_valid (grub_uint32_t *label) |
8906c3dd VS |
53 | { |
54 | grub_uint32_t *pos; | |
55 | grub_uint32_t sum = 0; | |
56 | ||
85c85365 VS |
57 | for (pos = label; |
58 | pos < (label + sizeof (struct grub_dvh_block) / 4); | |
8906c3dd | 59 | pos++) |
bcfcea01 | 60 | sum += grub_be_to_cpu32 (*pos); |
8906c3dd VS |
61 | |
62 | return ! sum; | |
63 | } | |
64 | ||
65 | static grub_err_t | |
66 | dvh_partition_map_iterate (grub_disk_t disk, | |
25239370 | 67 | grub_partition_iterate_hook_t hook, void *hook_data) |
8906c3dd VS |
68 | { |
69 | struct grub_partition p; | |
85c85365 VS |
70 | union |
71 | { | |
72 | struct grub_dvh_block dvh; | |
73 | grub_uint32_t raw[0]; | |
74 | } block; | |
8906c3dd VS |
75 | unsigned partnum; |
76 | grub_err_t err; | |
77 | ||
78 | p.partmap = &grub_dvh_partition_map; | |
79 | err = grub_disk_read (disk, 0, 0, sizeof (struct grub_dvh_block), | |
80 | &block); | |
81 | if (err) | |
82 | return err; | |
83 | ||
85c85365 | 84 | if (DVH_MAGIC != grub_be_to_cpu32 (block.dvh.magic)) |
8906c3dd VS |
85 | return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a dvh partition table"); |
86 | ||
85c85365 | 87 | if (! grub_dvh_is_valid (block.raw)) |
8906c3dd VS |
88 | return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum"); |
89 | ||
90 | /* Maybe another error value would be better, because partition | |
91 | table _is_ recognized but invalid. */ | |
85c85365 | 92 | for (partnum = 0; partnum < ARRAY_SIZE (block.dvh.parts); partnum++) |
8906c3dd | 93 | { |
85c85365 | 94 | if (block.dvh.parts[partnum].length == 0) |
8906c3dd VS |
95 | continue; |
96 | ||
97 | if (partnum == 10) | |
98 | continue; | |
99 | ||
85c85365 VS |
100 | p.start = grub_be_to_cpu32 (block.dvh.parts[partnum].start); |
101 | p.len = grub_be_to_cpu32 (block.dvh.parts[partnum].length); | |
8906c3dd | 102 | p.number = p.index = partnum; |
25239370 | 103 | if (hook (disk, &p, hook_data)) |
8906c3dd VS |
104 | break; |
105 | } | |
106 | ||
107 | return grub_errno; | |
108 | } | |
109 | ||
110 | ||
111 | /* Partition map type. */ | |
112 | static struct grub_partition_map grub_dvh_partition_map = | |
113 | { | |
114 | .name = "dvh", | |
115 | .iterate = dvh_partition_map_iterate, | |
116 | }; | |
117 | ||
118 | GRUB_MOD_INIT(part_dvh) | |
119 | { | |
120 | grub_partition_map_register (&grub_dvh_partition_map); | |
121 | } | |
122 | ||
123 | GRUB_MOD_FINI(part_dvh) | |
124 | { | |
125 | grub_partition_map_unregister (&grub_dvh_partition_map); | |
126 | } | |
127 |