Reimport nestpart
This commit is contained in:
parent
bf7fcba2d7
commit
15cb7d433f
26 changed files with 561 additions and 720 deletions
73
ChangeLog.nestpart
Normal file
73
ChangeLog.nestpart
Normal file
|
@ -0,0 +1,73 @@
|
|||
2009-06-08 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Nested partitions
|
||||
|
||||
* commands/blocklist.c (grub_cmd_blocklist): Don't check whether
|
||||
'partition' is NULL, grub_partition_get_start already does that.
|
||||
* commands/loadenv.c (check_blocklists): Likewise.
|
||||
(write_blocklists): Likewise.
|
||||
* conf/common.rmk (grub_probe_SOURCES): Add partmap/bsdlabel.c.
|
||||
(grub_fstest_SOURCES): Likewise.
|
||||
(pkglib_MODULES): Add bsdlabel.mod.
|
||||
(bsdlabel_mod_SOURCES): New variable.
|
||||
(bsdlabel_mod_CFLAGS): Likewise.
|
||||
(bsdlabel_mod_LDFLAGS): Likewise.
|
||||
* conf/i386-coreboot.rmk (grub_emu_SOURCES): Add partmap/bsdlabel.c.
|
||||
* conf/i386-pc.rmk (grub_setup_SOURCES): Likewise.
|
||||
(grub_emu_SOURCES): Likewise.
|
||||
* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
|
||||
* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise.
|
||||
* include/grub/bsdlabel.h: New file.
|
||||
* include/grub/partition.h (grub_partition_map): Remove 'probe' and
|
||||
'get_name'.
|
||||
(grub_partition): Add 'parent' and 'number'.
|
||||
(grub_partition_get_start): Handle nested partitions.
|
||||
* include/grub/pc_partition.h: Remove bsd-related entries.
|
||||
(grub_pc_partition): Remove.
|
||||
* kern/disk.c (grub_disk_close): Free partition data.
|
||||
(grub_disk_adjust_range): Handle nested partitions.
|
||||
* kern/partition.c (grub_partition_map_probe): New function.
|
||||
(grub_partition_probe): Parse name to number, handle subpartitions.
|
||||
(get_partmap): New function.
|
||||
(grub_partition_iterate): Handle subpartitions.
|
||||
(grub_partition_get_name): Likewise.
|
||||
* loader/i386/pc/bsd.c (grub_bsd_get_device): Likewise.
|
||||
* loader/i386/multiboot.c (grub_multiboot_get_bootdev): Likewise.
|
||||
* loader/i386/pc/chainloader.c (grub_chainloader_cmd): Likewise.
|
||||
* partmap/acorn.c (acorn_partition_map_iterate): Don't force raw access.
|
||||
Set 'number'.
|
||||
(acorn_partition_map_probe): Remove.
|
||||
(acorn_partition_map_get_name): Likewise.
|
||||
* partmap/amiga.c (amiga_partition_map_iterate): Don't force raw access.
|
||||
Set 'number'.
|
||||
Set 'index' to 0 since there can be only one partition entry per sector.
|
||||
(amiga_partition_map_probe): Remove.
|
||||
(amiga_partition_map_get_name): Likewise.
|
||||
* partmap/apple.c (apple_partition_map_iterate): Don't force raw access.
|
||||
Set 'number'.
|
||||
Set 'offset' and 'index' to real positions of partitions.
|
||||
(apple_partition_map_probe): Remove.
|
||||
(apple_partition_map_get_name): Likewise.
|
||||
* partmap/bsdlabel.c: New file.
|
||||
* partmap/gpt.c (gpt_partition_map_iterate): Don't force raw access.
|
||||
Set 'number'.
|
||||
Allocate 'data' so it can be correctly freed.
|
||||
Set 'index' to offset inside sector.
|
||||
(gpt_partition_map_probe): Remove.
|
||||
(gpt_partition_map_get_name): Likewise.
|
||||
* partmap/pc.c (grub_partition_parse): Remove.
|
||||
(pc_partition_map_iterate): Don't force raw access.
|
||||
Set 'number'.
|
||||
Make 'ext_offset' a local variable.
|
||||
(pc_partition_map_probe): Remove.
|
||||
(pc_partition_map_get_name): Remove.
|
||||
* partmap/sun.c (sun_partition_map_iterate): Don't force raw access.
|
||||
Set 'number'.
|
||||
(sun_partition_map_probe): Remove.
|
||||
(sun_partition_map_get_name): Likewise.
|
||||
* parttool/pcpart.c (grub_pcpart_boot): Handle nested partitions.
|
||||
(grub_pcpart_type): Likewise.
|
||||
* util/hostdisk.c (open_device): Handle new numbering scheme.
|
||||
(grub_util_biosdisk_get_grub_dev): Handle nested partitions.
|
||||
* util/i386/pc/grub-setup.c (setup): Handle new numbering scheme.
|
||||
* util/grub-probe.c (probe_partmap): Handle nested paritions.
|
|
@ -90,7 +90,6 @@ grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)),
|
|||
return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
"this command is available only for disk devices");
|
||||
|
||||
if (file->device->disk->partition)
|
||||
part_start = grub_partition_get_start (file->device->disk->partition);
|
||||
|
||||
file->read_hook = read_blocklist;
|
||||
|
|
|
@ -235,10 +235,8 @@ check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
|
|||
/* One more sanity check. Re-read all sectors by blocklists, and compare
|
||||
those with the data read via a file. */
|
||||
disk = file->device->disk;
|
||||
if (disk->partition)
|
||||
|
||||
part_start = grub_partition_get_start (disk->partition);
|
||||
else
|
||||
part_start = 0;
|
||||
|
||||
buf = grub_envblk_buffer (envblk);
|
||||
for (p = blocklists, index = 0; p; index += p->length, p = p->next)
|
||||
|
@ -268,10 +266,7 @@ write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
|
|||
|
||||
buf = grub_envblk_buffer (envblk);
|
||||
disk = file->device->disk;
|
||||
if (disk->partition)
|
||||
part_start = grub_partition_get_start (disk->partition);
|
||||
else
|
||||
part_start = 0;
|
||||
|
||||
index = 0;
|
||||
for (p = blocklists; p; index += p->length, p = p->next)
|
||||
|
|
|
@ -34,7 +34,7 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
|
|||
script/main.c script/execute.c script/function.c \
|
||||
script/lexer.c script/script.c grub_script.tab.c \
|
||||
partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \
|
||||
partmap/acorn.c partmap/gpt.c \
|
||||
partmap/acorn.c partmap/gpt.c partmap/bsd.c \
|
||||
\
|
||||
fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \
|
||||
fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
|
||||
|
|
|
@ -32,7 +32,8 @@ grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \
|
|||
fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \
|
||||
fs/befs.c fs/befs_be.c fs/tar.c \
|
||||
\
|
||||
partmap/msdos.c partmap/apple.c partmap/sun.c partmap/gpt.c\
|
||||
partmap/msdos.c partmap/bsdlabel.c partmap/apple.c \
|
||||
partmap/sun.c partmap/gpt.c\
|
||||
kern/fs.c kern/env.c fs/fshelp.c \
|
||||
disk/raid.c disk/mdraid_linux.c disk/lvm.c grub_probe_init.c
|
||||
|
||||
|
@ -69,8 +70,8 @@ grub_fstest_SOURCES = gnulib/progname.c util/grub-fstest.c util/hostfs.c \
|
|||
fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c \
|
||||
fs/befs_be.c fs/tar.c \
|
||||
\
|
||||
kern/partition.c partmap/msdos.c partmap/apple.c partmap/sun.c \
|
||||
partmap/gpt.c \
|
||||
kern/partition.c partmap/msdos.c partmap/bsdlabel.c \
|
||||
partmap/apple.c partmap/sun.c partmap/gpt.c \
|
||||
kern/fs.c kern/env.c fs/fshelp.c disk/raid.c \
|
||||
disk/raid5_recover.c disk/raid6_recover.c \
|
||||
disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \
|
||||
|
@ -376,6 +377,11 @@ part_gpt_mod_SOURCES = partmap/gpt.c
|
|||
part_gpt_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||
part_gpt_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||
|
||||
pkglib_MODULES += part_bsd.mod
|
||||
part_bsd_mod_SOURCES = partmap/bsdlabel.c
|
||||
part_bsd_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||
part_bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||
|
||||
# Special disk structures and generic drivers
|
||||
|
||||
pkglib_MODULES += raid.mod raid5rec.mod raid6rec.mod mdraid.mod dm_nv.mod \
|
||||
|
|
|
@ -104,7 +104,7 @@ grub_setup_SOURCES = gnulib/progname.c \
|
|||
fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \
|
||||
fs/befs.c fs/befs_be.c fs/tar.c \
|
||||
\
|
||||
partmap/msdos.c partmap/gpt.c \
|
||||
partmap/msdos.c partmap/bsdlabel.c partmap/gpt.c \
|
||||
\
|
||||
disk/raid.c disk/mdraid_linux.c disk/lvm.c \
|
||||
util/raid.c util/lvm.c \
|
||||
|
|
|
@ -79,7 +79,7 @@ grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \
|
|||
fs/befs.c fs/befs_be.c fs/tar.c \
|
||||
\
|
||||
partmap/amiga.c partmap/apple.c partmap/msdos.c \
|
||||
partmap/sun.c partmap/acorn.c \
|
||||
partmap/bsdlabel.c partmap/sun.c partmap/acorn.c \
|
||||
\
|
||||
disk/raid.c disk/mdraid_linux.c disk/lvm.c \
|
||||
util/raid.c util/lvm.c gnulib/progname.c \
|
||||
|
|
89
include/grub/bsdlabel.h
Normal file
89
include/grub/bsdlabel.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2004,2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRUB_BSDLABEL_PARTITION_HEADER
|
||||
#define GRUB_BSDLABEL_PARTITION_HEADER 1
|
||||
|
||||
/* Constants for BSD disk label. */
|
||||
#define GRUB_PC_PARTITION_BSD_LABEL_SECTOR 1
|
||||
#define GRUB_PC_PARTITION_BSD_LABEL_MAGIC 0x82564557
|
||||
|
||||
/* BSD partition types. */
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_UNUSED 0
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_SWAP 1
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_V6 2
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_V7 3
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_SYSV 4
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_V71K 5
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_V8 6
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_BSDFFS 7
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_MSDOS 8
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_BSDLFS 9
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_OTHER 10
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_HPFS 11
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_ISO9660 12
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_BOOT 13
|
||||
|
||||
/* FreeBSD-specific types. */
|
||||
#define GRUB_PC_PARTITION_FREEBSD_TYPE_VINUM 14
|
||||
#define GRUB_PC_PARTITION_FREEBSD_TYPE_RAID 15
|
||||
#define GRUB_PC_PARTITION_FREEBSD_TYPE_JFS2 21
|
||||
|
||||
/* NetBSD-specific types. */
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_ADOS 14
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_HFS 15
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_FILECORE 16
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_EXT2FS 17
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_NTFS 18
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_RAID 19
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_CCD 20
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_JFS2 21
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_APPLEUFS 22
|
||||
|
||||
/* OpenBSD-specific types. */
|
||||
#define GRUB_PC_PARTITION_OPENBSD_TYPE_ADOS 14
|
||||
#define GRUB_PC_PARTITION_OPENBSD_TYPE_HFS 15
|
||||
#define GRUB_PC_PARTITION_OPENBSD_TYPE_FILECORE 16
|
||||
#define GRUB_PC_PARTITION_OPENBSD_TYPE_EXT2FS 17
|
||||
#define GRUB_PC_PARTITION_OPENBSD_TYPE_NTFS 18
|
||||
#define GRUB_PC_PARTITION_OPENBSD_TYPE_RAID 19
|
||||
|
||||
/* The BSD partition entry. */
|
||||
struct grub_partition_bsd_entry
|
||||
{
|
||||
grub_uint32_t size;
|
||||
grub_uint32_t offset;
|
||||
grub_uint32_t fragment_size;
|
||||
grub_uint8_t fs_type;
|
||||
grub_uint8_t fs_fragments;
|
||||
grub_uint16_t fs_cylinders;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* The BSD disk label. Only define members useful for GRUB. */
|
||||
struct grub_partition_bsd_disk_label
|
||||
{
|
||||
grub_uint32_t magic;
|
||||
grub_uint8_t padding[128];
|
||||
grub_uint32_t magic2;
|
||||
grub_uint16_t checksum;
|
||||
grub_uint16_t num_partitions;
|
||||
grub_uint32_t boot_size;
|
||||
grub_uint32_t superblock_size;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif /* ! GRUB_PC_PARTITION_HEADER */
|
|
@ -53,75 +53,6 @@
|
|||
#define GRUB_PC_PARTITION_TYPE_GPT_DISK 0xee
|
||||
#define GRUB_PC_PARTITION_TYPE_LINUX_RAID 0xfd
|
||||
|
||||
/* Constants for BSD disk label. */
|
||||
#define GRUB_PC_PARTITION_BSD_LABEL_SECTOR 1
|
||||
#define GRUB_PC_PARTITION_BSD_LABEL_MAGIC 0x82564557
|
||||
#define GRUB_PC_PARTITION_BSD_MAX_ENTRIES 8
|
||||
|
||||
/* BSD partition types. */
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_UNUSED 0
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_SWAP 1
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_V6 2
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_V7 3
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_SYSV 4
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_V71K 5
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_V8 6
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_BSDFFS 7
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_MSDOS 8
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_BSDLFS 9
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_OTHER 10
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_HPFS 11
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_ISO9660 12
|
||||
#define GRUB_PC_PARTITION_BSD_TYPE_BOOT 13
|
||||
|
||||
/* FreeBSD-specific types. */
|
||||
#define GRUB_PC_PARTITION_FREEBSD_TYPE_VINUM 14
|
||||
#define GRUB_PC_PARTITION_FREEBSD_TYPE_RAID 15
|
||||
#define GRUB_PC_PARTITION_FREEBSD_TYPE_JFS2 21
|
||||
|
||||
/* NetBSD-specific types. */
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_ADOS 14
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_HFS 15
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_FILECORE 16
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_EXT2FS 17
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_NTFS 18
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_RAID 19
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_CCD 20
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_JFS2 21
|
||||
#define GRUB_PC_PARTITION_NETBSD_TYPE_APPLEUFS 22
|
||||
|
||||
/* OpenBSD-specific types. */
|
||||
#define GRUB_PC_PARTITION_OPENBSD_TYPE_ADOS 14
|
||||
#define GRUB_PC_PARTITION_OPENBSD_TYPE_HFS 15
|
||||
#define GRUB_PC_PARTITION_OPENBSD_TYPE_FILECORE 16
|
||||
#define GRUB_PC_PARTITION_OPENBSD_TYPE_EXT2FS 17
|
||||
#define GRUB_PC_PARTITION_OPENBSD_TYPE_NTFS 18
|
||||
#define GRUB_PC_PARTITION_OPENBSD_TYPE_RAID 19
|
||||
|
||||
/* The BSD partition entry. */
|
||||
struct grub_msdos_partition_bsd_entry
|
||||
{
|
||||
grub_uint32_t size;
|
||||
grub_uint32_t offset;
|
||||
grub_uint32_t fragment_size;
|
||||
grub_uint8_t fs_type;
|
||||
grub_uint8_t fs_fragments;
|
||||
grub_uint16_t fs_cylinders;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* The BSD disk label. Only define members useful for GRUB. */
|
||||
struct grub_msdos_partition_disk_label
|
||||
{
|
||||
grub_uint32_t magic;
|
||||
grub_uint8_t padding[128];
|
||||
grub_uint32_t magic2;
|
||||
grub_uint16_t checksum;
|
||||
grub_uint16_t num_partitions;
|
||||
grub_uint32_t boot_size;
|
||||
grub_uint32_t superblock_size;
|
||||
struct grub_msdos_partition_bsd_entry entries[GRUB_PC_PARTITION_BSD_MAX_ENTRIES];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* The partition entry. */
|
||||
struct grub_msdos_partition_entry
|
||||
{
|
||||
|
@ -168,23 +99,6 @@ struct grub_msdos_partition_mbr
|
|||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct grub_msdos_partition
|
||||
{
|
||||
/* The DOS partition number. */
|
||||
int dos_part;
|
||||
|
||||
/* The BSD partition number (a == 0). */
|
||||
int bsd_part;
|
||||
|
||||
/* The DOS partition type. */
|
||||
int dos_type;
|
||||
|
||||
/* The BSD partition type. */
|
||||
int bsd_type;
|
||||
|
||||
/* The offset of the extended partition. */
|
||||
unsigned long ext_offset;
|
||||
};
|
||||
|
||||
static inline int
|
||||
grub_msdos_partition_is_empty (int type)
|
||||
|
@ -200,12 +114,4 @@ grub_msdos_partition_is_extended (int type)
|
|||
|| type == GRUB_PC_PARTITION_TYPE_LINUX_EXTENDED);
|
||||
}
|
||||
|
||||
static inline int
|
||||
grub_msdos_partition_is_bsd (int type)
|
||||
{
|
||||
return (type == GRUB_PC_PARTITION_TYPE_FREEBSD
|
||||
|| type == GRUB_PC_PARTITION_TYPE_OPENBSD
|
||||
|| type == GRUB_PC_PARTITION_TYPE_NETBSD);
|
||||
}
|
||||
|
||||
#endif /* ! GRUB_PC_PARTITION_HEADER */
|
||||
|
|
|
@ -36,13 +36,6 @@ struct grub_partition_map
|
|||
int (*hook) (struct grub_disk *disk,
|
||||
const grub_partition_t partition));
|
||||
|
||||
/* Return the partition named STR on the disk DISK. */
|
||||
grub_partition_t (*probe) (struct grub_disk *disk,
|
||||
const char *str);
|
||||
|
||||
/* Return the name of the partition PARTITION. */
|
||||
char *(*get_name) (const grub_partition_t partition);
|
||||
|
||||
/* The next partition map type. */
|
||||
struct grub_partition_map *next;
|
||||
};
|
||||
|
@ -51,6 +44,9 @@ typedef struct grub_partition_map *grub_partition_map_t;
|
|||
/* Partition description. */
|
||||
struct grub_partition
|
||||
{
|
||||
/* The partition number. */
|
||||
int number;
|
||||
|
||||
/* The start sector. */
|
||||
grub_disk_addr_t start;
|
||||
|
||||
|
@ -66,6 +62,9 @@ struct grub_partition
|
|||
/* Partition map type specific data. */
|
||||
void *data;
|
||||
|
||||
/* Parent partition map. */
|
||||
struct grub_partition *parent;
|
||||
|
||||
/* The type partition map. */
|
||||
grub_partition_map_t partmap;
|
||||
};
|
||||
|
@ -101,7 +100,13 @@ void grub_apple_partition_map_fini (void);
|
|||
static inline grub_disk_addr_t
|
||||
grub_partition_get_start (const grub_partition_t p)
|
||||
{
|
||||
return p->start;
|
||||
grub_partition_t part;
|
||||
grub_uint64_t part_start = 0;
|
||||
|
||||
for (part = p; part; part = part->parent)
|
||||
part_start += part->start;
|
||||
|
||||
return part_start;
|
||||
}
|
||||
|
||||
static inline grub_uint64_t
|
||||
|
|
14
kern/disk.c
14
kern/disk.c
|
@ -330,6 +330,7 @@ grub_disk_open (const char *name)
|
|||
void
|
||||
grub_disk_close (grub_disk_t disk)
|
||||
{
|
||||
grub_partition_t part;
|
||||
grub_dprintf ("disk", "Closing `%s'.\n", disk->name);
|
||||
|
||||
if (disk->dev && disk->dev->close)
|
||||
|
@ -338,7 +339,13 @@ grub_disk_close (grub_disk_t disk)
|
|||
/* Reset the timer. */
|
||||
grub_last_time = grub_get_time_ms ();
|
||||
|
||||
while (disk->partition)
|
||||
{
|
||||
part = disk->partition->parent;
|
||||
grub_free (disk->partition->data);
|
||||
grub_free (disk->partition);
|
||||
disk->partition = part;
|
||||
}
|
||||
grub_free ((void *) disk->name);
|
||||
grub_free (disk);
|
||||
}
|
||||
|
@ -351,16 +358,17 @@ static grub_err_t
|
|||
grub_disk_adjust_range (grub_disk_t disk, grub_disk_addr_t *sector,
|
||||
grub_off_t *offset, grub_size_t size)
|
||||
{
|
||||
grub_partition_t part;
|
||||
*sector += *offset >> GRUB_DISK_SECTOR_BITS;
|
||||
*offset &= GRUB_DISK_SECTOR_SIZE - 1;
|
||||
|
||||
if (disk->partition)
|
||||
for (part = disk->partition; part; part = part->parent)
|
||||
{
|
||||
grub_disk_addr_t start;
|
||||
grub_uint64_t len;
|
||||
|
||||
start = grub_partition_get_start (disk->partition);
|
||||
len = grub_partition_get_len (disk->partition);
|
||||
start = part->start;
|
||||
len = part->len;
|
||||
|
||||
if (*sector >= len
|
||||
|| len - *sector < ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1)
|
||||
|
|
158
kern/partition.c
158
kern/partition.c
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/disk.h>
|
||||
|
||||
|
@ -54,17 +55,58 @@ grub_partition_map_iterate (int (*hook) (const grub_partition_map_t partmap))
|
|||
return 0;
|
||||
}
|
||||
|
||||
static grub_partition_t
|
||||
grub_partition_map_probe (const grub_partition_map_t partmap,
|
||||
grub_disk_t disk, int partnum)
|
||||
{
|
||||
grub_partition_t p = 0;
|
||||
|
||||
auto int find_func (grub_disk_t d, const grub_partition_t partition);
|
||||
|
||||
int find_func (grub_disk_t d __attribute__ ((unused)),
|
||||
const grub_partition_t partition)
|
||||
{
|
||||
if (partnum == partition->number)
|
||||
{
|
||||
p = (grub_partition_t) grub_malloc (sizeof (*p));
|
||||
if (! p)
|
||||
return 1;
|
||||
|
||||
grub_memcpy (p, partition, sizeof (*p));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
partmap->iterate (disk, find_func);
|
||||
if (grub_errno)
|
||||
goto fail;
|
||||
|
||||
return p;
|
||||
|
||||
fail:
|
||||
grub_free (p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_partition_t
|
||||
grub_partition_probe (struct grub_disk *disk, const char *str)
|
||||
{
|
||||
grub_partition_t part = 0;
|
||||
grub_partition_t curpart = 0;
|
||||
grub_partition_t tail;
|
||||
const char *ptr;
|
||||
int num;
|
||||
|
||||
auto int part_map_probe (const grub_partition_map_t partmap);
|
||||
|
||||
int part_map_probe (const grub_partition_map_t partmap)
|
||||
{
|
||||
part = partmap->probe (disk, str);
|
||||
if (part)
|
||||
disk->partition = part;
|
||||
curpart = grub_partition_map_probe (partmap, disk, num);
|
||||
disk->partition = tail;
|
||||
if (curpart)
|
||||
return 1;
|
||||
|
||||
if (grub_errno == GRUB_ERR_BAD_PART_TABLE)
|
||||
|
@ -77,27 +119,54 @@ grub_partition_probe (struct grub_disk *disk, const char *str)
|
|||
return 1;
|
||||
}
|
||||
|
||||
part = tail = disk->partition;
|
||||
|
||||
for (ptr = str; *ptr;)
|
||||
{
|
||||
/* BSD-like partition specification. */
|
||||
if (*ptr >= 'a' && *ptr <= 'z')
|
||||
num = *(ptr++) - 'a';
|
||||
else
|
||||
num = grub_strtoul (ptr, (char **) &ptr, 0) - 1;
|
||||
|
||||
curpart = 0;
|
||||
/* Use the first partition map type found. */
|
||||
grub_partition_map_iterate (part_map_probe);
|
||||
|
||||
if (! curpart)
|
||||
{
|
||||
while (part)
|
||||
{
|
||||
curpart = part->parent;
|
||||
grub_free (part);
|
||||
part = curpart;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
curpart->parent = part;
|
||||
part = curpart;
|
||||
if (! ptr || *ptr != ',')
|
||||
break;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return part;
|
||||
}
|
||||
|
||||
int
|
||||
grub_partition_iterate (struct grub_disk *disk,
|
||||
int (*hook) (grub_disk_t disk,
|
||||
const grub_partition_t partition))
|
||||
static grub_partition_map_t
|
||||
get_partmap (struct grub_disk *disk)
|
||||
{
|
||||
grub_partition_map_t partmap = 0;
|
||||
int ret = 0;
|
||||
|
||||
struct grub_partition part;
|
||||
int found = 0;
|
||||
auto int part_map_iterate (const grub_partition_map_t p);
|
||||
auto int part_map_iterate_hook (grub_disk_t d,
|
||||
const grub_partition_t partition);
|
||||
|
||||
int part_map_iterate_hook (grub_disk_t d __attribute__ ((unused)),
|
||||
const grub_partition_t partition __attribute__ ((unused)))
|
||||
const grub_partition_t partition)
|
||||
{
|
||||
found = 1;
|
||||
part = *partition;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -106,22 +175,58 @@ grub_partition_iterate (struct grub_disk *disk,
|
|||
grub_dprintf ("partition", "Detecting %s...\n", p->name);
|
||||
p->iterate (disk, part_map_iterate_hook);
|
||||
|
||||
if (grub_errno != GRUB_ERR_NONE)
|
||||
if (grub_errno != GRUB_ERR_NONE || ! found)
|
||||
{
|
||||
/* Continue to next partition map type. */
|
||||
grub_dprintf ("partition", "%s detection failed.\n", p->name);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return 0;
|
||||
}
|
||||
grub_free (part.data);
|
||||
|
||||
grub_dprintf ("partition", "%s detection succeeded.\n", p->name);
|
||||
partmap = p;
|
||||
return 1;
|
||||
}
|
||||
|
||||
grub_partition_map_iterate (part_map_iterate);
|
||||
return partmap;
|
||||
}
|
||||
|
||||
int
|
||||
grub_partition_iterate (struct grub_disk *disk,
|
||||
int (*hook) (grub_disk_t disk,
|
||||
const grub_partition_t partition))
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
auto int part_iterate (grub_disk_t dsk, const grub_partition_t p);
|
||||
|
||||
int part_iterate (grub_disk_t dsk,
|
||||
const grub_partition_t partition)
|
||||
{
|
||||
struct grub_partition p = *partition;
|
||||
grub_partition_map_t partmap = 0;
|
||||
p.parent = dsk->partition;
|
||||
dsk->partition = 0;
|
||||
if (hook (dsk, &p))
|
||||
return 1;
|
||||
if (p.start != 0)
|
||||
{
|
||||
dsk->partition = &p;
|
||||
partmap = get_partmap (dsk);
|
||||
if (partmap)
|
||||
ret = partmap->iterate (disk, hook);
|
||||
ret = partmap->iterate (dsk, part_iterate);
|
||||
}
|
||||
dsk->partition = p.parent;
|
||||
return ret;
|
||||
}
|
||||
|
||||
{
|
||||
grub_partition_map_t partmap = 0;
|
||||
partmap = get_partmap (disk);
|
||||
if (partmap)
|
||||
ret = partmap->iterate (disk, part_iterate);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -129,5 +234,30 @@ grub_partition_iterate (struct grub_disk *disk,
|
|||
char *
|
||||
grub_partition_get_name (const grub_partition_t partition)
|
||||
{
|
||||
return partition->partmap->get_name (partition);
|
||||
char *out = 0;
|
||||
/* Even on 64-bit machines this buffer is enough to hold longest number. */
|
||||
char buf[25];
|
||||
int curlen = 0;
|
||||
grub_partition_t part;
|
||||
for (part = partition; part; part = part->parent)
|
||||
{
|
||||
int strl;
|
||||
grub_snprintf (buf, sizeof (buf), "%d", part->number + 1);
|
||||
strl = grub_strlen (buf);
|
||||
if (curlen)
|
||||
{
|
||||
out = grub_realloc (out, curlen + strl + 2);
|
||||
grub_memcpy (out + strl + 1, out, curlen);
|
||||
out[curlen + 1 + strl] = 0;
|
||||
grub_memcpy (out, buf, strl);
|
||||
out[strl] = ',';
|
||||
curlen = curlen + 1 + strl;
|
||||
}
|
||||
else
|
||||
{
|
||||
curlen = strl;
|
||||
out = grub_strdup (buf);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -140,7 +140,6 @@ grub_bsd_get_device (grub_uint32_t * biosdev,
|
|||
grub_uint32_t * unit,
|
||||
grub_uint32_t * slice, grub_uint32_t * part)
|
||||
{
|
||||
char *p;
|
||||
grub_device_t dev;
|
||||
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
|
@ -154,21 +153,13 @@ grub_bsd_get_device (grub_uint32_t * biosdev,
|
|||
dev = grub_device_open (0);
|
||||
if (dev && dev->disk && dev->disk->partition)
|
||||
{
|
||||
|
||||
p = dev->disk->partition->partmap->get_name (dev->disk->partition);
|
||||
if (p)
|
||||
if (dev->disk->partition->parent)
|
||||
{
|
||||
if ((p[0] >= '0') && (p[0] <= '9'))
|
||||
{
|
||||
*slice = grub_strtoul (p, &p, 0);
|
||||
|
||||
if ((p) && (p[0] == ','))
|
||||
p++;
|
||||
}
|
||||
|
||||
if ((p[0] >= 'a') && (p[0] <= 'z'))
|
||||
*part = p[0] - 'a';
|
||||
*part = dev->disk->partition->number;
|
||||
*slice = dev->disk->partition->parent->number + 1;
|
||||
}
|
||||
else
|
||||
*slice = dev->disk->partition->number + 1;
|
||||
}
|
||||
if (dev)
|
||||
grub_device_close (dev);
|
||||
|
|
|
@ -435,7 +435,6 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
|
|||
void
|
||||
grub_multiboot_set_bootdev (void)
|
||||
{
|
||||
char *p;
|
||||
grub_uint32_t biosdev, slice = ~0, part = ~0;
|
||||
grub_device_t dev;
|
||||
|
||||
|
@ -448,21 +447,13 @@ grub_multiboot_set_bootdev (void)
|
|||
dev = grub_device_open (0);
|
||||
if (dev && dev->disk && dev->disk->partition)
|
||||
{
|
||||
|
||||
p = dev->disk->partition->partmap->get_name (dev->disk->partition);
|
||||
if (p)
|
||||
if (dev->disk->partition->parent)
|
||||
{
|
||||
if ((p[0] >= '0') && (p[0] <= '9'))
|
||||
{
|
||||
slice = grub_strtoul (p, &p, 0) - 1;
|
||||
|
||||
if ((p) && (p[0] == ','))
|
||||
p++;
|
||||
}
|
||||
|
||||
if ((p[0] >= 'a') && (p[0] <= 'z'))
|
||||
part = p[0] - 'a';
|
||||
part = dev->disk->partition->number;
|
||||
slice = dev->disk->partition->parent->number;
|
||||
}
|
||||
else
|
||||
slice = dev->disk->partition->number;
|
||||
}
|
||||
if (dev)
|
||||
grub_device_close (dev);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <grub/machine/memory.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/msdos_partition.h>
|
||||
#include <grub/machine/biosnum.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/video.h>
|
||||
|
@ -98,10 +99,22 @@ grub_chainloader_cmd (const char *filename, grub_chainloader_flags_t flags)
|
|||
dev = grub_device_open (0);
|
||||
if (dev && dev->disk && dev->disk->partition)
|
||||
{
|
||||
grub_disk_read (dev->disk, dev->disk->partition->offset, 446, 64,
|
||||
grub_disk_t disk = dev->disk;
|
||||
|
||||
if (disk)
|
||||
{
|
||||
grub_partition_t p = disk->partition;
|
||||
|
||||
if (p && grub_strcmp (p->partmap->name, "part_msdos") == 0)
|
||||
{
|
||||
disk->partition = p->parent;
|
||||
grub_disk_read (disk, p->offset, 446, 64,
|
||||
(void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR);
|
||||
part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR
|
||||
+ (dev->disk->partition->index << 4));
|
||||
+ (p->index << 4));
|
||||
disk->partition = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dev)
|
||||
|
|
|
@ -96,21 +96,17 @@ acorn_partition_map_iterate (grub_disk_t disk,
|
|||
const grub_partition_t partition))
|
||||
{
|
||||
struct grub_partition part;
|
||||
struct grub_disk raw;
|
||||
struct linux_part map[LINUX_MAP_ENTRIES];
|
||||
int i;
|
||||
grub_disk_addr_t sector;
|
||||
grub_disk_addr_t sector = 0;
|
||||
grub_err_t err;
|
||||
|
||||
/* Enforce raw disk access. */
|
||||
raw = *disk;
|
||||
raw.partition = 0;
|
||||
|
||||
err = acorn_partition_map_find (&raw, map, §or);
|
||||
err = acorn_partition_map_find (disk, map, §or);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
part.partmap = &grub_acorn_partition_map;
|
||||
part.data = 0;
|
||||
|
||||
for (i = 0; i != LINUX_MAP_ENTRIES; ++i)
|
||||
{
|
||||
|
@ -121,7 +117,7 @@ acorn_partition_map_iterate (grub_disk_t disk,
|
|||
part.start = sector + map[i].start;
|
||||
part.len = map[i].size;
|
||||
part.offset = 6;
|
||||
part.index = i;
|
||||
part.number = part.index = i;
|
||||
|
||||
if (hook (disk, &part))
|
||||
return grub_errno;
|
||||
|
@ -130,53 +126,6 @@ acorn_partition_map_iterate (grub_disk_t disk,
|
|||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
static grub_partition_t
|
||||
acorn_partition_map_probe (grub_disk_t disk, const char *str)
|
||||
{
|
||||
struct linux_part map[LINUX_MAP_ENTRIES];
|
||||
struct grub_disk raw = *disk;
|
||||
unsigned long partnum = grub_strtoul (str, 0, 10) - 1;
|
||||
grub_disk_addr_t sector;
|
||||
grub_err_t err;
|
||||
grub_partition_t p;
|
||||
|
||||
/* Enforce raw disk access. */
|
||||
raw.partition = 0;
|
||||
|
||||
/* Get the partition number. */
|
||||
if (partnum > LINUX_MAP_ENTRIES)
|
||||
goto fail;
|
||||
|
||||
err = acorn_partition_map_find (&raw, map, §or);
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
if (map[partnum].magic != LINUX_NATIVE_MAGIC
|
||||
&& map[partnum].magic != LINUX_SWAP_MAGIC)
|
||||
goto fail;
|
||||
|
||||
p = grub_malloc (sizeof (struct grub_partition));
|
||||
if (! p)
|
||||
return 0;
|
||||
|
||||
p->start = sector + map[partnum].start;
|
||||
p->len = map[partnum].size;
|
||||
p->offset = 6;
|
||||
p->index = partnum;
|
||||
return p;
|
||||
|
||||
fail:
|
||||
grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
acorn_partition_map_get_name (const grub_partition_t p)
|
||||
{
|
||||
return grub_xasprintf ("%d", p->index + 1);
|
||||
}
|
||||
|
||||
|
||||
/* Partition map type. */
|
||||
|
@ -184,8 +133,6 @@ static struct grub_partition_map grub_acorn_partition_map =
|
|||
{
|
||||
.name = "part_acorn",
|
||||
.iterate = acorn_partition_map_iterate,
|
||||
.probe = acorn_partition_map_probe,
|
||||
.get_name = acorn_partition_map_get_name
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(acorn_partition_map)
|
||||
|
|
|
@ -76,20 +76,15 @@ amiga_partition_map_iterate (grub_disk_t disk,
|
|||
{
|
||||
struct grub_partition part;
|
||||
struct grub_amiga_rdsk rdsk;
|
||||
struct grub_disk raw;
|
||||
int partno = 0;
|
||||
int next = -1;
|
||||
unsigned pos;
|
||||
|
||||
/* Enforce raw disk access. */
|
||||
raw = *disk;
|
||||
raw.partition = 0;
|
||||
|
||||
/* The RDSK block is one of the first 15 blocks. */
|
||||
for (pos = 0; pos < 15; pos++)
|
||||
{
|
||||
/* Read the RDSK block which is a descriptor for the entire disk. */
|
||||
if (grub_disk_read (&raw, pos, 0, sizeof (rdsk), &rdsk))
|
||||
if (grub_disk_read (disk, pos, 0, sizeof (rdsk), &rdsk))
|
||||
return grub_errno;
|
||||
|
||||
if (grub_strcmp ((char *) rdsk.magic, "RDSK") == 0)
|
||||
|
@ -104,13 +99,15 @@ amiga_partition_map_iterate (grub_disk_t disk,
|
|||
return grub_error (GRUB_ERR_BAD_PART_TABLE,
|
||||
"Amiga partition map not found");
|
||||
|
||||
part.data = 0;
|
||||
|
||||
/* The end of the partition list is marked using "-1". */
|
||||
while (next != -1)
|
||||
{
|
||||
struct grub_amiga_partition apart;
|
||||
|
||||
/* Read the RDSK block which is a descriptor for the entire disk. */
|
||||
if (grub_disk_read (&raw, next, 0, sizeof (apart), &apart))
|
||||
if (grub_disk_read (disk, next, 0, sizeof (apart), &apart))
|
||||
return grub_errno;
|
||||
|
||||
/* Calculate the first block and the size of the partition. */
|
||||
|
@ -123,7 +120,8 @@ amiga_partition_map_iterate (grub_disk_t disk,
|
|||
* grub_be_to_cpu32 (apart.block_per_track));
|
||||
|
||||
part.offset = (grub_off_t) next * 512;
|
||||
part.index = partno;
|
||||
part.number = partno;
|
||||
part.index = 0;
|
||||
part.partmap = &grub_amiga_partition_map;
|
||||
|
||||
if (hook (disk, &part))
|
||||
|
@ -136,65 +134,12 @@ amiga_partition_map_iterate (grub_disk_t disk,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static grub_partition_t
|
||||
amiga_partition_map_probe (grub_disk_t disk, const char *str)
|
||||
{
|
||||
grub_partition_t p = 0;
|
||||
int partnum = 0;
|
||||
char *s = (char *) str;
|
||||
|
||||
auto int find_func (grub_disk_t d, const grub_partition_t partition);
|
||||
|
||||
int find_func (grub_disk_t d __attribute__ ((unused)),
|
||||
const grub_partition_t partition)
|
||||
{
|
||||
if (partnum == partition->index)
|
||||
{
|
||||
p = (grub_partition_t) grub_malloc (sizeof (*p));
|
||||
if (! p)
|
||||
return 1;
|
||||
|
||||
grub_memcpy (p, partition, sizeof (*p));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the partition number. */
|
||||
partnum = grub_strtoul (s, 0, 10) - 1;
|
||||
if (grub_errno)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (amiga_partition_map_iterate (disk, find_func))
|
||||
goto fail;
|
||||
|
||||
return p;
|
||||
|
||||
fail:
|
||||
grub_free (p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
amiga_partition_map_get_name (const grub_partition_t p)
|
||||
{
|
||||
return grub_xasprintf ("%d", p->index + 1);
|
||||
}
|
||||
|
||||
|
||||
/* Partition map type. */
|
||||
static struct grub_partition_map grub_amiga_partition_map =
|
||||
{
|
||||
.name = "part_amiga",
|
||||
.iterate = amiga_partition_map_iterate,
|
||||
.probe = amiga_partition_map_probe,
|
||||
.get_name = amiga_partition_map_get_name
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(amiga_partition_map)
|
||||
|
|
|
@ -105,17 +105,12 @@ apple_partition_map_iterate (grub_disk_t disk,
|
|||
struct grub_partition part;
|
||||
struct grub_apple_header aheader;
|
||||
struct grub_apple_part apart;
|
||||
struct grub_disk raw;
|
||||
int partno = 0, partnum = 0;
|
||||
unsigned pos;
|
||||
|
||||
/* Enforce raw disk access. */
|
||||
raw = *disk;
|
||||
raw.partition = 0;
|
||||
|
||||
part.partmap = &grub_apple_partition_map;
|
||||
|
||||
if (grub_disk_read (&raw, 0, 0, sizeof (aheader), &aheader))
|
||||
if (grub_disk_read (disk, 0, 0, sizeof (aheader), &aheader))
|
||||
return grub_errno;
|
||||
|
||||
if (grub_be_to_cpu16 (aheader.magic) != GRUB_APPLE_HEADER_MAGIC)
|
||||
|
@ -127,12 +122,15 @@ apple_partition_map_iterate (grub_disk_t disk,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
part.data = 0;
|
||||
pos = grub_be_to_cpu16 (aheader.blocksize);
|
||||
|
||||
do
|
||||
{
|
||||
if (grub_disk_read (&raw, pos / GRUB_DISK_SECTOR_SIZE,
|
||||
pos % GRUB_DISK_SECTOR_SIZE,
|
||||
part.offset = pos / GRUB_DISK_SECTOR_SIZE;
|
||||
part.index = pos % GRUB_DISK_SECTOR_SIZE;
|
||||
|
||||
if (grub_disk_read (disk, part.offset, part.index,
|
||||
sizeof (struct grub_apple_part), &apart))
|
||||
return grub_errno;
|
||||
|
||||
|
@ -156,6 +154,7 @@ apple_partition_map_iterate (grub_disk_t disk,
|
|||
/ GRUB_DISK_SECTOR_SIZE;
|
||||
part.offset = pos;
|
||||
part.index = partno;
|
||||
part.number = partno;
|
||||
|
||||
grub_dprintf ("partition",
|
||||
"partition %d: name %s, type %s, start 0x%x, len 0x%x\n",
|
||||
|
@ -179,65 +178,12 @@ apple_partition_map_iterate (grub_disk_t disk,
|
|||
"Apple partition map not found");
|
||||
}
|
||||
|
||||
|
||||
static grub_partition_t
|
||||
apple_partition_map_probe (grub_disk_t disk, const char *str)
|
||||
{
|
||||
grub_partition_t p = 0;
|
||||
int partnum = 0;
|
||||
char *s = (char *) str;
|
||||
|
||||
auto int find_func (grub_disk_t d, const grub_partition_t partition);
|
||||
|
||||
int find_func (grub_disk_t d __attribute__ ((unused)),
|
||||
const grub_partition_t partition)
|
||||
{
|
||||
if (partnum == partition->index)
|
||||
{
|
||||
p = (grub_partition_t) grub_malloc (sizeof (*p));
|
||||
if (! p)
|
||||
return 1;
|
||||
|
||||
grub_memcpy (p, partition, sizeof (*p));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the partition number. */
|
||||
partnum = grub_strtoul (s, 0, 10) - 1;
|
||||
if (grub_errno)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (apple_partition_map_iterate (disk, find_func))
|
||||
goto fail;
|
||||
|
||||
return p;
|
||||
|
||||
fail:
|
||||
grub_free (p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
apple_partition_map_get_name (const grub_partition_t p)
|
||||
{
|
||||
return grub_xasprintf ("%d", p->index + 1);
|
||||
}
|
||||
|
||||
|
||||
/* Partition map type. */
|
||||
static struct grub_partition_map grub_apple_partition_map =
|
||||
{
|
||||
.name = "part_apple",
|
||||
.iterate = apple_partition_map_iterate,
|
||||
.probe = apple_partition_map_probe,
|
||||
.get_name = apple_partition_map_get_name
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(apple_partition_map)
|
||||
|
|
97
partmap/bsdlabel.c
Normal file
97
partmap/bsdlabel.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* bsdlabel.c - Read BSD style partition tables. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2002,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/partition.h>
|
||||
#include <grub/bsdlabel.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
static struct grub_partition_map grub_bsdlabel_partition_map;
|
||||
|
||||
|
||||
static grub_err_t
|
||||
bsdlabel_partition_map_iterate (grub_disk_t disk,
|
||||
int (*hook) (grub_disk_t disk,
|
||||
const grub_partition_t partition))
|
||||
{
|
||||
struct grub_partition_bsd_disk_label label;
|
||||
struct grub_partition p;
|
||||
grub_disk_addr_t delta = 0;
|
||||
unsigned pos;
|
||||
|
||||
/* BSDLabel offsets are absolute even when it's embed inside partition. */
|
||||
delta = grub_partition_get_start (disk->partition);
|
||||
|
||||
/* Read the BSD label. */
|
||||
if (grub_disk_read (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR,
|
||||
0, sizeof (label), &label))
|
||||
return grub_errno;
|
||||
|
||||
/* Check if it is valid. */
|
||||
if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC))
|
||||
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
|
||||
|
||||
pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR
|
||||
* GRUB_DISK_SECTOR_SIZE;
|
||||
|
||||
for (p.number = 0;
|
||||
p.number < grub_cpu_to_le16 (label.num_partitions);
|
||||
p.number++)
|
||||
{
|
||||
struct grub_partition_bsd_entry be;
|
||||
|
||||
p.offset = pos / GRUB_DISK_SECTOR_SIZE;
|
||||
p.index = pos % GRUB_DISK_SECTOR_SIZE;
|
||||
|
||||
if (grub_disk_read (disk, p.offset, p.index, sizeof (be), &be))
|
||||
return grub_errno;
|
||||
|
||||
p.start = grub_le_to_cpu32 (be.offset) - delta;
|
||||
p.len = grub_le_to_cpu32 (be.size);
|
||||
p.partmap = &grub_bsdlabel_partition_map;
|
||||
|
||||
if (be.fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED)
|
||||
if (hook (disk, &p))
|
||||
return grub_errno;
|
||||
|
||||
pos += sizeof (struct grub_partition_bsd_entry);
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
/* Partition map type. */
|
||||
static struct grub_partition_map grub_bsdlabel_partition_map =
|
||||
{
|
||||
.name = "part_bsd",
|
||||
.iterate = bsdlabel_partition_map_iterate,
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(bsd_partition_map)
|
||||
{
|
||||
grub_partition_map_register (&grub_bsdlabel_partition_map);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(bsd_partition_map)
|
||||
{
|
||||
grub_partition_map_unregister (&grub_bsdlabel_partition_map);
|
||||
}
|
|
@ -44,18 +44,13 @@ gpt_partition_map_iterate (grub_disk_t disk,
|
|||
struct grub_partition part;
|
||||
struct grub_gpt_header gpt;
|
||||
struct grub_gpt_partentry entry;
|
||||
struct grub_disk raw;
|
||||
struct grub_msdos_partition_mbr mbr;
|
||||
grub_uint64_t entries;
|
||||
unsigned int i;
|
||||
int last_offset = 0;
|
||||
|
||||
/* Enforce raw disk access. */
|
||||
raw = *disk;
|
||||
raw.partition = 0;
|
||||
|
||||
/* Read the protective MBR. */
|
||||
if (grub_disk_read (&raw, 0, 0, sizeof (mbr), &mbr))
|
||||
if (grub_disk_read (disk, 0, 0, sizeof (mbr), &mbr))
|
||||
return grub_errno;
|
||||
|
||||
/* Check if it is valid. */
|
||||
|
@ -67,7 +62,7 @@ gpt_partition_map_iterate (grub_disk_t disk,
|
|||
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found");
|
||||
|
||||
/* Read the GPT header. */
|
||||
if (grub_disk_read (&raw, 1, 0, sizeof (gpt), &gpt))
|
||||
if (grub_disk_read (disk, 1, 0, sizeof (gpt), &gpt))
|
||||
return grub_errno;
|
||||
|
||||
if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic)))
|
||||
|
@ -76,11 +71,15 @@ gpt_partition_map_iterate (grub_disk_t disk,
|
|||
grub_dprintf ("gpt", "Read a valid GPT header\n");
|
||||
|
||||
entries = grub_le_to_cpu64 (gpt.partitions);
|
||||
part.data = grub_malloc (sizeof (entry));
|
||||
for (i = 0; i < grub_le_to_cpu32 (gpt.maxpart); i++)
|
||||
{
|
||||
if (grub_disk_read (&raw, entries, last_offset,
|
||||
if (grub_disk_read (disk, entries, last_offset,
|
||||
sizeof (entry), &entry))
|
||||
{
|
||||
grub_free (part.data);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
if (grub_memcmp (&grub_gpt_partition_type_empty, &entry.type,
|
||||
sizeof (grub_gpt_partition_type_empty)))
|
||||
|
@ -90,16 +89,17 @@ gpt_partition_map_iterate (grub_disk_t disk,
|
|||
part.len = (grub_le_to_cpu64 (entry.end)
|
||||
- grub_le_to_cpu64 (entry.start) + 1);
|
||||
part.offset = entries;
|
||||
part.index = i;
|
||||
part.number = i;
|
||||
part.index = last_offset;
|
||||
part.partmap = &grub_gpt_partition_map;
|
||||
part.data = &entry;
|
||||
grub_memcpy (part.data, &entry, sizeof (entry));
|
||||
|
||||
grub_dprintf ("gpt", "GPT entry %d: start=%lld, length=%lld\n", i,
|
||||
(unsigned long long) part.start,
|
||||
(unsigned long long) part.len);
|
||||
|
||||
if (hook (disk, &part))
|
||||
return 1;
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
last_offset += grub_le_to_cpu32 (gpt.partentry_size);
|
||||
|
@ -110,59 +110,9 @@ gpt_partition_map_iterate (grub_disk_t disk,
|
|||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
grub_free (part.data);
|
||||
|
||||
|
||||
static grub_partition_t
|
||||
gpt_partition_map_probe (grub_disk_t disk, const char *str)
|
||||
{
|
||||
grub_partition_t p = 0;
|
||||
int partnum = 0;
|
||||
char *s = (char *) str;
|
||||
|
||||
auto int find_func (grub_disk_t d, const grub_partition_t partition);
|
||||
|
||||
int find_func (grub_disk_t d __attribute__ ((unused)),
|
||||
const grub_partition_t partition)
|
||||
{
|
||||
if (partnum == partition->index)
|
||||
{
|
||||
p = (grub_partition_t) grub_malloc (sizeof (*p));
|
||||
if (! p)
|
||||
return 1;
|
||||
|
||||
grub_memcpy (p, partition, sizeof (*p));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the partition number. */
|
||||
partnum = grub_strtoul (s, 0, 10) - 1;
|
||||
if (grub_errno)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
|
||||
return 0;
|
||||
}
|
||||
|
||||
gpt_partition_map_iterate (disk, find_func);
|
||||
if (grub_errno)
|
||||
goto fail;
|
||||
|
||||
return p;
|
||||
|
||||
fail:
|
||||
grub_free (p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
gpt_partition_map_get_name (const grub_partition_t p)
|
||||
{
|
||||
return grub_xasprintf ("%d", p->index + 1);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -171,8 +121,6 @@ static struct grub_partition_map grub_gpt_partition_map =
|
|||
{
|
||||
.name = "part_gpt",
|
||||
.iterate = gpt_partition_map_iterate,
|
||||
.probe = gpt_partition_map_probe,
|
||||
.get_name = gpt_partition_map_get_name
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(gpt_partition_map)
|
||||
|
|
205
partmap/msdos.c
205
partmap/msdos.c
|
@ -27,87 +27,21 @@
|
|||
static struct grub_partition_map grub_msdos_partition_map;
|
||||
|
||||
|
||||
/* Parse the partition representation in STR and return a partition. */
|
||||
static grub_partition_t
|
||||
grub_partition_parse (const char *str)
|
||||
{
|
||||
grub_partition_t p;
|
||||
struct grub_msdos_partition *pcdata;
|
||||
|
||||
char *s = (char *) str;
|
||||
|
||||
p = (grub_partition_t) grub_malloc (sizeof (*p));
|
||||
if (! p)
|
||||
return 0;
|
||||
|
||||
pcdata = (struct grub_msdos_partition *) grub_malloc (sizeof (*pcdata));
|
||||
if (! pcdata)
|
||||
goto fail;
|
||||
|
||||
p->data = pcdata;
|
||||
p->partmap = &grub_msdos_partition_map;
|
||||
|
||||
/* Initialize some of the fields with invalid values. */
|
||||
pcdata->bsd_part = pcdata->dos_type = pcdata->bsd_type = p->index = -1;
|
||||
|
||||
/* Get the DOS partition number. The number is counted from one for
|
||||
the user interface, and from zero internally. */
|
||||
pcdata->dos_part = grub_strtoul (s, &s, 0) - 1;
|
||||
|
||||
if (grub_errno)
|
||||
{
|
||||
/* Not found. Maybe only a BSD label is specified. */
|
||||
pcdata->dos_part = -1;
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
else if (*s == ',')
|
||||
s++;
|
||||
|
||||
if (*s)
|
||||
{
|
||||
if (*s >= 'a' && *s <= 'h')
|
||||
{
|
||||
pcdata->bsd_part = *s - 'a';
|
||||
s++;
|
||||
}
|
||||
|
||||
if (*s)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (pcdata->dos_part == -1 && pcdata->bsd_part == -1)
|
||||
goto fail;
|
||||
|
||||
return p;
|
||||
|
||||
fail:
|
||||
grub_free (p);
|
||||
grub_free (pcdata);
|
||||
grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
pc_partition_map_iterate (grub_disk_t disk,
|
||||
int (*hook) (grub_disk_t disk,
|
||||
const grub_partition_t partition))
|
||||
{
|
||||
struct grub_partition p;
|
||||
struct grub_msdos_partition pcdata;
|
||||
struct grub_msdos_partition_mbr mbr;
|
||||
struct grub_msdos_partition_disk_label label;
|
||||
struct grub_disk raw;
|
||||
int labeln = 0;
|
||||
grub_disk_addr_t lastaddr;
|
||||
|
||||
/* Enforce raw disk access. */
|
||||
raw = *disk;
|
||||
raw.partition = 0;
|
||||
grub_disk_addr_t ext_offset;
|
||||
|
||||
p.offset = 0;
|
||||
pcdata.ext_offset = 0;
|
||||
pcdata.dos_part = -1;
|
||||
p.data = &pcdata;
|
||||
ext_offset = 0;
|
||||
p.data = 0;
|
||||
p.number = -1;
|
||||
p.partmap = &grub_msdos_partition_map;
|
||||
|
||||
/* Any value different than `p.offset' will satisfy the check during
|
||||
|
@ -120,7 +54,7 @@ pc_partition_map_iterate (grub_disk_t disk,
|
|||
struct grub_msdos_partition_entry *e;
|
||||
|
||||
/* Read the MBR. */
|
||||
if (grub_disk_read (&raw, p.offset, 0, sizeof (mbr), &mbr))
|
||||
if (grub_disk_read (disk, p.offset, 0, sizeof (mbr), &mbr))
|
||||
goto finish;
|
||||
|
||||
/* This is our loop-detection algorithm. It works the following way:
|
||||
|
@ -150,13 +84,10 @@ pc_partition_map_iterate (grub_disk_t disk,
|
|||
|
||||
p.start = p.offset + grub_le_to_cpu32 (e->start);
|
||||
p.len = grub_le_to_cpu32 (e->length);
|
||||
pcdata.bsd_part = -1;
|
||||
pcdata.dos_type = e->type;
|
||||
pcdata.bsd_type = -1;
|
||||
|
||||
grub_dprintf ("partition",
|
||||
"partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n",
|
||||
p.index, e->flag, pcdata.dos_type,
|
||||
p.index, e->flag, e->type,
|
||||
(unsigned long long) p.start,
|
||||
(unsigned long long) p.len);
|
||||
|
||||
|
@ -168,59 +99,15 @@ pc_partition_map_iterate (grub_disk_t disk,
|
|||
if (! grub_msdos_partition_is_empty (e->type)
|
||||
&& ! grub_msdos_partition_is_extended (e->type))
|
||||
{
|
||||
pcdata.dos_part++;
|
||||
p.number++;
|
||||
|
||||
if (hook (disk, &p))
|
||||
return 1;
|
||||
|
||||
/* Check if this is a BSD partition. */
|
||||
if (grub_msdos_partition_is_bsd (e->type))
|
||||
{
|
||||
/* Check if the BSD label is within the DOS partition. */
|
||||
if (p.len <= GRUB_PC_PARTITION_BSD_LABEL_SECTOR)
|
||||
{
|
||||
grub_dprintf ("partition", "no space for disk label\n");
|
||||
continue;
|
||||
return grub_errno;
|
||||
}
|
||||
/* Read the BSD label. */
|
||||
if (grub_disk_read (&raw,
|
||||
(p.start
|
||||
+ GRUB_PC_PARTITION_BSD_LABEL_SECTOR),
|
||||
0,
|
||||
sizeof (label),
|
||||
&label))
|
||||
goto finish;
|
||||
|
||||
/* Check if it is valid. */
|
||||
if (label.magic
|
||||
!= grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC))
|
||||
{
|
||||
grub_dprintf ("partition",
|
||||
"invalid disk label magic 0x%x on partition %d\n",
|
||||
label.magic, p.index);
|
||||
continue;
|
||||
}
|
||||
for (pcdata.bsd_part = 0;
|
||||
pcdata.bsd_part < grub_cpu_to_le16 (label.num_partitions);
|
||||
pcdata.bsd_part++)
|
||||
{
|
||||
struct grub_msdos_partition_bsd_entry *be
|
||||
= label.entries + pcdata.bsd_part;
|
||||
|
||||
p.start = grub_le_to_cpu32 (be->offset);
|
||||
p.len = grub_le_to_cpu32 (be->size);
|
||||
pcdata.bsd_type = be->fs_type;
|
||||
|
||||
if (be->fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED)
|
||||
if (hook (disk, &p))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pcdata.dos_part < 4)
|
||||
else if (p.number < 4)
|
||||
/* If this partition is a logical one, shouldn't increase the
|
||||
partition number. */
|
||||
pcdata.dos_part++;
|
||||
p.number++;
|
||||
}
|
||||
|
||||
/* Find an extended partition. */
|
||||
|
@ -230,9 +117,9 @@ pc_partition_map_iterate (grub_disk_t disk,
|
|||
|
||||
if (grub_msdos_partition_is_extended (e->type))
|
||||
{
|
||||
p.offset = pcdata.ext_offset + grub_le_to_cpu32 (e->start);
|
||||
if (! pcdata.ext_offset)
|
||||
pcdata.ext_offset = p.offset;
|
||||
p.offset = ext_offset + grub_le_to_cpu32 (e->start);
|
||||
if (! ext_offset)
|
||||
ext_offset = p.offset;
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -247,78 +134,12 @@ pc_partition_map_iterate (grub_disk_t disk,
|
|||
return grub_errno;
|
||||
}
|
||||
|
||||
|
||||
static grub_partition_t
|
||||
pc_partition_map_probe (grub_disk_t disk, const char *str)
|
||||
{
|
||||
grub_partition_t p;
|
||||
struct grub_msdos_partition *pcdata;
|
||||
|
||||
auto int find_func (grub_disk_t d, const grub_partition_t partition);
|
||||
|
||||
int find_func (grub_disk_t d __attribute__ ((unused)),
|
||||
const grub_partition_t partition)
|
||||
{
|
||||
struct grub_msdos_partition *partdata = partition->data;
|
||||
|
||||
if ((pcdata->dos_part == partdata->dos_part || pcdata->dos_part == -1)
|
||||
&& pcdata->bsd_part == partdata->bsd_part)
|
||||
{
|
||||
grub_memcpy (p, partition, sizeof (*p));
|
||||
p->data = pcdata;
|
||||
grub_memcpy (pcdata, partdata, sizeof (*pcdata));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = grub_partition_parse (str);
|
||||
if (! p)
|
||||
return 0;
|
||||
|
||||
pcdata = p->data;
|
||||
pc_partition_map_iterate (disk, find_func);
|
||||
if (grub_errno)
|
||||
goto fail;
|
||||
|
||||
if (p->index < 0)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_DEVICE, "no such partition");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return p;
|
||||
|
||||
fail:
|
||||
grub_free (p);
|
||||
grub_free (pcdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
pc_partition_map_get_name (const grub_partition_t p)
|
||||
{
|
||||
struct grub_msdos_partition *pcdata = p->data;
|
||||
|
||||
if (pcdata->bsd_part < 0)
|
||||
return grub_xasprintf ("%d", pcdata->dos_part + 1);
|
||||
else if (pcdata->dos_part < 0)
|
||||
return grub_xasprintf ("%c", pcdata->bsd_part + 'a');
|
||||
else
|
||||
return grub_xasprintf ("%d,%c", pcdata->dos_part + 1,
|
||||
pcdata->bsd_part + 'a');
|
||||
}
|
||||
|
||||
|
||||
/* Partition map type. */
|
||||
static struct grub_partition_map grub_msdos_partition_map =
|
||||
{
|
||||
.name = "part_msdos",
|
||||
.iterate = pc_partition_map_iterate,
|
||||
.probe = pc_partition_map_probe,
|
||||
.get_name = pc_partition_map_get_name
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(pc_partition_map)
|
||||
|
|
|
@ -88,19 +88,15 @@ sun_partition_map_iterate (grub_disk_t disk,
|
|||
const grub_partition_t partition))
|
||||
{
|
||||
grub_partition_t p;
|
||||
struct grub_disk raw;
|
||||
struct grub_sun_block block;
|
||||
int partnum;
|
||||
|
||||
raw = *disk;
|
||||
raw.partition = 0;
|
||||
|
||||
p = (grub_partition_t) grub_zalloc (sizeof (struct grub_partition));
|
||||
if (! p)
|
||||
return grub_errno;
|
||||
|
||||
p->partmap = &grub_sun_partition_map;
|
||||
if (grub_disk_read (&raw, 0, 0, sizeof (struct grub_sun_block),
|
||||
if (grub_disk_read (disk, 0, 0, sizeof (struct grub_sun_block),
|
||||
&block) == GRUB_ERR_NONE)
|
||||
{
|
||||
if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic))
|
||||
|
@ -124,7 +120,7 @@ sun_partition_map_iterate (grub_disk_t disk,
|
|||
* grub_be_to_cpu16 (block.ntrks)
|
||||
* grub_be_to_cpu16 (block.nsect));
|
||||
p->len = grub_be_to_cpu32 (desc->num_sectors);
|
||||
p->index = partnum;
|
||||
p->number = p->index = partnum;
|
||||
if (p->len)
|
||||
{
|
||||
if (hook (disk, p))
|
||||
|
@ -138,62 +134,11 @@ sun_partition_map_iterate (grub_disk_t disk,
|
|||
return grub_errno;
|
||||
}
|
||||
|
||||
static grub_partition_t
|
||||
sun_partition_map_probe (grub_disk_t disk, const char *str)
|
||||
{
|
||||
grub_partition_t p = 0;
|
||||
int partnum = 0;
|
||||
char *s = (char *) str;
|
||||
|
||||
auto int find_func (grub_disk_t d, const grub_partition_t partition);
|
||||
|
||||
int find_func (grub_disk_t d __attribute__ ((unused)),
|
||||
const grub_partition_t partition)
|
||||
{
|
||||
if (partnum == partition->index)
|
||||
{
|
||||
p = (grub_partition_t) grub_malloc (sizeof (*p));
|
||||
if (p)
|
||||
grub_memcpy (p, partition, sizeof (*p));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
partnum = grub_strtoul (s, 0, 10) - 1;
|
||||
if (grub_errno == GRUB_ERR_NONE)
|
||||
{
|
||||
if (sun_partition_map_iterate (disk, find_func))
|
||||
{
|
||||
grub_free (p);
|
||||
p = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
|
||||
p = 0;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *
|
||||
sun_partition_map_get_name (const grub_partition_t p)
|
||||
{
|
||||
return grub_xasprintf ("%d", p->index + 1);
|
||||
}
|
||||
|
||||
/* Partition map type. */
|
||||
static struct grub_partition_map grub_sun_partition_map =
|
||||
{
|
||||
.name = "part_sun",
|
||||
.iterate = sun_partition_map_iterate,
|
||||
.probe = sun_partition_map_probe,
|
||||
.get_name = sun_partition_map_get_name
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(sun_partition_map)
|
||||
|
|
|
@ -49,7 +49,7 @@ static grub_err_t grub_pcpart_boot (const grub_device_t dev,
|
|||
|
||||
index = dev->disk->partition->index;
|
||||
part = dev->disk->partition;
|
||||
dev->disk->partition = 0;
|
||||
dev->disk->partition = part->parent;
|
||||
|
||||
/* Read the MBR. */
|
||||
if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), &mbr))
|
||||
|
@ -96,7 +96,7 @@ static grub_err_t grub_pcpart_type (const grub_device_t dev,
|
|||
|
||||
index = dev->disk->partition->index;
|
||||
part = dev->disk->partition;
|
||||
dev->disk->partition = 0;
|
||||
dev->disk->partition = part->parent;
|
||||
|
||||
/* Read the parttable. */
|
||||
if (grub_disk_read (dev->disk, part->offset, 0,
|
||||
|
|
|
@ -82,13 +82,16 @@ grub_refresh (void)
|
|||
static void
|
||||
probe_partmap (grub_disk_t disk)
|
||||
{
|
||||
grub_partition_t part;
|
||||
|
||||
if (disk->partition == NULL)
|
||||
{
|
||||
grub_util_info ("no partition map found for %s", disk->name);
|
||||
return;
|
||||
}
|
||||
|
||||
printf ("%s\n", disk->partition->partmap->name);
|
||||
for (part = disk->partition; part; part = part->parent)
|
||||
printf ("%s\n", part->partmap->name);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -334,10 +334,13 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags)
|
|||
{
|
||||
int is_partition = 0;
|
||||
char dev[PATH_MAX];
|
||||
grub_disk_addr_t part_start = 0;
|
||||
|
||||
part_start = grub_partition_get_start (disk->partition);
|
||||
|
||||
strcpy (dev, map[disk->id].device);
|
||||
if (disk->partition && strncmp (map[disk->id].device, "/dev/", 5) == 0)
|
||||
is_partition = linux_find_partition (dev, disk->partition->start);
|
||||
is_partition = linux_find_partition (dev, part_start);
|
||||
|
||||
/* Open the partition. */
|
||||
grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev);
|
||||
|
@ -353,7 +356,7 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags)
|
|||
ioctl (fd, BLKFLSBUF, 0);
|
||||
|
||||
if (is_partition)
|
||||
sector -= disk->partition->start;
|
||||
sector -= part_start;
|
||||
}
|
||||
#else /* ! __linux__ */
|
||||
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
|
@ -952,39 +955,25 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
|
|||
int find_partition (grub_disk_t disk __attribute__ ((unused)),
|
||||
const grub_partition_t partition)
|
||||
{
|
||||
struct grub_msdos_partition *pcdata = NULL;
|
||||
|
||||
if (strcmp (partition->partmap->name, "part_msdos") == 0)
|
||||
pcdata = partition->data;
|
||||
|
||||
if (pcdata)
|
||||
{
|
||||
if (pcdata->bsd_part < 0)
|
||||
grub_util_info ("DOS partition %d starts from %lu",
|
||||
pcdata->dos_part, partition->start);
|
||||
else
|
||||
grub_util_info ("BSD partition %d,%c starts from %lu",
|
||||
pcdata->dos_part, pcdata->bsd_part + 'a',
|
||||
partition->start);
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_disk_addr_t part_start = 0;
|
||||
grub_util_info ("Partition %d starts from %lu",
|
||||
partition->index, partition->start);
|
||||
}
|
||||
partition->number, partition->start);
|
||||
|
||||
if (hdg.start == partition->start)
|
||||
part_start = grub_partition_get_start (partition);
|
||||
|
||||
if (hdg.start == part_start)
|
||||
{
|
||||
if (pcdata)
|
||||
if (partition->parent)
|
||||
{
|
||||
dos_part = pcdata->dos_part;
|
||||
bsd_part = pcdata->bsd_part;
|
||||
dos_part = partition->parent->number;
|
||||
bsd_part = partition->number;
|
||||
}
|
||||
else
|
||||
{
|
||||
dos_part = partition->index;
|
||||
dos_part = partition->number;
|
||||
bsd_part = -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,15 +116,10 @@ setup (const char *dir,
|
|||
int NESTED_FUNC_ATTR find_usable_region_msdos (grub_disk_t disk __attribute__ ((unused)),
|
||||
const grub_partition_t p)
|
||||
{
|
||||
struct grub_msdos_partition *pcdata = p->data;
|
||||
|
||||
/* There's always an embed region, and it starts right after the MBR. */
|
||||
embed_region.start = 1;
|
||||
|
||||
/* For its end offset, include as many dummy partitions as we can. */
|
||||
if (! grub_msdos_partition_is_empty (pcdata->dos_type)
|
||||
&& ! grub_msdos_partition_is_bsd (pcdata->dos_type)
|
||||
&& embed_region.end > p->start)
|
||||
if (embed_region.end > p->start)
|
||||
embed_region.end = p->start;
|
||||
|
||||
return 0;
|
||||
|
@ -289,22 +284,19 @@ setup (const char *dir,
|
|||
/* Embed information about the installed location. */
|
||||
if (root_dev->disk->partition)
|
||||
{
|
||||
if (strcmp (root_dev->disk->partition->partmap->name,
|
||||
"part_msdos") == 0)
|
||||
if (root_dev->disk->partition->parent)
|
||||
{
|
||||
struct grub_msdos_partition *pcdata =
|
||||
root_dev->disk->partition->data;
|
||||
dos_part = pcdata->dos_part;
|
||||
bsd_part = pcdata->bsd_part;
|
||||
}
|
||||
else if (strcmp (root_dev->disk->partition->partmap->name,
|
||||
"part_gpt") == 0)
|
||||
{
|
||||
dos_part = root_dev->disk->partition->index;
|
||||
bsd_part = -1;
|
||||
if (root_dev->disk->partition->parent->parent)
|
||||
grub_util_error ("Installing on doubly nested partitions is "
|
||||
"not supported");
|
||||
dos_part = root_dev->disk->partition->parent->number;
|
||||
bsd_part = root_dev->disk->partition->number;
|
||||
}
|
||||
else
|
||||
grub_util_error (_("no DOS-style partitions found"));
|
||||
{
|
||||
dos_part = root_dev->disk->partition->number;
|
||||
bsd_part = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
dos_part = bsd_part = -1;
|
||||
|
@ -337,6 +329,8 @@ setup (const char *dir,
|
|||
int NESTED_FUNC_ATTR identify_partmap (grub_disk_t disk __attribute__ ((unused)),
|
||||
const grub_partition_t p)
|
||||
{
|
||||
if (p->parent)
|
||||
return 0;
|
||||
dest_partmap = p->partmap->name;
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue