23
23
#include <grub/mm.h>
24
24
#include <grub/misc.h>
25
25
#include <grub/dl.h>
26
#include <grub/i18n.h>
27
28
GRUB_MOD_LICENSE ("GPLv3+");
29
30
static struct grub_partition_map grub_msdos_partition_map;
34
#include <grub/emu/misc.h>
36
struct embed_signature
39
const char *signature;
41
enum { TYPE_SOFTWARE, TYPE_RAID } type;
44
const char message_warn[][200] = {
45
/* TRANSLATORS: MBR gap and boot track is the same thing and is the space
46
between MBR and first partitition. If your language translates well only
47
"boot track", you can just use it everywhere. Next two messages are about
48
RAID controllers/software bugs which GRUB has to live with. Please spread
49
the message that these are bugs in other software and not merely
50
suboptimal behaviour. */
51
[TYPE_RAID] = N_("Sector %llu is already in use by raid controller `%s';"
53
"Please ask the manufacturer not to store data in MBR gap"),
54
[TYPE_SOFTWARE] = N_("Sector %llu is already in use by the program `%s';"
56
"This software may cause boot or other problems in "
57
"future. Please ask its authors not to store data "
62
/* Signatures of other software that may be using sectors in the embedding
64
struct embed_signature embed_signatures[] =
74
.signature = "\xd4\x41\xa0\xf5\x03\x00\x03\x00",
80
.signature = "\xd8\x41\xa0\xf5\x02\x00\x02\x00",
85
/* from Ryan Perkins */
86
.name = "HP Backup and Recovery Manager (?)",
87
.signature = "\x70\x8a\x5d\x46\x35\xc5\x1b\x93"
88
"\xae\x3d\x86\xfd\xb1\x55\x3e\xe0",
93
.name = "HighPoint RAID controller",
33
102
grub_partition_msdos_iterate (grub_disk_t disk,
34
103
int (*hook) (grub_disk_t disk,
67
136
if (grub_disk_read (disk, p.offset, 0, sizeof (mbr), &mbr))
139
/* If this is a GPT partition, this MBR is just a dummy. */
141
for (i = 0; i < 4; i++)
142
if (mbr.entries[i].type == GRUB_PC_PARTITION_TYPE_GPT_DISK)
143
return grub_error (GRUB_ERR_BAD_PART_TABLE, "dummy mbr");
70
145
/* This is our loop-detection algorithm. It works the following way:
71
146
It saves last position which was a power of two. Then it compares the
72
147
saved value with a current one. This way it's guaranteed that the loop
93
168
e = mbr.entries + p.index;
95
p.start = p.offset + grub_le_to_cpu32 (e->start) - delta;
96
p.len = grub_le_to_cpu32 (e->length);
171
+ (grub_le_to_cpu32 (e->start)
172
<< (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)) - delta;
173
p.len = grub_le_to_cpu32 (e->length)
174
<< (disk->log_sector_size - GRUB_DISK_SECTOR_BITS);
97
175
p.msdostype = e->type;
99
177
grub_dprintf ("partition",
102
180
(unsigned long long) p.start,
103
181
(unsigned long long) p.len);
105
/* If this is a GPT partition, this MBR is just a dummy. */
106
if (e->type == GRUB_PC_PARTITION_TYPE_GPT_DISK && p.index == 0)
107
return grub_error (GRUB_ERR_BAD_PART_TABLE, "dummy mbr");
109
183
/* If this partition is a normal one, call the hook. */
110
184
if (! grub_msdos_partition_is_empty (e->type)
111
185
&& ! grub_msdos_partition_is_extended (e->type))
206
283
e = mbr.entries + i;
208
285
if (!grub_msdos_partition_is_empty (e->type)
209
&& end > offset + grub_le_to_cpu32 (e->start))
210
end = offset + grub_le_to_cpu32 (e->start);
287
+ (grub_le_to_cpu32 (e->start)
288
<< (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)))
289
end = offset + (grub_le_to_cpu32 (e->start)
290
<< (disk->log_sector_size - GRUB_DISK_SECTOR_BITS));
212
292
/* If this is a GPT partition, this MBR is just a dummy. */
213
293
if (e->type == GRUB_PC_PARTITION_TYPE_GPT_DISK && i == 0)
237
319
if (end >= *nsectors + 2)
322
char *embed_signature_check;
323
unsigned int orig_nsectors, avail_nsectors;
325
orig_nsectors = *nsectors;
240
326
*nsectors = end - 2;
327
avail_nsectors = *nsectors;
328
if (*nsectors > max_nsectors)
329
*nsectors = max_nsectors;
241
330
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
243
332
return grub_errno;
244
333
for (i = 0; i < *nsectors; i++)
245
334
(*sectors)[i] = 1 + i;
336
/* Check for software that is already using parts of the embedding
339
embed_signature_check = grub_malloc (GRUB_DISK_SECTOR_SIZE);
340
for (i = 0; i < *nsectors; i++)
342
if (grub_disk_read (disk, (*sectors)[i], 0, GRUB_DISK_SECTOR_SIZE,
343
embed_signature_check))
346
for (j = 0; j < ARRAY_SIZE (embed_signatures); j++)
347
if (! grub_memcmp (embed_signatures[j].signature,
348
embed_signature_check,
349
embed_signatures[j].signature_len))
351
if (j == ARRAY_SIZE (embed_signatures))
353
grub_util_warn (_(message_warn[embed_signatures[j].type]),
354
(*sectors)[i], embed_signatures[j].name);
356
if (avail_nsectors < *nsectors)
357
*nsectors = avail_nsectors;
359
/* Avoid this sector. */
360
for (j = i; j < *nsectors; j++)
363
/* Have we run out of space? */
364
if (avail_nsectors < orig_nsectors)
367
/* Make sure to check the next sector. */
370
grub_free (embed_signature_check);
372
if (*nsectors < orig_nsectors)
373
return grub_error (GRUB_ERR_OUT_OF_RANGE,
374
N_("other software is using the embedding area, and "
375
"there is not enough room for core.img. Such "
376
"software is often trying to store data in a way "
377
"that avoids detection. We recommend you "
246
380
return GRUB_ERR_NONE;
250
384
return grub_error (GRUB_ERR_FILE_NOT_FOUND,
251
"This msdos-style partition label has no "
252
"post-MBR gap; embedding won't be possible!");
385
N_("this msdos-style partition label has no "
386
"post-MBR gap; embedding won't be possible"));
254
388
if (*nsectors > 62)
255
389
return grub_error (GRUB_ERR_OUT_OF_RANGE,
256
"Your core.img is unusually large. "
257
"It won't fit in the embedding area.");
390
N_("your core.img is unusually large. "
391
"It won't fit in the embedding area"));
259
393
return grub_error (GRUB_ERR_OUT_OF_RANGE,
260
"Your embedding area is unusually small. "
261
"core.img won't fit in it.");
394
N_("your embedding area is unusually small. "
395
"core.img won't fit in it."));