* include/grub/partition.h (grub_partition_map): Change prototype of
embed to take a maximum value for nsectors. * include/grub/emu/hostdisk.h (grub_util_ldm_embed): Likewise. * include/grub/fs.h (grub_fs): Likewise. * grub-core/partmap/msdos.c (embed_signatures): New array. (pc_partition_map_embed): Check for and avoid sectors matching any of the signatures in embed_signatures, up to max_nsectors. * grub-core/partmap/gpt.c (gpt_partition_map_embed): Restrict returned sector map to max_nsectors. * grub-core/disk/ldm.c (grub_util_ldm_embed): Likewise. * grub-core/fs/btrfs.c (grub_btrfs_embed): Likewise. * grub-core/fs/zfs/zfs.c (grub_zfs_embed): Likewise. * util/grub-setup.c (setup): Allow for the embedding area being split into multiple blocklists. Tell dest_partmap->embed the maximum number of sectors we care about.
This commit is contained in:
commit
e3c78337c3
10 changed files with 175 additions and 17 deletions
25
ChangeLog
25
ChangeLog
|
@ -1,3 +1,28 @@
|
||||||
|
2012-02-27 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* include/grub/partition.h (grub_partition_map): Change prototype of
|
||||||
|
embed to take a maximum value for nsectors.
|
||||||
|
* include/grub/emu/hostdisk.h (grub_util_ldm_embed): Likewise.
|
||||||
|
* include/grub/fs.h (grub_fs): Likewise.
|
||||||
|
* grub-core/partmap/msdos.c (embed_signatures): New array.
|
||||||
|
(pc_partition_map_embed): Check for and avoid sectors matching any
|
||||||
|
of the signatures in embed_signatures, up to max_nsectors.
|
||||||
|
* grub-core/partmap/gpt.c (gpt_partition_map_embed): Restrict
|
||||||
|
returned sector map to max_nsectors.
|
||||||
|
* grub-core/disk/ldm.c (grub_util_ldm_embed): Likewise.
|
||||||
|
* grub-core/fs/btrfs.c (grub_btrfs_embed): Likewise.
|
||||||
|
* grub-core/fs/zfs/zfs.c (grub_zfs_embed): Likewise.
|
||||||
|
* util/grub-setup.c (setup): Allow for the embedding area being
|
||||||
|
split into multiple blocklists. Tell dest_partmap->embed the
|
||||||
|
maximum number of sectors we care about.
|
||||||
|
|
||||||
|
2012-02-27 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* include/grub/fs.h (grub_fs) [GRUB_UTIL]: Add blocklist_install field.
|
||||||
|
Specify blocklist_install and reserver_first_sector for all fs.
|
||||||
|
* util/grub-setup.c (setup): Use FIBMAP/FIEMAP on Linux. Check resulting
|
||||||
|
blocklists.
|
||||||
|
|
||||||
2012-02-27 Vladimir Serbinenko <phcoder@gmail.com>
|
2012-02-27 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* util/grub-install.in: Clarify strings.
|
* util/grub-install.in: Clarify strings.
|
||||||
|
|
|
@ -909,6 +909,7 @@ grub_util_is_ldm (grub_disk_t disk)
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
|
grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
|
||||||
|
unsigned int max_nsectors,
|
||||||
grub_embed_type_t embed_type,
|
grub_embed_type_t embed_type,
|
||||||
grub_disk_addr_t **sectors)
|
grub_disk_addr_t **sectors)
|
||||||
{
|
{
|
||||||
|
@ -967,6 +968,8 @@ grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
|
||||||
N_("your LDM embedding Partition is too small;"
|
N_("your LDM embedding Partition is too small;"
|
||||||
" embedding won't be possible"));
|
" embedding won't be possible"));
|
||||||
*nsectors = lv->size;
|
*nsectors = lv->size;
|
||||||
|
if (*nsectors > max_nsectors)
|
||||||
|
*nsectors = max_nsectors;
|
||||||
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
||||||
if (!*sectors)
|
if (!*sectors)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
|
@ -1620,6 +1620,7 @@ grub_btrfs_label (grub_device_t device, char **label)
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_btrfs_embed (grub_device_t device __attribute__ ((unused)),
|
grub_btrfs_embed (grub_device_t device __attribute__ ((unused)),
|
||||||
unsigned int *nsectors,
|
unsigned int *nsectors,
|
||||||
|
unsigned int max_nsectors,
|
||||||
grub_embed_type_t embed_type,
|
grub_embed_type_t embed_type,
|
||||||
grub_disk_addr_t **sectors)
|
grub_disk_addr_t **sectors)
|
||||||
{
|
{
|
||||||
|
@ -1635,6 +1636,8 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)),
|
||||||
"It won't fit in the embedding area"));
|
"It won't fit in the embedding area"));
|
||||||
|
|
||||||
*nsectors = 64 * 2 - 1;
|
*nsectors = 64 * 2 - 1;
|
||||||
|
if (*nsectors > max_nsectors)
|
||||||
|
*nsectors = max_nsectors;
|
||||||
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
||||||
if (!*sectors)
|
if (!*sectors)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
|
@ -3902,6 +3902,7 @@ grub_zfs_dir (grub_device_t device, const char *path,
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_zfs_embed (grub_device_t device __attribute__ ((unused)),
|
grub_zfs_embed (grub_device_t device __attribute__ ((unused)),
|
||||||
unsigned int *nsectors,
|
unsigned int *nsectors,
|
||||||
|
unsigned int max_nsectors,
|
||||||
grub_embed_type_t embed_type,
|
grub_embed_type_t embed_type,
|
||||||
grub_disk_addr_t **sectors)
|
grub_disk_addr_t **sectors)
|
||||||
{
|
{
|
||||||
|
@ -3917,6 +3918,8 @@ grub_zfs_embed (grub_device_t device __attribute__ ((unused)),
|
||||||
"It won't fit in the embedding area"));
|
"It won't fit in the embedding area"));
|
||||||
|
|
||||||
*nsectors = (VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS);
|
*nsectors = (VDEV_BOOT_SIZE >> GRUB_DISK_SECTOR_BITS);
|
||||||
|
if (*nsectors > max_nsectors)
|
||||||
|
*nsectors = max_nsectors;
|
||||||
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
||||||
if (!*sectors)
|
if (!*sectors)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
|
@ -128,6 +128,7 @@ grub_gpt_partition_map_iterate (grub_disk_t disk,
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
gpt_partition_map_embed (struct grub_disk *disk_, unsigned int *nsectors,
|
gpt_partition_map_embed (struct grub_disk *disk_, unsigned int *nsectors,
|
||||||
|
unsigned int max_nsectors,
|
||||||
grub_embed_type_t embed_type,
|
grub_embed_type_t embed_type,
|
||||||
grub_disk_addr_t **sectors)
|
grub_disk_addr_t **sectors)
|
||||||
{
|
{
|
||||||
|
@ -183,6 +184,8 @@ gpt_partition_map_embed (struct grub_disk *disk_, unsigned int *nsectors,
|
||||||
" embedding won't be possible"));
|
" embedding won't be possible"));
|
||||||
|
|
||||||
*nsectors = len;
|
*nsectors = len;
|
||||||
|
if (*nsectors > max_nsectors)
|
||||||
|
*nsectors = max_nsectors;
|
||||||
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
||||||
if (!*sectors)
|
if (!*sectors)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
|
@ -30,6 +30,66 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
static struct grub_partition_map grub_msdos_partition_map;
|
static struct grub_partition_map grub_msdos_partition_map;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef GRUB_UTIL
|
||||||
|
#include <grub/emu/misc.h>
|
||||||
|
|
||||||
|
struct embed_signature
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
const char *signature;
|
||||||
|
int signature_len;
|
||||||
|
enum { TYPE_SOFTWARE, TYPE_RAID } type;
|
||||||
|
};
|
||||||
|
|
||||||
|
const char message_warn[][200] = {
|
||||||
|
[TYPE_RAID] = N_("Sector %llu is already in use by %s; avoiding it. "
|
||||||
|
"Please ask the manufacturer not to store data in MBR gap"),
|
||||||
|
[TYPE_SOFTWARE] = N_("Sector %llu is already in use by %s; avoiding it. "
|
||||||
|
"This software may cause boot or other problems in "
|
||||||
|
"future. Please ask its authors not to store data "
|
||||||
|
"in the boot track")
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Signatures of other software that may be using sectors in the embedding
|
||||||
|
area. */
|
||||||
|
struct embed_signature embed_signatures[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.name = "ZISD",
|
||||||
|
.signature = "ZISD",
|
||||||
|
.signature_len = 4,
|
||||||
|
.type = TYPE_SOFTWARE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "FlexNet",
|
||||||
|
.signature = "\xd4\x41\xa0\xf5\x03\x00\x03\x00",
|
||||||
|
.signature_len = 8,
|
||||||
|
.type = TYPE_SOFTWARE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "FlexNet",
|
||||||
|
.signature = "\xd8\x41\xa0\xf5\x02\x00\x02\x00",
|
||||||
|
.signature_len = 8,
|
||||||
|
.type = TYPE_SOFTWARE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* from Ryan Perkins */
|
||||||
|
.name = "HP Backup and Recovery Manager (?)",
|
||||||
|
.signature = "\x70\x8a\x5d\x46\x35\xc5\x1b\x93"
|
||||||
|
"\xae\x3d\x86\xfd\xb1\x55\x3e\xe0",
|
||||||
|
.signature_len = 16,
|
||||||
|
.type = TYPE_SOFTWARE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "HighPoint RAID controller",
|
||||||
|
.signature = "ycgl",
|
||||||
|
.signature_len = 4,
|
||||||
|
.type = TYPE_RAID
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_partition_msdos_iterate (grub_disk_t disk,
|
grub_partition_msdos_iterate (grub_disk_t disk,
|
||||||
int (*hook) (grub_disk_t disk,
|
int (*hook) (grub_disk_t disk,
|
||||||
|
@ -154,6 +214,7 @@ grub_partition_msdos_iterate (grub_disk_t disk,
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors,
|
pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors,
|
||||||
|
unsigned int max_nsectors,
|
||||||
grub_embed_type_t embed_type,
|
grub_embed_type_t embed_type,
|
||||||
grub_disk_addr_t **sectors)
|
grub_disk_addr_t **sectors)
|
||||||
{
|
{
|
||||||
|
@ -247,13 +308,65 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors,
|
||||||
|
|
||||||
if (end >= *nsectors + 2)
|
if (end >= *nsectors + 2)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i, j;
|
||||||
|
char *embed_signature_check;
|
||||||
|
unsigned int orig_nsectors, avail_nsectors;
|
||||||
|
|
||||||
|
orig_nsectors = *nsectors;
|
||||||
*nsectors = end - 2;
|
*nsectors = end - 2;
|
||||||
|
avail_nsectors = *nsectors;
|
||||||
|
if (*nsectors > max_nsectors)
|
||||||
|
*nsectors = max_nsectors;
|
||||||
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
|
||||||
if (!*sectors)
|
if (!*sectors)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
for (i = 0; i < *nsectors; i++)
|
for (i = 0; i < *nsectors; i++)
|
||||||
(*sectors)[i] = 1 + i;
|
(*sectors)[i] = 1 + i;
|
||||||
|
|
||||||
|
/* Check for software that is already using parts of the embedding
|
||||||
|
* area.
|
||||||
|
*/
|
||||||
|
embed_signature_check = grub_malloc (GRUB_DISK_SECTOR_SIZE);
|
||||||
|
for (i = 0; i < *nsectors; i++)
|
||||||
|
{
|
||||||
|
if (grub_disk_read (disk, (*sectors)[i], 0, GRUB_DISK_SECTOR_SIZE,
|
||||||
|
embed_signature_check))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (j = 0; j < ARRAY_SIZE (embed_signatures); j++)
|
||||||
|
if (! grub_memcmp (embed_signatures[j].signature,
|
||||||
|
embed_signature_check,
|
||||||
|
embed_signatures[j].signature_len))
|
||||||
|
break;
|
||||||
|
if (j == ARRAY_SIZE (embed_signatures))
|
||||||
|
continue;
|
||||||
|
grub_util_warn (_(message_warn[embed_signatures[j].type]),
|
||||||
|
(*sectors)[i], embed_signatures[j].name);
|
||||||
|
avail_nsectors--;
|
||||||
|
if (avail_nsectors < *nsectors)
|
||||||
|
*nsectors = avail_nsectors;
|
||||||
|
|
||||||
|
/* Avoid this sector. */
|
||||||
|
for (j = i; j < *nsectors; j++)
|
||||||
|
(*sectors)[j]++;
|
||||||
|
|
||||||
|
/* Have we run out of space? */
|
||||||
|
if (avail_nsectors < orig_nsectors)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Make sure to check the next sector. */
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
grub_free (embed_signature_check);
|
||||||
|
|
||||||
|
if (*nsectors < orig_nsectors)
|
||||||
|
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||||
|
N_("other software is using the embedding area, and "
|
||||||
|
"there is not enough room for core.img. Such "
|
||||||
|
"software is often trying to store data in a way "
|
||||||
|
"that avoids detection. We recommend you "
|
||||||
|
"investigate"));
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ grub_util_is_ldm (grub_disk_t disk);
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
|
grub_util_ldm_embed (struct grub_disk *disk, unsigned int *nsectors,
|
||||||
|
unsigned int max_nsectors,
|
||||||
grub_embed_type_t embed_type,
|
grub_embed_type_t embed_type,
|
||||||
grub_disk_addr_t **sectors);
|
grub_disk_addr_t **sectors);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -81,6 +81,7 @@ struct grub_fs
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
/* Determine sectors available for embedding. */
|
/* Determine sectors available for embedding. */
|
||||||
grub_err_t (*embed) (grub_device_t device, unsigned int *nsectors,
|
grub_err_t (*embed) (grub_device_t device, unsigned int *nsectors,
|
||||||
|
unsigned int max_nsectors,
|
||||||
grub_embed_type_t embed_type,
|
grub_embed_type_t embed_type,
|
||||||
grub_disk_addr_t **sectors);
|
grub_disk_addr_t **sectors);
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ struct grub_partition_map
|
||||||
#ifdef GRUB_UTIL
|
#ifdef GRUB_UTIL
|
||||||
/* Determine sectors available for embedding. */
|
/* Determine sectors available for embedding. */
|
||||||
grub_err_t (*embed) (struct grub_disk *disk, unsigned int *nsectors,
|
grub_err_t (*embed) (struct grub_disk *disk, unsigned int *nsectors,
|
||||||
|
unsigned int max_nsectors,
|
||||||
grub_embed_type_t embed_type,
|
grub_embed_type_t embed_type,
|
||||||
grub_disk_addr_t **sectors);
|
grub_disk_addr_t **sectors);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -337,7 +337,7 @@ setup (const char *dir,
|
||||||
grub_disk_addr_t *sectors;
|
grub_disk_addr_t *sectors;
|
||||||
int i;
|
int i;
|
||||||
grub_fs_t fs;
|
grub_fs_t fs;
|
||||||
unsigned int nsec;
|
unsigned int nsec, maxsec;
|
||||||
|
|
||||||
/* Unlike root_dev, with dest_dev we're interested in the partition map even
|
/* Unlike root_dev, with dest_dev we're interested in the partition map even
|
||||||
if dest_dev itself is a whole disk. */
|
if dest_dev itself is a whole disk. */
|
||||||
|
@ -457,14 +457,21 @@ setup (const char *dir,
|
||||||
}
|
}
|
||||||
|
|
||||||
nsec = core_sectors;
|
nsec = core_sectors;
|
||||||
|
|
||||||
|
maxsec = 2 * core_sectors;
|
||||||
|
if (maxsec > ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR)
|
||||||
|
>> GRUB_DISK_SECTOR_BITS))
|
||||||
|
maxsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR)
|
||||||
|
>> GRUB_DISK_SECTOR_BITS);
|
||||||
|
|
||||||
if (is_ldm)
|
if (is_ldm)
|
||||||
err = grub_util_ldm_embed (dest_dev->disk, &nsec,
|
err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec,
|
||||||
GRUB_EMBED_PCBIOS, §ors);
|
GRUB_EMBED_PCBIOS, §ors);
|
||||||
else if (dest_partmap)
|
else if (dest_partmap)
|
||||||
err = dest_partmap->embed (dest_dev->disk, &nsec,
|
err = dest_partmap->embed (dest_dev->disk, &nsec, maxsec,
|
||||||
GRUB_EMBED_PCBIOS, §ors);
|
GRUB_EMBED_PCBIOS, §ors);
|
||||||
else
|
else
|
||||||
err = fs->embed (dest_dev, &nsec,
|
err = fs->embed (dest_dev, &nsec, maxsec,
|
||||||
GRUB_EMBED_PCBIOS, §ors);
|
GRUB_EMBED_PCBIOS, §ors);
|
||||||
if (!err && nsec < core_sectors)
|
if (!err && nsec < core_sectors)
|
||||||
{
|
{
|
||||||
|
@ -472,6 +479,8 @@ setup (const char *dir,
|
||||||
N_("Your embedding area is unusually small. "
|
N_("Your embedding area is unusually small. "
|
||||||
"core.img won't fit in it."));
|
"core.img won't fit in it."));
|
||||||
}
|
}
|
||||||
|
err = dest_partmap->embed (dest_dev->disk, &nsec, maxsec,
|
||||||
|
GRUB_EMBED_PCBIOS, §ors);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
|
@ -480,12 +489,7 @@ setup (const char *dir,
|
||||||
goto unable_to_embed;
|
goto unable_to_embed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsec > 2 * core_sectors)
|
assert (nsec <= maxsec);
|
||||||
nsec = 2 * core_sectors;
|
|
||||||
if (nsec > ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR)
|
|
||||||
>> GRUB_DISK_SECTOR_BITS))
|
|
||||||
nsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR)
|
|
||||||
>> GRUB_DISK_SECTOR_BITS);
|
|
||||||
|
|
||||||
/* Clean out the blocklists. */
|
/* Clean out the blocklists. */
|
||||||
block = first_block;
|
block = first_block;
|
||||||
|
@ -507,6 +511,13 @@ setup (const char *dir,
|
||||||
save_blocklists (sectors[i] + grub_partition_get_start (container),
|
save_blocklists (sectors[i] + grub_partition_get_start (container),
|
||||||
0, GRUB_DISK_SECTOR_SIZE);
|
0, GRUB_DISK_SECTOR_SIZE);
|
||||||
|
|
||||||
|
/* Make sure that the last blocklist is a terminator. */
|
||||||
|
if (block == first_block)
|
||||||
|
block--;
|
||||||
|
block->start = 0;
|
||||||
|
block->len = 0;
|
||||||
|
block->segment = 0;
|
||||||
|
|
||||||
write_rootdev (core_img, root_dev, boot_img, first_sector);
|
write_rootdev (core_img, root_dev, boot_img, first_sector);
|
||||||
|
|
||||||
core_img = realloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE);
|
core_img = realloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE);
|
||||||
|
@ -535,12 +546,6 @@ setup (const char *dir,
|
||||||
assert (grub_memcmp (tmp, core_img, core_size) == 0);
|
assert (grub_memcmp (tmp, core_img, core_size) == 0);
|
||||||
free (tmp);
|
free (tmp);
|
||||||
|
|
||||||
/* Make sure that the second blocklist is a terminator. */
|
|
||||||
block = first_block - 1;
|
|
||||||
block->start = 0;
|
|
||||||
block->len = 0;
|
|
||||||
block->segment = 0;
|
|
||||||
|
|
||||||
/* Write the core image onto the disk. */
|
/* Write the core image onto the disk. */
|
||||||
for (i = 0; i < nsec; i++)
|
for (i = 0; i < nsec; i++)
|
||||||
grub_disk_write (dest_dev->disk, sectors[i], 0,
|
grub_disk_write (dest_dev->disk, sectors[i], 0,
|
||||||
|
|
Loading…
Reference in a new issue