merged with mainline
This commit is contained in:
commit
baae00df35
34 changed files with 750 additions and 1499 deletions
|
@ -25,6 +25,8 @@ docs/version.texi
|
||||||
*.exec
|
*.exec
|
||||||
genkernsyms.sh
|
genkernsyms.sh
|
||||||
gensymlist.sh
|
gensymlist.sh
|
||||||
|
gentrigtables
|
||||||
|
grub-bin2h
|
||||||
grub-dumpbios
|
grub-dumpbios
|
||||||
grub-editenv
|
grub-editenv
|
||||||
grub-emu
|
grub-emu
|
||||||
|
@ -40,8 +42,13 @@ grub-pe2elf
|
||||||
grub-probe
|
grub-probe
|
||||||
grub_probe_init.c
|
grub_probe_init.c
|
||||||
grub_probe_init.h
|
grub_probe_init.h
|
||||||
|
grub-reboot
|
||||||
|
grub-script-check
|
||||||
|
grub_script_check_init.c
|
||||||
|
grub_script_check_init.h
|
||||||
grub_script.tab.c
|
grub_script.tab.c
|
||||||
grub_script.tab.h
|
grub_script.tab.h
|
||||||
|
grub-set-default
|
||||||
grub-setup
|
grub-setup
|
||||||
grub_setup_init.c
|
grub_setup_init.c
|
||||||
grub_setup_init.h
|
grub_setup_init.h
|
||||||
|
@ -62,4 +69,5 @@ stamp-h
|
||||||
stamp-h1
|
stamp-h1
|
||||||
stamp-h.in
|
stamp-h.in
|
||||||
symlist.c
|
symlist.c
|
||||||
|
trigtables.c
|
||||||
update-grub_lib
|
update-grub_lib
|
||||||
|
|
129
ChangeLog
129
ChangeLog
|
@ -1,3 +1,132 @@
|
||||||
|
2010-03-26 BVK Chaitanya <bvk@localhost>
|
||||||
|
|
||||||
|
For loop support to GRUB script.
|
||||||
|
|
||||||
|
* include/grub/script_sh.h (grub_script_cmdfor): New struct.
|
||||||
|
(grub_script_create_cmdfor): New function prototype.
|
||||||
|
(grub_script_execute_cmdfor): New function prototype.
|
||||||
|
* script/execute.c (grub_script_execute_cmdfor): New function.
|
||||||
|
* script/parser.y (command): New for command.
|
||||||
|
(forcmd): New grammar rule.
|
||||||
|
* script/script.c (grub_script_create_cmdfor): New function.
|
||||||
|
* util/grub-script-check.c (grub_script_execute_cmdfor): New
|
||||||
|
function.
|
||||||
|
* tests/grub_script_for1.in: New testcase.
|
||||||
|
* conf/tests.rmk: Rules for new testcase.
|
||||||
|
|
||||||
|
2010-03-26 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 part_bsd.mod.
|
||||||
|
(part_bsd_mod_SOURCES): New variable.
|
||||||
|
(part_bsd_mod_CFLAGS): Likewise.
|
||||||
|
(part_bsd_mod_LDFLAGS): Likewise.
|
||||||
|
* conf/i386-pc.rmk (grub_setup_SOURCES): Add partmap/bsdlabel.c.
|
||||||
|
(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'. Remove 'data'.
|
||||||
|
(grub_partition_map_list): New variable.
|
||||||
|
(grub_partition_map_register): Inline.
|
||||||
|
(grub_partition_map_unregister): Likewise.
|
||||||
|
(FOR_PARTITION_MAPS): New macro.
|
||||||
|
(grub_partition_map_iterate): Removed.
|
||||||
|
(grub_partition_get_start): Handle nested partitions.
|
||||||
|
* include/grub/msdos_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/msdos.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/msdospart.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.
|
||||||
|
* util/grub-install.in: Insert all subpartition modules.
|
||||||
|
* util/ieee1275/grub-install.in: Likewise.
|
||||||
|
|
||||||
|
2010-03-24 Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
|
||||||
|
|
||||||
|
* kern/dl.c (grub_dl_resolve_symbols): Improve error message
|
||||||
|
grammar.
|
||||||
|
|
||||||
|
2010-03-24 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* .bzrignore: Add grub-bin2h, grub-reboot, and grub-set-default.
|
||||||
|
|
||||||
|
2010-03-21 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* util/grub-install.in: Copy .mo files from @datadir@/locale, to
|
||||||
|
match where 'make install' puts them.
|
||||||
|
* util/i386/efi/grub-install.in: Likewise.
|
||||||
|
|
||||||
|
2010-03-19 Colin Watson <cjwatson@ubuntu.com>
|
||||||
|
|
||||||
|
* .bzrignore: Add gentrigtables, grub-script-check,
|
||||||
|
grub_script_check_init.c, grub_script_check_init.h, and
|
||||||
|
trigtables.c.
|
||||||
|
|
||||||
|
2010-03-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* kern/parser.c: Indented.
|
||||||
|
|
||||||
|
2010-03-17 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* term/i386/pc/vesafb.c: Removed (orphaned, deprecated and broken).
|
||||||
|
|
||||||
|
2010-03-17 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
* video/fb/fbblit.c (grub_video_fbblit_blend_XXXA8888_1bit): Handle
|
||||||
|
alpha_mask_size == 0 case.
|
||||||
|
|
||||||
2010-03-14 BVK Chaitanya <bvk.groups@gmail.com>
|
2010-03-14 BVK Chaitanya <bvk.groups@gmail.com>
|
||||||
|
|
||||||
GRUB shell lexer and parser improvements.
|
GRUB shell lexer and parser improvements.
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
2010-01-12 BVK Chaitanya <bvk.groups@gmail.com>
|
|
||||||
|
|
||||||
For loop support to GRUB script.
|
|
||||||
|
|
||||||
* include/grub/script_sh.h (grub_script_cmdfor): New struct.
|
|
||||||
(grub_script_create_cmdfor): New function prototype.
|
|
||||||
(grub_script_execute_cmdfor): New function prototype.
|
|
||||||
* script/execute.c (grub_script_execute_cmdfor): New function.
|
|
||||||
* script/parser.y (command): New for command.
|
|
||||||
(forcmd): New grammar rule.
|
|
||||||
* script/script.c (grub_script_create_cmdfor): New function.
|
|
||||||
* util/grub-script-check.c (grub_script_execute_cmdfor): New
|
|
||||||
function.
|
|
|
@ -90,8 +90,7 @@ grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)),
|
||||||
return grub_error (GRUB_ERR_BAD_DEVICE,
|
return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||||
"this command is available only for disk devices");
|
"this command is available only for disk devices");
|
||||||
|
|
||||||
if (file->device->disk->partition)
|
part_start = grub_partition_get_start (file->device->disk->partition);
|
||||||
part_start = grub_partition_get_start (file->device->disk->partition);
|
|
||||||
|
|
||||||
file->read_hook = read_blocklist;
|
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
|
/* One more sanity check. Re-read all sectors by blocklists, and compare
|
||||||
those with the data read via a file. */
|
those with the data read via a file. */
|
||||||
disk = file->device->disk;
|
disk = file->device->disk;
|
||||||
if (disk->partition)
|
|
||||||
part_start = grub_partition_get_start (disk->partition);
|
part_start = grub_partition_get_start (disk->partition);
|
||||||
else
|
|
||||||
part_start = 0;
|
|
||||||
|
|
||||||
buf = grub_envblk_buffer (envblk);
|
buf = grub_envblk_buffer (envblk);
|
||||||
for (p = blocklists, index = 0; p; index += p->length, p = p->next)
|
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);
|
buf = grub_envblk_buffer (envblk);
|
||||||
disk = file->device->disk;
|
disk = file->device->disk;
|
||||||
if (disk->partition)
|
part_start = grub_partition_get_start (disk->partition);
|
||||||
part_start = grub_partition_get_start (disk->partition);
|
|
||||||
else
|
|
||||||
part_start = 0;
|
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
for (p = blocklists; p; index += p->length, p = p->next)
|
for (p = blocklists; p; index += p->length, p = p->next)
|
||||||
|
|
|
@ -35,7 +35,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/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 \
|
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 \
|
kern/fs.c kern/env.c fs/fshelp.c \
|
||||||
disk/raid.c disk/mdraid_linux.c disk/lvm.c grub_probe_init.c
|
disk/raid.c disk/mdraid_linux.c disk/lvm.c grub_probe_init.c
|
||||||
|
|
||||||
|
@ -72,8 +73,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/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 \
|
fs/befs_be.c fs/tar.c \
|
||||||
\
|
\
|
||||||
kern/partition.c partmap/msdos.c partmap/apple.c partmap/sun.c \
|
kern/partition.c partmap/msdos.c partmap/bsdlabel.c \
|
||||||
partmap/gpt.c \
|
partmap/apple.c partmap/sun.c partmap/gpt.c \
|
||||||
kern/fs.c kern/env.c fs/fshelp.c disk/raid.c \
|
kern/fs.c kern/env.c fs/fshelp.c disk/raid.c \
|
||||||
disk/raid5_recover.c disk/raid6_recover.c \
|
disk/raid5_recover.c disk/raid6_recover.c \
|
||||||
disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \
|
disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \
|
||||||
|
@ -403,6 +404,11 @@ part_gpt_mod_SOURCES = partmap/gpt.c
|
||||||
part_gpt_mod_CFLAGS = $(COMMON_CFLAGS)
|
part_gpt_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||||
part_gpt_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
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
|
# Special disk structures and generic drivers
|
||||||
|
|
||||||
pkglib_MODULES += raid.mod raid5rec.mod raid6rec.mod mdraid.mod dm_nv.mod \
|
pkglib_MODULES += raid.mod raid5rec.mod raid6rec.mod mdraid.mod dm_nv.mod \
|
||||||
|
|
|
@ -80,13 +80,13 @@ grub_setup_SOURCES = gnulib/progname.c \
|
||||||
kern/file.c kern/fs.c kern/env.c kern/list.c \
|
kern/file.c kern/fs.c kern/env.c kern/list.c \
|
||||||
fs/fshelp.c \
|
fs/fshelp.c \
|
||||||
\
|
\
|
||||||
fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \
|
fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \
|
||||||
fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
|
fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \
|
||||||
fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \
|
fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \
|
||||||
fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.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 \
|
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 \
|
disk/raid.c disk/mdraid_linux.c disk/lvm.c \
|
||||||
util/raid.c util/lvm.c \
|
util/raid.c util/lvm.c \
|
||||||
|
|
|
@ -61,8 +61,8 @@ grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c \
|
||||||
fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.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 \
|
fs/befs.c fs/befs_be.c fs/tar.c \
|
||||||
\
|
\
|
||||||
partmap/amiga.c partmap/apple.c partmap/msdos.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 \
|
disk/raid.c disk/mdraid_linux.c disk/lvm.c \
|
||||||
util/raid.c util/lvm.c gnulib/progname.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_GPT_DISK 0xee
|
||||||
#define GRUB_PC_PARTITION_TYPE_LINUX_RAID 0xfd
|
#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. */
|
/* The partition entry. */
|
||||||
struct grub_msdos_partition_entry
|
struct grub_msdos_partition_entry
|
||||||
{
|
{
|
||||||
|
@ -168,23 +99,6 @@ struct grub_msdos_partition_mbr
|
||||||
} __attribute__ ((packed));
|
} __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
|
static inline int
|
||||||
grub_msdos_partition_is_empty (int type)
|
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);
|
|| 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 */
|
#endif /* ! GRUB_PC_PARTITION_HEADER */
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#define GRUB_PART_HEADER 1
|
#define GRUB_PART_HEADER 1
|
||||||
|
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
|
#include <grub/list.h>
|
||||||
|
|
||||||
struct grub_disk;
|
struct grub_disk;
|
||||||
|
|
||||||
|
@ -28,6 +29,9 @@ typedef struct grub_partition *grub_partition_t;
|
||||||
/* Partition map type. */
|
/* Partition map type. */
|
||||||
struct grub_partition_map
|
struct grub_partition_map
|
||||||
{
|
{
|
||||||
|
/* The next partition map type. */
|
||||||
|
struct grub_partition_map *next;
|
||||||
|
|
||||||
/* The name of the partition map type. */
|
/* The name of the partition map type. */
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
|
@ -35,22 +39,15 @@ struct grub_partition_map
|
||||||
grub_err_t (*iterate) (struct grub_disk *disk,
|
grub_err_t (*iterate) (struct grub_disk *disk,
|
||||||
int (*hook) (struct grub_disk *disk,
|
int (*hook) (struct grub_disk *disk,
|
||||||
const grub_partition_t partition));
|
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;
|
|
||||||
};
|
};
|
||||||
typedef struct grub_partition_map *grub_partition_map_t;
|
typedef struct grub_partition_map *grub_partition_map_t;
|
||||||
|
|
||||||
/* Partition description. */
|
/* Partition description. */
|
||||||
struct grub_partition
|
struct grub_partition
|
||||||
{
|
{
|
||||||
|
/* The partition number. */
|
||||||
|
int number;
|
||||||
|
|
||||||
/* The start sector. */
|
/* The start sector. */
|
||||||
grub_disk_addr_t start;
|
grub_disk_addr_t start;
|
||||||
|
|
||||||
|
@ -63,8 +60,8 @@ struct grub_partition
|
||||||
/* The index of this partition in the partition table. */
|
/* The index of this partition in the partition table. */
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
/* Partition map type specific data. */
|
/* Parent partition map. */
|
||||||
void *data;
|
struct grub_partition *parent;
|
||||||
|
|
||||||
/* The type partition map. */
|
/* The type partition map. */
|
||||||
grub_partition_map_t partmap;
|
grub_partition_map_t partmap;
|
||||||
|
@ -77,17 +74,36 @@ int EXPORT_FUNC(grub_partition_iterate) (struct grub_disk *disk,
|
||||||
const grub_partition_t partition));
|
const grub_partition_t partition));
|
||||||
char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition);
|
char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition);
|
||||||
|
|
||||||
int EXPORT_FUNC(grub_partition_map_iterate) (int (*hook) (const grub_partition_map_t partmap));
|
|
||||||
|
|
||||||
void EXPORT_FUNC(grub_partition_map_register) (grub_partition_map_t partmap);
|
extern grub_partition_map_t EXPORT_VAR(grub_partition_map_list);
|
||||||
|
|
||||||
void EXPORT_FUNC(grub_partition_map_unregister) (grub_partition_map_t partmap);
|
static inline void
|
||||||
|
grub_partition_map_register (grub_partition_map_t partmap)
|
||||||
|
{
|
||||||
|
grub_list_push (GRUB_AS_LIST_P (&grub_partition_map_list),
|
||||||
|
GRUB_AS_LIST (partmap));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
grub_partition_map_unregister (grub_partition_map_t partmap)
|
||||||
|
{
|
||||||
|
grub_list_remove (GRUB_AS_LIST_P (&grub_partition_map_list),
|
||||||
|
GRUB_AS_LIST (partmap));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FOR_PARTITION_MAPS(var) for (var = grub_partition_map_list; var; var = var->next)
|
||||||
|
|
||||||
|
|
||||||
static inline grub_disk_addr_t
|
static inline grub_disk_addr_t
|
||||||
grub_partition_get_start (const grub_partition_t p)
|
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
|
static inline grub_uint64_t
|
||||||
|
|
17
kern/disk.c
17
kern/disk.c
|
@ -330,6 +330,7 @@ grub_disk_open (const char *name)
|
||||||
void
|
void
|
||||||
grub_disk_close (grub_disk_t disk)
|
grub_disk_close (grub_disk_t disk)
|
||||||
{
|
{
|
||||||
|
grub_partition_t part;
|
||||||
grub_dprintf ("disk", "Closing `%s'.\n", disk->name);
|
grub_dprintf ("disk", "Closing `%s'.\n", disk->name);
|
||||||
|
|
||||||
if (disk->dev && disk->dev->close)
|
if (disk->dev && disk->dev->close)
|
||||||
|
@ -338,7 +339,12 @@ grub_disk_close (grub_disk_t disk)
|
||||||
/* Reset the timer. */
|
/* Reset the timer. */
|
||||||
grub_last_time = grub_get_time_ms ();
|
grub_last_time = grub_get_time_ms ();
|
||||||
|
|
||||||
grub_free (disk->partition);
|
while (disk->partition)
|
||||||
|
{
|
||||||
|
part = disk->partition->parent;
|
||||||
|
grub_free (disk->partition);
|
||||||
|
disk->partition = part;
|
||||||
|
}
|
||||||
grub_free ((void *) disk->name);
|
grub_free ((void *) disk->name);
|
||||||
grub_free (disk);
|
grub_free (disk);
|
||||||
}
|
}
|
||||||
|
@ -349,18 +355,19 @@ grub_disk_close (grub_disk_t disk)
|
||||||
- Verify that the range is inside the partition. */
|
- Verify that the range is inside the partition. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_disk_adjust_range (grub_disk_t disk, grub_disk_addr_t *sector,
|
grub_disk_adjust_range (grub_disk_t disk, grub_disk_addr_t *sector,
|
||||||
grub_off_t *offset, grub_size_t size)
|
grub_off_t *offset, grub_size_t size)
|
||||||
{
|
{
|
||||||
|
grub_partition_t part;
|
||||||
*sector += *offset >> GRUB_DISK_SECTOR_BITS;
|
*sector += *offset >> GRUB_DISK_SECTOR_BITS;
|
||||||
*offset &= GRUB_DISK_SECTOR_SIZE - 1;
|
*offset &= GRUB_DISK_SECTOR_SIZE - 1;
|
||||||
|
|
||||||
if (disk->partition)
|
for (part = disk->partition; part; part = part->parent)
|
||||||
{
|
{
|
||||||
grub_disk_addr_t start;
|
grub_disk_addr_t start;
|
||||||
grub_uint64_t len;
|
grub_uint64_t len;
|
||||||
|
|
||||||
start = grub_partition_get_start (disk->partition);
|
start = part->start;
|
||||||
len = grub_partition_get_len (disk->partition);
|
len = part->len;
|
||||||
|
|
||||||
if (*sector >= len
|
if (*sector >= len
|
||||||
|| len - *sector < ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1)
|
|| len - *sector < ((*offset + size + GRUB_DISK_SECTOR_SIZE - 1)
|
||||||
|
|
|
@ -348,7 +348,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e)
|
||||||
sym->st_value = (Elf_Addr) grub_dl_resolve_symbol (name);
|
sym->st_value = (Elf_Addr) grub_dl_resolve_symbol (name);
|
||||||
if (! sym->st_value)
|
if (! sym->st_value)
|
||||||
return grub_error (GRUB_ERR_BAD_MODULE,
|
return grub_error (GRUB_ERR_BAD_MODULE,
|
||||||
"the symbol `%s' not found", name);
|
"symbol not found: `%s'", name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
140
kern/parser.c
140
kern/parser.c
|
@ -26,32 +26,31 @@
|
||||||
/* All the possible state transitions on the command line. If a
|
/* All the possible state transitions on the command line. If a
|
||||||
transition can not be found, it is assumed that there is no
|
transition can not be found, it is assumed that there is no
|
||||||
transition and keep_value is assumed to be 1. */
|
transition and keep_value is assumed to be 1. */
|
||||||
static struct grub_parser_state_transition state_transitions[] =
|
static struct grub_parser_state_transition state_transitions[] = {
|
||||||
{
|
{GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_QUOTE, '\'', 0},
|
||||||
{ GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_QUOTE, '\'', 0},
|
{GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_DQUOTE, '\"', 0},
|
||||||
{ GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_DQUOTE, '\"', 0},
|
{GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_VAR, '$', 0},
|
||||||
{ GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_VAR, '$', 0},
|
{GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_ESC, '\\', 0},
|
||||||
{ GRUB_PARSER_STATE_TEXT, GRUB_PARSER_STATE_ESC, '\\', 0},
|
|
||||||
|
|
||||||
{ GRUB_PARSER_STATE_ESC, GRUB_PARSER_STATE_TEXT, 0, 1},
|
{GRUB_PARSER_STATE_ESC, GRUB_PARSER_STATE_TEXT, 0, 1},
|
||||||
|
|
||||||
{ GRUB_PARSER_STATE_QUOTE, GRUB_PARSER_STATE_TEXT, '\'', 0},
|
{GRUB_PARSER_STATE_QUOTE, GRUB_PARSER_STATE_TEXT, '\'', 0},
|
||||||
|
|
||||||
{ GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_TEXT, '\"', 0},
|
{GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_TEXT, '\"', 0},
|
||||||
{ GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_QVAR, '$', 0},
|
{GRUB_PARSER_STATE_DQUOTE, GRUB_PARSER_STATE_QVAR, '$', 0},
|
||||||
|
|
||||||
{ GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME2, '{', 0},
|
{GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME2, '{', 0},
|
||||||
{ GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME, 0, 1},
|
{GRUB_PARSER_STATE_VAR, GRUB_PARSER_STATE_VARNAME, 0, 1},
|
||||||
{ GRUB_PARSER_STATE_VARNAME, GRUB_PARSER_STATE_TEXT, ' ', 1},
|
{GRUB_PARSER_STATE_VARNAME, GRUB_PARSER_STATE_TEXT, ' ', 1},
|
||||||
{ GRUB_PARSER_STATE_VARNAME2, GRUB_PARSER_STATE_TEXT, '}', 0},
|
{GRUB_PARSER_STATE_VARNAME2, GRUB_PARSER_STATE_TEXT, '}', 0},
|
||||||
|
|
||||||
{ GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME2, '{', 0},
|
{GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME2, '{', 0},
|
||||||
{ GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME, 0, 1},
|
{GRUB_PARSER_STATE_QVAR, GRUB_PARSER_STATE_QVARNAME, 0, 1},
|
||||||
{ GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_TEXT, '\"', 0},
|
{GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_TEXT, '\"', 0},
|
||||||
{ GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_DQUOTE, ' ', 1},
|
{GRUB_PARSER_STATE_QVARNAME, GRUB_PARSER_STATE_DQUOTE, ' ', 1},
|
||||||
{ GRUB_PARSER_STATE_QVARNAME2, GRUB_PARSER_STATE_DQUOTE, '}', 0},
|
{GRUB_PARSER_STATE_QVARNAME2, GRUB_PARSER_STATE_DQUOTE, '}', 0},
|
||||||
|
|
||||||
{ 0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,17 +73,17 @@ grub_parser_cmdline_state (grub_parser_state_t state, char c, char *result)
|
||||||
if (transition->input == c)
|
if (transition->input == c)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (transition->input == ' ' && ! grub_isalpha (c)
|
if (transition->input == ' ' && !grub_isalpha (c)
|
||||||
&& ! grub_isdigit (c) && c != '_')
|
&& !grub_isdigit (c) && c != '_')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* A less perfect match was found, use this one if no exact
|
/* A less perfect match was found, use this one if no exact
|
||||||
match can be found. */
|
match can be found. */
|
||||||
if (transition->input == 0)
|
if (transition->input == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! transition->from_state)
|
if (!transition->from_state)
|
||||||
transition = &default_transition;
|
transition = &default_transition;
|
||||||
|
|
||||||
if (transition->keep_value)
|
if (transition->keep_value)
|
||||||
|
@ -113,43 +112,44 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline,
|
||||||
auto int check_varstate (grub_parser_state_t s);
|
auto int check_varstate (grub_parser_state_t s);
|
||||||
|
|
||||||
int check_varstate (grub_parser_state_t s)
|
int check_varstate (grub_parser_state_t s)
|
||||||
{
|
{
|
||||||
return (s == GRUB_PARSER_STATE_VARNAME
|
return (s == GRUB_PARSER_STATE_VARNAME
|
||||||
|| s == GRUB_PARSER_STATE_VARNAME2
|
|| s == GRUB_PARSER_STATE_VARNAME2
|
||||||
|| s == GRUB_PARSER_STATE_QVARNAME
|
|| s == GRUB_PARSER_STATE_QVARNAME
|
||||||
|| s == GRUB_PARSER_STATE_QVARNAME2);
|
|| s == GRUB_PARSER_STATE_QVARNAME2);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto void add_var (grub_parser_state_t newstate);
|
auto void add_var (grub_parser_state_t newstate);
|
||||||
|
|
||||||
void add_var (grub_parser_state_t newstate)
|
void add_var (grub_parser_state_t newstate)
|
||||||
{
|
{
|
||||||
char *val;
|
char *val;
|
||||||
|
|
||||||
/* Check if a variable was being read in and the end of the name
|
/* Check if a variable was being read in and the end of the name
|
||||||
was reached. */
|
was reached. */
|
||||||
if (! (check_varstate (state) && !check_varstate (newstate)))
|
if (!(check_varstate (state) && !check_varstate (newstate)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
*(vp++) = '\0';
|
*(vp++) = '\0';
|
||||||
val = grub_env_get (varname);
|
val = grub_env_get (varname);
|
||||||
vp = varname;
|
vp = varname;
|
||||||
if (! val)
|
if (!val)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Insert the contents of the variable in the buffer. */
|
/* Insert the contents of the variable in the buffer. */
|
||||||
for (; *val; val++)
|
for (; *val; val++)
|
||||||
*(bp++) = *val;
|
*(bp++) = *val;
|
||||||
}
|
}
|
||||||
|
|
||||||
*argc = 0;
|
*argc = 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (! rd || !*rd)
|
if (!rd || !*rd)
|
||||||
{
|
{
|
||||||
if (getline)
|
if (getline)
|
||||||
getline (&rd, 1);
|
getline (&rd, 1);
|
||||||
else break;
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rd)
|
if (!rd)
|
||||||
|
@ -190,7 +190,8 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline,
|
||||||
}
|
}
|
||||||
state = newstate;
|
state = newstate;
|
||||||
}
|
}
|
||||||
} while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state));
|
}
|
||||||
|
while (state != GRUB_PARSER_STATE_TEXT && !check_varstate (state));
|
||||||
|
|
||||||
/* A special case for when the last character was part of a
|
/* A special case for when the last character was part of a
|
||||||
variable. */
|
variable. */
|
||||||
|
@ -204,12 +205,12 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline,
|
||||||
|
|
||||||
/* Reserve memory for the return values. */
|
/* Reserve memory for the return values. */
|
||||||
args = grub_malloc (bp - buffer);
|
args = grub_malloc (bp - buffer);
|
||||||
if (! args)
|
if (!args)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
grub_memcpy (args, buffer, bp - buffer);
|
grub_memcpy (args, buffer, bp - buffer);
|
||||||
|
|
||||||
*argv = grub_malloc (sizeof (char *) * (*argc + 1));
|
*argv = grub_malloc (sizeof (char *) * (*argc + 1));
|
||||||
if (! *argv)
|
if (!*argv)
|
||||||
{
|
{
|
||||||
grub_free (args);
|
grub_free (args);
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
@ -229,35 +230,34 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct grub_handler_class grub_parser_class =
|
struct grub_handler_class grub_parser_class = {
|
||||||
{
|
.name = "parser"
|
||||||
.name = "parser"
|
};
|
||||||
};
|
|
||||||
|
|
||||||
grub_err_t
|
grub_err_t
|
||||||
grub_parser_execute (char *source)
|
grub_parser_execute (char *source)
|
||||||
{
|
{
|
||||||
auto grub_err_t getline (char **line, int cont);
|
auto grub_err_t getline (char **line, int cont);
|
||||||
grub_err_t getline (char **line, int cont __attribute__ ((unused)))
|
grub_err_t getline (char **line, int cont __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
if (! source)
|
if (!source)
|
||||||
{
|
{
|
||||||
*line = 0;
|
*line = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = grub_strchr (source, '\n');
|
p = grub_strchr (source, '\n');
|
||||||
if (p)
|
if (p)
|
||||||
*p = 0;
|
*p = 0;
|
||||||
|
|
||||||
*line = grub_strdup (source);
|
*line = grub_strdup (source);
|
||||||
if (p)
|
if (p)
|
||||||
*p = '\n';
|
*p = '\n';
|
||||||
source = p ? p + 1 : 0;
|
source = p ? p + 1 : 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (source)
|
while (source)
|
||||||
{
|
{
|
||||||
|
|
208
kern/partition.c
208
kern/partition.c
|
@ -17,40 +17,44 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
#include <grub/partition.h>
|
#include <grub/partition.h>
|
||||||
#include <grub/disk.h>
|
#include <grub/disk.h>
|
||||||
|
|
||||||
static grub_partition_map_t grub_partition_map_list;
|
grub_partition_map_t grub_partition_map_list;
|
||||||
|
|
||||||
void
|
static grub_partition_t
|
||||||
grub_partition_map_register (grub_partition_map_t partmap)
|
grub_partition_map_probe (const grub_partition_map_t partmap,
|
||||||
|
grub_disk_t disk, int partnum)
|
||||||
{
|
{
|
||||||
partmap->next = grub_partition_map_list;
|
grub_partition_t p = 0;
|
||||||
grub_partition_map_list = partmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
auto int find_func (grub_disk_t d, const grub_partition_t partition);
|
||||||
grub_partition_map_unregister (grub_partition_map_t partmap)
|
|
||||||
{
|
|
||||||
grub_partition_map_t *p, q;
|
|
||||||
|
|
||||||
for (p = &grub_partition_map_list, q = *p; q; p = &(q->next), q = q->next)
|
int find_func (grub_disk_t d __attribute__ ((unused)),
|
||||||
if (q == partmap)
|
const grub_partition_t partition)
|
||||||
{
|
{
|
||||||
*p = q->next;
|
if (partnum == partition->number)
|
||||||
break;
|
{
|
||||||
}
|
p = (grub_partition_t) grub_malloc (sizeof (*p));
|
||||||
}
|
if (! p)
|
||||||
|
return 1;
|
||||||
|
|
||||||
int
|
grub_memcpy (p, partition, sizeof (*p));
|
||||||
grub_partition_map_iterate (int (*hook) (const grub_partition_map_t partmap))
|
return 1;
|
||||||
{
|
}
|
||||||
grub_partition_map_t p;
|
|
||||||
|
|
||||||
for (p = grub_partition_map_list; p; p = p->next)
|
return 0;
|
||||||
if (hook (p))
|
}
|
||||||
return 1;
|
|
||||||
|
|
||||||
|
partmap->iterate (disk, find_func);
|
||||||
|
if (grub_errno)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
grub_free (p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,28 +62,66 @@ grub_partition_t
|
||||||
grub_partition_probe (struct grub_disk *disk, const char *str)
|
grub_partition_probe (struct grub_disk *disk, const char *str)
|
||||||
{
|
{
|
||||||
grub_partition_t part = 0;
|
grub_partition_t part = 0;
|
||||||
|
grub_partition_t curpart = 0;
|
||||||
|
grub_partition_t tail;
|
||||||
|
const char *ptr;
|
||||||
|
|
||||||
auto int part_map_probe (const grub_partition_map_t partmap);
|
part = tail = disk->partition;
|
||||||
|
|
||||||
int part_map_probe (const grub_partition_map_t partmap)
|
for (ptr = str; *ptr;)
|
||||||
{
|
{
|
||||||
part = partmap->probe (disk, str);
|
grub_partition_map_t partmap;
|
||||||
if (part)
|
int num;
|
||||||
return 1;
|
const char *partname, *partname_end;
|
||||||
|
|
||||||
if (grub_errno == GRUB_ERR_BAD_PART_TABLE)
|
partname = ptr;
|
||||||
|
while (*ptr && grub_isalpha (*ptr))
|
||||||
|
ptr++;
|
||||||
|
partname_end = ptr;
|
||||||
|
num = grub_strtoul (ptr, (char **) &ptr, 0) - 1;
|
||||||
|
|
||||||
|
curpart = 0;
|
||||||
|
/* Use the first partition map type found. */
|
||||||
|
FOR_PARTITION_MAPS(partmap)
|
||||||
|
{
|
||||||
|
if (partname_end != partname &&
|
||||||
|
(grub_strncmp (partmap->name, partname, partname_end - partname)
|
||||||
|
!= 0 || partmap->name[partname_end - partname] != 0))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
disk->partition = part;
|
||||||
|
curpart = grub_partition_map_probe (partmap, disk, num);
|
||||||
|
disk->partition = tail;
|
||||||
|
if (curpart)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (grub_errno == GRUB_ERR_BAD_PART_TABLE)
|
||||||
|
{
|
||||||
|
/* Continue to next partition map type. */
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! curpart)
|
||||||
{
|
{
|
||||||
/* Continue to next partition map type. */
|
while (part)
|
||||||
grub_errno = GRUB_ERR_NONE;
|
{
|
||||||
|
curpart = part->parent;
|
||||||
|
grub_free (part);
|
||||||
|
part = curpart;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
curpart->parent = part;
|
||||||
return 1;
|
part = curpart;
|
||||||
|
if (! ptr || *ptr != ',')
|
||||||
|
break;
|
||||||
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use the first partition map type found. */
|
|
||||||
grub_partition_map_iterate (part_map_probe);
|
|
||||||
|
|
||||||
return part;
|
return part;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,40 +130,51 @@ grub_partition_iterate (struct grub_disk *disk,
|
||||||
int (*hook) (grub_disk_t disk,
|
int (*hook) (grub_disk_t disk,
|
||||||
const grub_partition_t partition))
|
const grub_partition_t partition))
|
||||||
{
|
{
|
||||||
grub_partition_map_t partmap = 0;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
auto int part_map_iterate (const grub_partition_map_t p);
|
auto int part_iterate (grub_disk_t dsk, const grub_partition_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)),
|
int part_iterate (grub_disk_t dsk,
|
||||||
const grub_partition_t partition __attribute__ ((unused)))
|
const grub_partition_t partition)
|
||||||
{
|
{
|
||||||
return 1;
|
struct grub_partition p = *partition;
|
||||||
}
|
p.parent = dsk->partition;
|
||||||
|
dsk->partition = 0;
|
||||||
int part_map_iterate (const grub_partition_map_t p)
|
if (hook (dsk, &p))
|
||||||
{
|
|
||||||
grub_dprintf ("partition", "Detecting %s...\n", p->name);
|
|
||||||
p->iterate (disk, part_map_iterate_hook);
|
|
||||||
|
|
||||||
if (grub_errno != GRUB_ERR_NONE)
|
|
||||||
{
|
{
|
||||||
/* Continue to next partition map type. */
|
ret = 1;
|
||||||
grub_dprintf ("partition", "%s detection failed.\n", p->name);
|
return 1;
|
||||||
grub_errno = GRUB_ERR_NONE;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
if (p.start != 0)
|
||||||
grub_dprintf ("partition", "%s detection succeeded.\n", p->name);
|
{
|
||||||
partmap = p;
|
const struct grub_partition_map *partmap;
|
||||||
return 1;
|
dsk->partition = &p;
|
||||||
|
FOR_PARTITION_MAPS(partmap)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
err = partmap->iterate (dsk, part_iterate);
|
||||||
|
if (err)
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dsk->partition = p.parent;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_partition_map_iterate (part_map_iterate);
|
{
|
||||||
if (partmap)
|
const struct grub_partition_map *partmap;
|
||||||
ret = partmap->iterate (disk, hook);
|
FOR_PARTITION_MAPS(partmap)
|
||||||
|
{
|
||||||
|
grub_err_t err;
|
||||||
|
err = partmap->iterate (disk, part_iterate);
|
||||||
|
if (err)
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -129,5 +182,32 @@ grub_partition_iterate (struct grub_disk *disk,
|
||||||
char *
|
char *
|
||||||
grub_partition_get_name (const grub_partition_t partition)
|
grub_partition_get_name (const grub_partition_t partition)
|
||||||
{
|
{
|
||||||
return partition->partmap->get_name (partition);
|
char *out = 0;
|
||||||
|
int curlen = 0;
|
||||||
|
grub_partition_t part;
|
||||||
|
for (part = partition; part; part = part->parent)
|
||||||
|
{
|
||||||
|
/* Even on 64-bit machines this buffer is enough to hold
|
||||||
|
longest number. */
|
||||||
|
char buf[grub_strlen (part->partmap->name) + 25];
|
||||||
|
int strl;
|
||||||
|
grub_snprintf (buf, sizeof (buf), "%s%d", part->partmap->name,
|
||||||
|
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 * unit,
|
||||||
grub_uint32_t * slice, grub_uint32_t * part)
|
grub_uint32_t * slice, grub_uint32_t * part)
|
||||||
{
|
{
|
||||||
char *p;
|
|
||||||
grub_device_t dev;
|
grub_device_t dev;
|
||||||
|
|
||||||
#ifdef GRUB_MACHINE_PCBIOS
|
#ifdef GRUB_MACHINE_PCBIOS
|
||||||
|
@ -154,22 +153,13 @@ grub_bsd_get_device (grub_uint32_t * biosdev,
|
||||||
dev = grub_device_open (0);
|
dev = grub_device_open (0);
|
||||||
if (dev && dev->disk && dev->disk->partition)
|
if (dev && dev->disk && dev->disk->partition)
|
||||||
{
|
{
|
||||||
char *p0;
|
if (dev->disk->partition->parent)
|
||||||
p0 = p = dev->disk->partition->partmap->get_name (dev->disk->partition);
|
|
||||||
if (p)
|
|
||||||
{
|
{
|
||||||
if ((p[0] >= '0') && (p[0] <= '9'))
|
*part = dev->disk->partition->number;
|
||||||
{
|
*slice = dev->disk->partition->parent->number + 1;
|
||||||
*slice = grub_strtoul (p, &p, 0);
|
|
||||||
|
|
||||||
if ((p) && (p[0] == ','))
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((p[0] >= 'a') && (p[0] <= 'z'))
|
|
||||||
*part = p[0] - 'a';
|
|
||||||
}
|
}
|
||||||
grub_free (p0);
|
else
|
||||||
|
*slice = dev->disk->partition->number + 1;
|
||||||
}
|
}
|
||||||
if (dev)
|
if (dev)
|
||||||
grub_device_close (dev);
|
grub_device_close (dev);
|
||||||
|
|
|
@ -435,7 +435,6 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
|
||||||
void
|
void
|
||||||
grub_multiboot_set_bootdev (void)
|
grub_multiboot_set_bootdev (void)
|
||||||
{
|
{
|
||||||
char *p;
|
|
||||||
grub_uint32_t biosdev, slice = ~0, part = ~0;
|
grub_uint32_t biosdev, slice = ~0, part = ~0;
|
||||||
grub_device_t dev;
|
grub_device_t dev;
|
||||||
|
|
||||||
|
@ -448,22 +447,13 @@ grub_multiboot_set_bootdev (void)
|
||||||
dev = grub_device_open (0);
|
dev = grub_device_open (0);
|
||||||
if (dev && dev->disk && dev->disk->partition)
|
if (dev && dev->disk && dev->disk->partition)
|
||||||
{
|
{
|
||||||
char *p0;
|
if (dev->disk->partition->parent)
|
||||||
p = p0 = dev->disk->partition->partmap->get_name (dev->disk->partition);
|
{
|
||||||
if (p)
|
part = dev->disk->partition->number;
|
||||||
{
|
slice = dev->disk->partition->parent->number;
|
||||||
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';
|
|
||||||
}
|
}
|
||||||
grub_free (p0);
|
else
|
||||||
|
slice = dev->disk->partition->number;
|
||||||
}
|
}
|
||||||
if (dev)
|
if (dev)
|
||||||
grub_device_close (dev);
|
grub_device_close (dev);
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <grub/machine/memory.h>
|
#include <grub/machine/memory.h>
|
||||||
#include <grub/dl.h>
|
#include <grub/dl.h>
|
||||||
#include <grub/command.h>
|
#include <grub/command.h>
|
||||||
|
#include <grub/msdos_partition.h>
|
||||||
#include <grub/machine/biosnum.h>
|
#include <grub/machine/biosnum.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
#include <grub/video.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);
|
dev = grub_device_open (0);
|
||||||
if (dev && dev->disk && dev->disk->partition)
|
if (dev && dev->disk && dev->disk->partition)
|
||||||
{
|
{
|
||||||
grub_disk_read (dev->disk, dev->disk->partition->offset, 446, 64,
|
grub_disk_t disk = dev->disk;
|
||||||
(void *) GRUB_MEMORY_MACHINE_PART_TABLE_ADDR);
|
|
||||||
part_addr = (void *) (GRUB_MEMORY_MACHINE_PART_TABLE_ADDR
|
if (disk)
|
||||||
+ (dev->disk->partition->index << 4));
|
{
|
||||||
|
grub_partition_t p = disk->partition;
|
||||||
|
|
||||||
|
if (p && grub_strcmp (p->partmap->name, "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
|
||||||
|
+ (p->index << 4));
|
||||||
|
disk->partition = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev)
|
if (dev)
|
||||||
|
|
|
@ -96,17 +96,12 @@ acorn_partition_map_iterate (grub_disk_t disk,
|
||||||
const grub_partition_t partition))
|
const grub_partition_t partition))
|
||||||
{
|
{
|
||||||
struct grub_partition part;
|
struct grub_partition part;
|
||||||
struct grub_disk raw;
|
|
||||||
struct linux_part map[LINUX_MAP_ENTRIES];
|
struct linux_part map[LINUX_MAP_ENTRIES];
|
||||||
int i;
|
int i;
|
||||||
grub_disk_addr_t sector;
|
grub_disk_addr_t sector = 0;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
||||||
/* Enforce raw disk access. */
|
err = acorn_partition_map_find (disk, map, §or);
|
||||||
raw = *disk;
|
|
||||||
raw.partition = 0;
|
|
||||||
|
|
||||||
err = acorn_partition_map_find (&raw, map, §or);
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -121,7 +116,7 @@ acorn_partition_map_iterate (grub_disk_t disk,
|
||||||
part.start = sector + map[i].start;
|
part.start = sector + map[i].start;
|
||||||
part.len = map[i].size;
|
part.len = map[i].size;
|
||||||
part.offset = 6;
|
part.offset = 6;
|
||||||
part.index = i;
|
part.number = part.index = i;
|
||||||
|
|
||||||
if (hook (disk, &part))
|
if (hook (disk, &part))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
@ -130,62 +125,13 @@ acorn_partition_map_iterate (grub_disk_t disk,
|
||||||
return GRUB_ERR_NONE;
|
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. */
|
/* Partition map type. */
|
||||||
static struct grub_partition_map grub_acorn_partition_map =
|
static struct grub_partition_map grub_acorn_partition_map =
|
||||||
{
|
{
|
||||||
.name = "part_acorn",
|
.name = "acorn",
|
||||||
.iterate = acorn_partition_map_iterate,
|
.iterate = acorn_partition_map_iterate,
|
||||||
.probe = acorn_partition_map_probe,
|
|
||||||
.get_name = acorn_partition_map_get_name
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GRUB_MOD_INIT(part_acorn)
|
GRUB_MOD_INIT(part_acorn)
|
||||||
|
|
|
@ -76,20 +76,15 @@ amiga_partition_map_iterate (grub_disk_t disk,
|
||||||
{
|
{
|
||||||
struct grub_partition part;
|
struct grub_partition part;
|
||||||
struct grub_amiga_rdsk rdsk;
|
struct grub_amiga_rdsk rdsk;
|
||||||
struct grub_disk raw;
|
|
||||||
int partno = 0;
|
int partno = 0;
|
||||||
int next = -1;
|
int next = -1;
|
||||||
unsigned pos;
|
unsigned pos;
|
||||||
|
|
||||||
/* Enforce raw disk access. */
|
|
||||||
raw = *disk;
|
|
||||||
raw.partition = 0;
|
|
||||||
|
|
||||||
/* The RDSK block is one of the first 15 blocks. */
|
/* The RDSK block is one of the first 15 blocks. */
|
||||||
for (pos = 0; pos < 15; pos++)
|
for (pos = 0; pos < 15; pos++)
|
||||||
{
|
{
|
||||||
/* Read the RDSK block which is a descriptor for the entire disk. */
|
/* 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;
|
return grub_errno;
|
||||||
|
|
||||||
if (grub_strcmp ((char *) rdsk.magic, "RDSK") == 0)
|
if (grub_strcmp ((char *) rdsk.magic, "RDSK") == 0)
|
||||||
|
@ -110,7 +105,7 @@ amiga_partition_map_iterate (grub_disk_t disk,
|
||||||
struct grub_amiga_partition apart;
|
struct grub_amiga_partition apart;
|
||||||
|
|
||||||
/* Read the RDSK block which is a descriptor for the entire disk. */
|
/* 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;
|
return grub_errno;
|
||||||
|
|
||||||
/* Calculate the first block and the size of the partition. */
|
/* Calculate the first block and the size of the partition. */
|
||||||
|
@ -123,7 +118,8 @@ amiga_partition_map_iterate (grub_disk_t disk,
|
||||||
* grub_be_to_cpu32 (apart.block_per_track));
|
* grub_be_to_cpu32 (apart.block_per_track));
|
||||||
|
|
||||||
part.offset = (grub_off_t) next * 512;
|
part.offset = (grub_off_t) next * 512;
|
||||||
part.index = partno;
|
part.number = partno;
|
||||||
|
part.index = 0;
|
||||||
part.partmap = &grub_amiga_partition_map;
|
part.partmap = &grub_amiga_partition_map;
|
||||||
|
|
||||||
if (hook (disk, &part))
|
if (hook (disk, &part))
|
||||||
|
@ -136,65 +132,12 @@ amiga_partition_map_iterate (grub_disk_t disk,
|
||||||
return 0;
|
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. */
|
/* Partition map type. */
|
||||||
static struct grub_partition_map grub_amiga_partition_map =
|
static struct grub_partition_map grub_amiga_partition_map =
|
||||||
{
|
{
|
||||||
.name = "part_amiga",
|
.name = "amiga",
|
||||||
.iterate = amiga_partition_map_iterate,
|
.iterate = amiga_partition_map_iterate,
|
||||||
.probe = amiga_partition_map_probe,
|
|
||||||
.get_name = amiga_partition_map_get_name
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GRUB_MOD_INIT(part_amiga)
|
GRUB_MOD_INIT(part_amiga)
|
||||||
|
|
|
@ -105,17 +105,12 @@ apple_partition_map_iterate (grub_disk_t disk,
|
||||||
struct grub_partition part;
|
struct grub_partition part;
|
||||||
struct grub_apple_header aheader;
|
struct grub_apple_header aheader;
|
||||||
struct grub_apple_part apart;
|
struct grub_apple_part apart;
|
||||||
struct grub_disk raw;
|
|
||||||
int partno = 0, partnum = 0;
|
int partno = 0, partnum = 0;
|
||||||
unsigned pos;
|
unsigned pos;
|
||||||
|
|
||||||
/* Enforce raw disk access. */
|
|
||||||
raw = *disk;
|
|
||||||
raw.partition = 0;
|
|
||||||
|
|
||||||
part.partmap = &grub_apple_partition_map;
|
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;
|
return grub_errno;
|
||||||
|
|
||||||
if (grub_be_to_cpu16 (aheader.magic) != GRUB_APPLE_HEADER_MAGIC)
|
if (grub_be_to_cpu16 (aheader.magic) != GRUB_APPLE_HEADER_MAGIC)
|
||||||
|
@ -131,8 +126,10 @@ apple_partition_map_iterate (grub_disk_t disk,
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (grub_disk_read (&raw, pos / GRUB_DISK_SECTOR_SIZE,
|
part.offset = pos / GRUB_DISK_SECTOR_SIZE;
|
||||||
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))
|
sizeof (struct grub_apple_part), &apart))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
|
@ -156,6 +153,7 @@ apple_partition_map_iterate (grub_disk_t disk,
|
||||||
/ GRUB_DISK_SECTOR_SIZE;
|
/ GRUB_DISK_SECTOR_SIZE;
|
||||||
part.offset = pos;
|
part.offset = pos;
|
||||||
part.index = partno;
|
part.index = partno;
|
||||||
|
part.number = partno;
|
||||||
|
|
||||||
grub_dprintf ("partition",
|
grub_dprintf ("partition",
|
||||||
"partition %d: name %s, type %s, start 0x%x, len 0x%x\n",
|
"partition %d: name %s, type %s, start 0x%x, len 0x%x\n",
|
||||||
|
@ -179,65 +177,12 @@ apple_partition_map_iterate (grub_disk_t disk,
|
||||||
"Apple partition map not found");
|
"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. */
|
/* Partition map type. */
|
||||||
static struct grub_partition_map grub_apple_partition_map =
|
static struct grub_partition_map grub_apple_partition_map =
|
||||||
{
|
{
|
||||||
.name = "part_apple",
|
.name = "apple",
|
||||||
.iterate = apple_partition_map_iterate,
|
.iterate = apple_partition_map_iterate,
|
||||||
.probe = apple_partition_map_probe,
|
|
||||||
.get_name = apple_partition_map_get_name
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GRUB_MOD_INIT(part_apple)
|
GRUB_MOD_INIT(part_apple)
|
||||||
|
|
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 = "bsd",
|
||||||
|
.iterate = bsdlabel_partition_map_iterate,
|
||||||
|
};
|
||||||
|
|
||||||
|
GRUB_MOD_INIT(part_bsd)
|
||||||
|
{
|
||||||
|
grub_partition_map_register (&grub_bsdlabel_partition_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
GRUB_MOD_FINI(part_bsd)
|
||||||
|
{
|
||||||
|
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_partition part;
|
||||||
struct grub_gpt_header gpt;
|
struct grub_gpt_header gpt;
|
||||||
struct grub_gpt_partentry entry;
|
struct grub_gpt_partentry entry;
|
||||||
struct grub_disk raw;
|
|
||||||
struct grub_msdos_partition_mbr mbr;
|
struct grub_msdos_partition_mbr mbr;
|
||||||
grub_uint64_t entries;
|
grub_uint64_t entries;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int last_offset = 0;
|
int last_offset = 0;
|
||||||
|
|
||||||
/* Enforce raw disk access. */
|
|
||||||
raw = *disk;
|
|
||||||
raw.partition = 0;
|
|
||||||
|
|
||||||
/* Read the protective MBR. */
|
/* 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;
|
return grub_errno;
|
||||||
|
|
||||||
/* Check if it is valid. */
|
/* 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");
|
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found");
|
||||||
|
|
||||||
/* Read the GPT header. */
|
/* 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;
|
return grub_errno;
|
||||||
|
|
||||||
if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic)))
|
if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic)))
|
||||||
|
@ -78,7 +73,7 @@ gpt_partition_map_iterate (grub_disk_t disk,
|
||||||
entries = grub_le_to_cpu64 (gpt.partitions);
|
entries = grub_le_to_cpu64 (gpt.partitions);
|
||||||
for (i = 0; i < grub_le_to_cpu32 (gpt.maxpart); i++)
|
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))
|
sizeof (entry), &entry))
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
|
@ -90,16 +85,16 @@ gpt_partition_map_iterate (grub_disk_t disk,
|
||||||
part.len = (grub_le_to_cpu64 (entry.end)
|
part.len = (grub_le_to_cpu64 (entry.end)
|
||||||
- grub_le_to_cpu64 (entry.start) + 1);
|
- grub_le_to_cpu64 (entry.start) + 1);
|
||||||
part.offset = entries;
|
part.offset = entries;
|
||||||
part.index = i;
|
part.number = i;
|
||||||
|
part.index = last_offset;
|
||||||
part.partmap = &grub_gpt_partition_map;
|
part.partmap = &grub_gpt_partition_map;
|
||||||
part.data = &entry;
|
|
||||||
|
|
||||||
grub_dprintf ("gpt", "GPT entry %d: start=%lld, length=%lld\n", i,
|
grub_dprintf ("gpt", "GPT entry %d: start=%lld, length=%lld\n", i,
|
||||||
(unsigned long long) part.start,
|
(unsigned long long) part.start,
|
||||||
(unsigned long long) part.len);
|
(unsigned long long) part.len);
|
||||||
|
|
||||||
if (hook (disk, &part))
|
if (hook (disk, &part))
|
||||||
return 1;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_offset += grub_le_to_cpu32 (gpt.partentry_size);
|
last_offset += grub_le_to_cpu32 (gpt.partentry_size);
|
||||||
|
@ -110,69 +105,15 @@ gpt_partition_map_iterate (grub_disk_t disk,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return GRUB_ERR_NONE;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Partition map type. */
|
/* Partition map type. */
|
||||||
static struct grub_partition_map grub_gpt_partition_map =
|
static struct grub_partition_map grub_gpt_partition_map =
|
||||||
{
|
{
|
||||||
.name = "part_gpt",
|
.name = "gpt",
|
||||||
.iterate = gpt_partition_map_iterate,
|
.iterate = gpt_partition_map_iterate,
|
||||||
.probe = gpt_partition_map_probe,
|
|
||||||
.get_name = gpt_partition_map_get_name
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GRUB_MOD_INIT(part_gpt)
|
GRUB_MOD_INIT(part_gpt)
|
||||||
|
|
206
partmap/msdos.c
206
partmap/msdos.c
|
@ -27,87 +27,20 @@
|
||||||
static struct grub_partition_map grub_msdos_partition_map;
|
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
|
static grub_err_t
|
||||||
pc_partition_map_iterate (grub_disk_t disk,
|
pc_partition_map_iterate (grub_disk_t disk,
|
||||||
int (*hook) (grub_disk_t disk,
|
int (*hook) (grub_disk_t disk,
|
||||||
const grub_partition_t partition))
|
const grub_partition_t partition))
|
||||||
{
|
{
|
||||||
struct grub_partition p;
|
struct grub_partition p;
|
||||||
struct grub_msdos_partition pcdata;
|
|
||||||
struct grub_msdos_partition_mbr mbr;
|
struct grub_msdos_partition_mbr mbr;
|
||||||
struct grub_msdos_partition_disk_label label;
|
|
||||||
struct grub_disk raw;
|
|
||||||
int labeln = 0;
|
int labeln = 0;
|
||||||
grub_disk_addr_t lastaddr;
|
grub_disk_addr_t lastaddr;
|
||||||
|
grub_disk_addr_t ext_offset;
|
||||||
/* Enforce raw disk access. */
|
|
||||||
raw = *disk;
|
|
||||||
raw.partition = 0;
|
|
||||||
|
|
||||||
p.offset = 0;
|
p.offset = 0;
|
||||||
pcdata.ext_offset = 0;
|
ext_offset = 0;
|
||||||
pcdata.dos_part = -1;
|
p.number = -1;
|
||||||
p.data = &pcdata;
|
|
||||||
p.partmap = &grub_msdos_partition_map;
|
p.partmap = &grub_msdos_partition_map;
|
||||||
|
|
||||||
/* Any value different than `p.offset' will satisfy the check during
|
/* Any value different than `p.offset' will satisfy the check during
|
||||||
|
@ -120,7 +53,7 @@ pc_partition_map_iterate (grub_disk_t disk,
|
||||||
struct grub_msdos_partition_entry *e;
|
struct grub_msdos_partition_entry *e;
|
||||||
|
|
||||||
/* Read the MBR. */
|
/* 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;
|
goto finish;
|
||||||
|
|
||||||
/* This is our loop-detection algorithm. It works the following way:
|
/* This is our loop-detection algorithm. It works the following way:
|
||||||
|
@ -150,13 +83,10 @@ pc_partition_map_iterate (grub_disk_t disk,
|
||||||
|
|
||||||
p.start = p.offset + grub_le_to_cpu32 (e->start);
|
p.start = p.offset + grub_le_to_cpu32 (e->start);
|
||||||
p.len = grub_le_to_cpu32 (e->length);
|
p.len = grub_le_to_cpu32 (e->length);
|
||||||
pcdata.bsd_part = -1;
|
|
||||||
pcdata.dos_type = e->type;
|
|
||||||
pcdata.bsd_type = -1;
|
|
||||||
|
|
||||||
grub_dprintf ("partition",
|
grub_dprintf ("partition",
|
||||||
"partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n",
|
"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.start,
|
||||||
(unsigned long long) p.len);
|
(unsigned long long) p.len);
|
||||||
|
|
||||||
|
@ -168,59 +98,15 @@ pc_partition_map_iterate (grub_disk_t disk,
|
||||||
if (! grub_msdos_partition_is_empty (e->type)
|
if (! grub_msdos_partition_is_empty (e->type)
|
||||||
&& ! grub_msdos_partition_is_extended (e->type))
|
&& ! grub_msdos_partition_is_extended (e->type))
|
||||||
{
|
{
|
||||||
pcdata.dos_part++;
|
p.number++;
|
||||||
|
|
||||||
if (hook (disk, &p))
|
if (hook (disk, &p))
|
||||||
return 1;
|
return grub_errno;
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
/* 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
|
/* If this partition is a logical one, shouldn't increase the
|
||||||
partition number. */
|
partition number. */
|
||||||
pcdata.dos_part++;
|
p.number++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find an extended partition. */
|
/* Find an extended partition. */
|
||||||
|
@ -230,9 +116,9 @@ pc_partition_map_iterate (grub_disk_t disk,
|
||||||
|
|
||||||
if (grub_msdos_partition_is_extended (e->type))
|
if (grub_msdos_partition_is_extended (e->type))
|
||||||
{
|
{
|
||||||
p.offset = pcdata.ext_offset + grub_le_to_cpu32 (e->start);
|
p.offset = ext_offset + grub_le_to_cpu32 (e->start);
|
||||||
if (! pcdata.ext_offset)
|
if (! ext_offset)
|
||||||
pcdata.ext_offset = p.offset;
|
ext_offset = p.offset;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -247,78 +133,12 @@ pc_partition_map_iterate (grub_disk_t disk,
|
||||||
return grub_errno;
|
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. */
|
/* Partition map type. */
|
||||||
static struct grub_partition_map grub_msdos_partition_map =
|
static struct grub_partition_map grub_msdos_partition_map =
|
||||||
{
|
{
|
||||||
.name = "part_msdos",
|
.name = "msdos",
|
||||||
.iterate = pc_partition_map_iterate,
|
.iterate = pc_partition_map_iterate,
|
||||||
.probe = pc_partition_map_probe,
|
|
||||||
.get_name = pc_partition_map_get_name
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GRUB_MOD_INIT(part_msdos)
|
GRUB_MOD_INIT(part_msdos)
|
||||||
|
|
|
@ -88,20 +88,16 @@ sun_partition_map_iterate (grub_disk_t disk,
|
||||||
const grub_partition_t partition))
|
const grub_partition_t partition))
|
||||||
{
|
{
|
||||||
grub_partition_t p;
|
grub_partition_t p;
|
||||||
struct grub_disk raw;
|
|
||||||
struct grub_sun_block block;
|
struct grub_sun_block block;
|
||||||
int partnum;
|
int partnum;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
|
|
||||||
raw = *disk;
|
|
||||||
raw.partition = 0;
|
|
||||||
|
|
||||||
p = (grub_partition_t) grub_zalloc (sizeof (struct grub_partition));
|
p = (grub_partition_t) grub_zalloc (sizeof (struct grub_partition));
|
||||||
if (! p)
|
if (! p)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
p->partmap = &grub_sun_partition_map;
|
p->partmap = &grub_sun_partition_map;
|
||||||
err = grub_disk_read (&raw, 0, 0, sizeof (struct grub_sun_block),
|
err = grub_disk_read (disk, 0, 0, sizeof (struct grub_sun_block),
|
||||||
&block);
|
&block);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
|
@ -112,13 +108,12 @@ sun_partition_map_iterate (grub_disk_t disk,
|
||||||
if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic))
|
if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic))
|
||||||
{
|
{
|
||||||
grub_free (p);
|
grub_free (p);
|
||||||
return grub_error (GRUB_ERR_BAD_PART_TABLE,
|
return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a sun partition table");
|
||||||
"not a sun partition table");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! grub_sun_is_valid (&block))
|
if (! grub_sun_is_valid (&block))
|
||||||
{
|
{
|
||||||
grub_free (p);
|
grub_free (p);
|
||||||
return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
|
return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +122,7 @@ sun_partition_map_iterate (grub_disk_t disk,
|
||||||
for (partnum = 0; partnum < GRUB_PARTMAP_SUN_MAX_PARTS; partnum++)
|
for (partnum = 0; partnum < GRUB_PARTMAP_SUN_MAX_PARTS; partnum++)
|
||||||
{
|
{
|
||||||
struct grub_sun_partition_descriptor *desc;
|
struct grub_sun_partition_descriptor *desc;
|
||||||
|
|
||||||
if (block.infos[partnum].id == 0
|
if (block.infos[partnum].id == 0
|
||||||
|| block.infos[partnum].id == GRUB_PARTMAP_SUN_WHOLE_DISK_ID)
|
|| block.infos[partnum].id == GRUB_PARTMAP_SUN_WHOLE_DISK_ID)
|
||||||
continue;
|
continue;
|
||||||
|
@ -137,7 +132,7 @@ sun_partition_map_iterate (grub_disk_t disk,
|
||||||
* grub_be_to_cpu16 (block.ntrks)
|
* grub_be_to_cpu16 (block.ntrks)
|
||||||
* grub_be_to_cpu16 (block.nsect));
|
* grub_be_to_cpu16 (block.nsect));
|
||||||
p->len = grub_be_to_cpu32 (desc->num_sectors);
|
p->len = grub_be_to_cpu32 (desc->num_sectors);
|
||||||
p->index = partnum;
|
p->number = p->index = partnum;
|
||||||
if (p->len)
|
if (p->len)
|
||||||
{
|
{
|
||||||
if (hook (disk, p))
|
if (hook (disk, p))
|
||||||
|
@ -150,62 +145,11 @@ sun_partition_map_iterate (grub_disk_t disk,
|
||||||
return grub_errno;
|
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. */
|
/* Partition map type. */
|
||||||
static struct grub_partition_map grub_sun_partition_map =
|
static struct grub_partition_map grub_sun_partition_map =
|
||||||
{
|
{
|
||||||
.name = "part_sun",
|
.name = "sun",
|
||||||
.iterate = sun_partition_map_iterate,
|
.iterate = sun_partition_map_iterate,
|
||||||
.probe = sun_partition_map_probe,
|
|
||||||
.get_name = sun_partition_map_get_name
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GRUB_MOD_INIT(part_sun)
|
GRUB_MOD_INIT(part_sun)
|
||||||
|
|
|
@ -49,7 +49,7 @@ static grub_err_t grub_pcpart_boot (const grub_device_t dev,
|
||||||
|
|
||||||
index = dev->disk->partition->index;
|
index = dev->disk->partition->index;
|
||||||
part = dev->disk->partition;
|
part = dev->disk->partition;
|
||||||
dev->disk->partition = 0;
|
dev->disk->partition = part->parent;
|
||||||
|
|
||||||
/* Read the MBR. */
|
/* Read the MBR. */
|
||||||
if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), &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;
|
index = dev->disk->partition->index;
|
||||||
part = dev->disk->partition;
|
part = dev->disk->partition;
|
||||||
dev->disk->partition = 0;
|
dev->disk->partition = part->parent;
|
||||||
|
|
||||||
/* Read the parttable. */
|
/* Read the parttable. */
|
||||||
if (grub_disk_read (dev->disk, part->offset, 0,
|
if (grub_disk_read (dev->disk, part->offset, 0,
|
||||||
|
@ -140,10 +140,10 @@ static grub_err_t grub_pcpart_type (const grub_device_t dev,
|
||||||
|
|
||||||
GRUB_MOD_INIT (msdospart)
|
GRUB_MOD_INIT (msdospart)
|
||||||
{
|
{
|
||||||
activate_table_handle = grub_parttool_register ("part_msdos",
|
activate_table_handle = grub_parttool_register ("msdos",
|
||||||
grub_pcpart_boot,
|
grub_pcpart_boot,
|
||||||
grub_pcpart_bootargs);
|
grub_pcpart_bootargs);
|
||||||
type_table_handle = grub_parttool_register ("part_msdos",
|
type_table_handle = grub_parttool_register ("msdos",
|
||||||
grub_pcpart_type,
|
grub_pcpart_type,
|
||||||
grub_pcpart_typeargs);
|
grub_pcpart_typeargs);
|
||||||
|
|
||||||
|
|
|
@ -1,606 +0,0 @@
|
||||||
/*
|
|
||||||
* GRUB -- GRand Unified Bootloader
|
|
||||||
* Copyright (C) 2005,2007,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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TODO: Deprecated and broken. Scheduled for removal as there is VBE driver in Video subsystem.
|
|
||||||
|
|
||||||
#include <grub/machine/memory.h>
|
|
||||||
#include <grub/machine/vga.h>
|
|
||||||
#include <grub/machine/vbe.h>
|
|
||||||
#include <grub/machine/console.h>
|
|
||||||
#include <grub/term.h>
|
|
||||||
#include <grub/types.h>
|
|
||||||
#include <grub/dl.h>
|
|
||||||
#include <grub/misc.h>
|
|
||||||
#include <grub/normal.h>
|
|
||||||
#include <grub/font.h>
|
|
||||||
#include <grub/mm.h>
|
|
||||||
#include <grub/env.h>
|
|
||||||
|
|
||||||
#define DEFAULT_CHAR_WIDTH 8
|
|
||||||
#define DEFAULT_CHAR_HEIGHT 16
|
|
||||||
|
|
||||||
#define DEFAULT_FG_COLOR 0xa
|
|
||||||
#define DEFAULT_BG_COLOR 0x0
|
|
||||||
|
|
||||||
struct grub_colored_char
|
|
||||||
{
|
|
||||||
/* An Unicode codepoint. */
|
|
||||||
grub_uint32_t code;
|
|
||||||
|
|
||||||
/* Color indexes. */
|
|
||||||
unsigned char fg_color;
|
|
||||||
unsigned char bg_color;
|
|
||||||
|
|
||||||
/* The width of this character minus one. */
|
|
||||||
unsigned char width;
|
|
||||||
|
|
||||||
/* The column index of this character. */
|
|
||||||
unsigned char index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct grub_virtual_screen
|
|
||||||
{
|
|
||||||
/* Dimensions of the virtual screen. */
|
|
||||||
grub_uint32_t width;
|
|
||||||
grub_uint32_t height;
|
|
||||||
|
|
||||||
/* Offset in the display. */
|
|
||||||
grub_uint32_t offset_x;
|
|
||||||
grub_uint32_t offset_y;
|
|
||||||
|
|
||||||
/* TTY Character sizes. */
|
|
||||||
grub_uint32_t char_width;
|
|
||||||
grub_uint32_t char_height;
|
|
||||||
|
|
||||||
/* Virtual screen TTY size. */
|
|
||||||
grub_uint32_t columns;
|
|
||||||
grub_uint32_t rows;
|
|
||||||
|
|
||||||
/* Current cursor details. */
|
|
||||||
grub_uint32_t cursor_x;
|
|
||||||
grub_uint32_t cursor_y;
|
|
||||||
grub_uint8_t cursor_state;
|
|
||||||
grub_uint8_t fg_color;
|
|
||||||
grub_uint8_t bg_color;
|
|
||||||
|
|
||||||
/* Text buffer for virtual screen. Contains (columns * rows) number
|
|
||||||
of entries. */
|
|
||||||
struct grub_colored_char *text_buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Make sure text buffer is not marked as allocated. */
|
|
||||||
static struct grub_virtual_screen virtual_screen =
|
|
||||||
{
|
|
||||||
.text_buffer = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned char *vga_font = 0;
|
|
||||||
static grub_uint32_t old_mode = 0;
|
|
||||||
|
|
||||||
static struct grub_vbe_mode_info_block mode_info;
|
|
||||||
static grub_uint8_t *framebuffer = 0;
|
|
||||||
static grub_uint32_t bytes_per_scan_line = 0;
|
|
||||||
|
|
||||||
static void
|
|
||||||
grub_virtual_screen_free (void)
|
|
||||||
{
|
|
||||||
/* If virtual screen has been allocated, free it. */
|
|
||||||
if (virtual_screen.text_buffer != 0)
|
|
||||||
grub_free (virtual_screen.text_buffer);
|
|
||||||
|
|
||||||
/* Reset virtual screen data. */
|
|
||||||
grub_memset (&virtual_screen, 0, sizeof (virtual_screen));
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_virtual_screen_setup (grub_uint32_t width,
|
|
||||||
grub_uint32_t height)
|
|
||||||
{
|
|
||||||
/* Free old virtual screen. */
|
|
||||||
grub_virtual_screen_free ();
|
|
||||||
|
|
||||||
/* Initialize with default data. */
|
|
||||||
virtual_screen.width = width;
|
|
||||||
virtual_screen.height = height;
|
|
||||||
virtual_screen.offset_x = 0;
|
|
||||||
virtual_screen.offset_y = 0;
|
|
||||||
virtual_screen.char_width = DEFAULT_CHAR_WIDTH;
|
|
||||||
virtual_screen.char_height = DEFAULT_CHAR_HEIGHT;
|
|
||||||
virtual_screen.cursor_x = 0;
|
|
||||||
virtual_screen.cursor_y = 0;
|
|
||||||
virtual_screen.cursor_state = 1;
|
|
||||||
virtual_screen.fg_color = DEFAULT_FG_COLOR;
|
|
||||||
virtual_screen.bg_color = DEFAULT_BG_COLOR;
|
|
||||||
|
|
||||||
/* Calculate size of text buffer. */
|
|
||||||
virtual_screen.columns = virtual_screen.width / virtual_screen.char_width;
|
|
||||||
virtual_screen.rows = virtual_screen.height / virtual_screen.char_height;
|
|
||||||
|
|
||||||
/* Allocate memory for text buffer. */
|
|
||||||
virtual_screen.text_buffer =
|
|
||||||
(struct grub_colored_char *) grub_malloc (virtual_screen.columns
|
|
||||||
* virtual_screen.rows
|
|
||||||
* sizeof (*virtual_screen.text_buffer));
|
|
||||||
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_vesafb_mod_init (void)
|
|
||||||
{
|
|
||||||
grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE;
|
|
||||||
struct grub_vbe_info_block controller_info;
|
|
||||||
char *modevar;
|
|
||||||
|
|
||||||
/* Use fonts from VGA bios. */
|
|
||||||
vga_font = grub_vga_get_font ();
|
|
||||||
|
|
||||||
/* Check if we have VESA BIOS installed. */
|
|
||||||
if (grub_vbe_probe (&controller_info) != GRUB_ERR_NONE)
|
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
/* Check existence of vbe_mode environment variable. */
|
|
||||||
modevar = grub_env_get ("vbe_mode");
|
|
||||||
|
|
||||||
if (modevar != 0)
|
|
||||||
{
|
|
||||||
unsigned long value;
|
|
||||||
|
|
||||||
value = grub_strtoul (modevar, 0, 0);
|
|
||||||
if (grub_errno == GRUB_ERR_NONE)
|
|
||||||
use_mode = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Store initial video mode. */
|
|
||||||
if (grub_vbe_get_video_mode (&old_mode) != GRUB_ERR_NONE)
|
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
/* Setup desired graphics mode. */
|
|
||||||
if (grub_vbe_set_video_mode (use_mode, &mode_info) != GRUB_ERR_NONE)
|
|
||||||
return grub_errno;
|
|
||||||
|
|
||||||
/* Determine framebuffer and bytes per scan line. */
|
|
||||||
framebuffer = (grub_uint8_t *) mode_info.phys_base_addr;
|
|
||||||
|
|
||||||
if (controller_info.version >= 0x300)
|
|
||||||
bytes_per_scan_line = mode_info.lin_bytes_per_scan_line;
|
|
||||||
else
|
|
||||||
bytes_per_scan_line = mode_info.bytes_per_scan_line;
|
|
||||||
|
|
||||||
/* Create virtual screen. */
|
|
||||||
if (grub_virtual_screen_setup (mode_info.x_resolution,
|
|
||||||
mode_info.y_resolution) != GRUB_ERR_NONE)
|
|
||||||
{
|
|
||||||
grub_vbe_set_video_mode (old_mode, 0);
|
|
||||||
return grub_errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure frame buffer is black. */
|
|
||||||
grub_memset (framebuffer,
|
|
||||||
0,
|
|
||||||
bytes_per_scan_line * mode_info.y_resolution);
|
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_err_t
|
|
||||||
grub_vesafb_mod_fini (void)
|
|
||||||
{
|
|
||||||
grub_virtual_screen_free ();
|
|
||||||
|
|
||||||
grub_vbe_set_video_mode (old_mode, 0);
|
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
grub_virtual_screen_get_glyph (grub_uint32_t code,
|
|
||||||
unsigned char bitmap[32],
|
|
||||||
unsigned *width)
|
|
||||||
{
|
|
||||||
if (code > 0x7f)
|
|
||||||
{
|
|
||||||
/* Map some unicode characters to the VGA font, if possible. */
|
|
||||||
switch (code)
|
|
||||||
{
|
|
||||||
case 0x2190: /* left arrow */
|
|
||||||
code = 0x1b;
|
|
||||||
break;
|
|
||||||
case 0x2191: /* up arrow */
|
|
||||||
code = 0x18;
|
|
||||||
break;
|
|
||||||
case 0x2192: /* right arrow */
|
|
||||||
code = 0x1a;
|
|
||||||
break;
|
|
||||||
case 0x2193: /* down arrow */
|
|
||||||
code = 0x19;
|
|
||||||
break;
|
|
||||||
case 0x2501: /* horizontal line */
|
|
||||||
code = 0xc4;
|
|
||||||
break;
|
|
||||||
case 0x2503: /* vertical line */
|
|
||||||
code = 0xb3;
|
|
||||||
break;
|
|
||||||
case 0x250F: /* upper-left corner */
|
|
||||||
code = 0xda;
|
|
||||||
break;
|
|
||||||
case 0x2513: /* upper-right corner */
|
|
||||||
code = 0xbf;
|
|
||||||
break;
|
|
||||||
case 0x2517: /* lower-left corner */
|
|
||||||
code = 0xc0;
|
|
||||||
break;
|
|
||||||
case 0x251B: /* lower-right corner */
|
|
||||||
code = 0xd9;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return grub_font_get_glyph_any (code, bitmap, width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO This is wrong for the new font module. Should it be fixed? */
|
|
||||||
if (bitmap)
|
|
||||||
grub_memcpy (bitmap,
|
|
||||||
vga_font + code * virtual_screen.char_height,
|
|
||||||
virtual_screen.char_height);
|
|
||||||
*width = 1;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
grub_virtual_screen_invalidate_char (struct grub_colored_char *p)
|
|
||||||
{
|
|
||||||
p->code = 0xFFFF;
|
|
||||||
|
|
||||||
if (p->width)
|
|
||||||
{
|
|
||||||
struct grub_colored_char *q;
|
|
||||||
|
|
||||||
for (q = p + 1; q <= p + p->width; q++)
|
|
||||||
{
|
|
||||||
q->code = 0xFFFF;
|
|
||||||
q->width = 0;
|
|
||||||
q->index = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p->width = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
write_char (void)
|
|
||||||
{
|
|
||||||
struct grub_colored_char *p;
|
|
||||||
unsigned char bitmap[32];
|
|
||||||
unsigned width;
|
|
||||||
unsigned y;
|
|
||||||
unsigned offset;
|
|
||||||
|
|
||||||
p = (virtual_screen.text_buffer
|
|
||||||
+ virtual_screen.cursor_x
|
|
||||||
+ (virtual_screen.cursor_y * virtual_screen.columns));
|
|
||||||
|
|
||||||
p -= p->index;
|
|
||||||
|
|
||||||
if (! grub_virtual_screen_get_glyph (p->code, bitmap, &width))
|
|
||||||
{
|
|
||||||
grub_virtual_screen_invalidate_char (p);
|
|
||||||
width = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (y = 0, offset = 0;
|
|
||||||
y < virtual_screen.char_height;
|
|
||||||
y++, offset++)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0;
|
|
||||||
(i < width * virtual_screen.char_width) && (offset < 32);
|
|
||||||
i++)
|
|
||||||
{
|
|
||||||
unsigned char color;
|
|
||||||
|
|
||||||
if (bitmap[offset] & (1 << (8-i)))
|
|
||||||
{
|
|
||||||
color = p->fg_color;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
color = p->bg_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_vbe_set_pixel_index(i + (virtual_screen.cursor_x
|
|
||||||
* virtual_screen.char_width),
|
|
||||||
y + (virtual_screen.cursor_y
|
|
||||||
* virtual_screen.char_height),
|
|
||||||
color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
write_cursor (void)
|
|
||||||
{
|
|
||||||
grub_uint32_t x;
|
|
||||||
grub_uint32_t y;
|
|
||||||
|
|
||||||
for (y = ((virtual_screen.cursor_y + 1) * virtual_screen.char_height) - 3;
|
|
||||||
y < ((virtual_screen.cursor_y + 1) * virtual_screen.char_height) - 1;
|
|
||||||
y++)
|
|
||||||
{
|
|
||||||
for (x = virtual_screen.cursor_x * virtual_screen.char_width;
|
|
||||||
x < (virtual_screen.cursor_x + 1) * virtual_screen.char_width;
|
|
||||||
x++)
|
|
||||||
{
|
|
||||||
grub_vbe_set_pixel_index(x, y, 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
scroll_up (void)
|
|
||||||
{
|
|
||||||
grub_uint32_t i;
|
|
||||||
|
|
||||||
/* Scroll text buffer with one line to up. */
|
|
||||||
grub_memmove (virtual_screen.text_buffer,
|
|
||||||
virtual_screen.text_buffer + virtual_screen.columns,
|
|
||||||
sizeof (*virtual_screen.text_buffer)
|
|
||||||
* virtual_screen.columns
|
|
||||||
* (virtual_screen.rows - 1));
|
|
||||||
|
|
||||||
/* Clear last line in text buffer. */
|
|
||||||
for (i = virtual_screen.columns * (virtual_screen.rows - 1);
|
|
||||||
i < virtual_screen.columns * virtual_screen.rows;
|
|
||||||
i++)
|
|
||||||
{
|
|
||||||
virtual_screen.text_buffer[i].code = ' ';
|
|
||||||
virtual_screen.text_buffer[i].fg_color = 0;
|
|
||||||
virtual_screen.text_buffer[i].bg_color = 0;
|
|
||||||
virtual_screen.text_buffer[i].width = 0;
|
|
||||||
virtual_screen.text_buffer[i].index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Scroll framebuffer with one line to up. */
|
|
||||||
grub_memmove (framebuffer,
|
|
||||||
framebuffer
|
|
||||||
+ bytes_per_scan_line * virtual_screen.char_height,
|
|
||||||
bytes_per_scan_line
|
|
||||||
* (mode_info.y_resolution - virtual_screen.char_height));
|
|
||||||
|
|
||||||
/* Clear last line in framebuffer. */
|
|
||||||
grub_memset (framebuffer
|
|
||||||
+ (bytes_per_scan_line
|
|
||||||
* (mode_info.y_resolution - virtual_screen.char_height)),
|
|
||||||
0,
|
|
||||||
bytes_per_scan_line * virtual_screen.char_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
grub_vesafb_putchar (grub_uint32_t c)
|
|
||||||
{
|
|
||||||
if (c == '\a')
|
|
||||||
/* FIXME */
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (c == '\b' || c == '\n' || c == '\r')
|
|
||||||
{
|
|
||||||
/* Erase current cursor, if any. */
|
|
||||||
if (virtual_screen.cursor_state)
|
|
||||||
write_char ();
|
|
||||||
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '\b':
|
|
||||||
if (virtual_screen.cursor_x > 0)
|
|
||||||
virtual_screen.cursor_x--;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\n':
|
|
||||||
if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
|
|
||||||
scroll_up ();
|
|
||||||
else
|
|
||||||
virtual_screen.cursor_y++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\r':
|
|
||||||
virtual_screen.cursor_x = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virtual_screen.cursor_state)
|
|
||||||
write_cursor ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned width;
|
|
||||||
struct grub_colored_char *p;
|
|
||||||
|
|
||||||
grub_virtual_screen_get_glyph (c, 0, &width);
|
|
||||||
|
|
||||||
if (virtual_screen.cursor_x + width > virtual_screen.columns)
|
|
||||||
grub_putchar ('\n');
|
|
||||||
|
|
||||||
p = (virtual_screen.text_buffer +
|
|
||||||
virtual_screen.cursor_x +
|
|
||||||
virtual_screen.cursor_y * virtual_screen.columns);
|
|
||||||
p->code = c;
|
|
||||||
p->fg_color = virtual_screen.fg_color;
|
|
||||||
p->bg_color = virtual_screen.bg_color;
|
|
||||||
p->width = width - 1;
|
|
||||||
p->index = 0;
|
|
||||||
|
|
||||||
if (width > 1)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 1; i < width; i++)
|
|
||||||
{
|
|
||||||
p[i].code = ' ';
|
|
||||||
p[i].width = width - 1;
|
|
||||||
p[i].index = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
write_char ();
|
|
||||||
|
|
||||||
virtual_screen.cursor_x += width;
|
|
||||||
if (virtual_screen.cursor_x >= virtual_screen.columns)
|
|
||||||
{
|
|
||||||
virtual_screen.cursor_x = 0;
|
|
||||||
|
|
||||||
if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
|
|
||||||
scroll_up ();
|
|
||||||
else
|
|
||||||
virtual_screen.cursor_y++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virtual_screen.cursor_state)
|
|
||||||
write_cursor ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_ssize_t
|
|
||||||
grub_vesafb_getcharwidth (grub_uint32_t c)
|
|
||||||
{
|
|
||||||
unsigned width;
|
|
||||||
|
|
||||||
if (! grub_virtual_screen_get_glyph (c, 0, &width))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_uint16_t
|
|
||||||
grub_virtual_screen_getwh (void)
|
|
||||||
{
|
|
||||||
return (virtual_screen.columns << 8) | virtual_screen.rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_uint16_t
|
|
||||||
grub_virtual_screen_getxy (void)
|
|
||||||
{
|
|
||||||
return ((virtual_screen.cursor_x << 8) | virtual_screen.cursor_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
grub_vesafb_gotoxy (grub_uint8_t x, grub_uint8_t y)
|
|
||||||
{
|
|
||||||
if (x >= virtual_screen.columns || y >= virtual_screen.rows)
|
|
||||||
{
|
|
||||||
grub_error (GRUB_ERR_OUT_OF_RANGE, "invalid point (%u,%u)",
|
|
||||||
(unsigned) x, (unsigned) y);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virtual_screen.cursor_state)
|
|
||||||
write_char ();
|
|
||||||
|
|
||||||
virtual_screen.cursor_x = x;
|
|
||||||
virtual_screen.cursor_y = y;
|
|
||||||
|
|
||||||
if (virtual_screen.cursor_state)
|
|
||||||
write_cursor ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
grub_virtual_screen_cls (void)
|
|
||||||
{
|
|
||||||
grub_uint32_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
|
|
||||||
{
|
|
||||||
virtual_screen.text_buffer[i].code = ' ';
|
|
||||||
virtual_screen.text_buffer[i].fg_color = 0;
|
|
||||||
virtual_screen.text_buffer[i].bg_color = 0;
|
|
||||||
virtual_screen.text_buffer[i].width = 0;
|
|
||||||
virtual_screen.text_buffer[i].index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual_screen.cursor_x = virtual_screen.cursor_y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
grub_vesafb_cls (void)
|
|
||||||
{
|
|
||||||
grub_virtual_screen_cls ();
|
|
||||||
|
|
||||||
grub_memset (framebuffer,
|
|
||||||
0,
|
|
||||||
mode_info.y_resolution * bytes_per_scan_line);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
grub_virtual_screen_setcolorstate (grub_term_color_state state)
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case GRUB_TERM_COLOR_STANDARD:
|
|
||||||
case GRUB_TERM_COLOR_NORMAL:
|
|
||||||
virtual_screen.fg_color = DEFAULT_FG_COLOR;
|
|
||||||
virtual_screen.bg_color = DEFAULT_BG_COLOR;
|
|
||||||
break;
|
|
||||||
case GRUB_TERM_COLOR_HIGHLIGHT:
|
|
||||||
virtual_screen.fg_color = DEFAULT_BG_COLOR;
|
|
||||||
virtual_screen.bg_color = DEFAULT_FG_COLOR;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
grub_vesafb_setcursor (int on)
|
|
||||||
{
|
|
||||||
if (virtual_screen.cursor_state != on)
|
|
||||||
{
|
|
||||||
if (virtual_screen.cursor_state)
|
|
||||||
write_char ();
|
|
||||||
else
|
|
||||||
write_cursor ();
|
|
||||||
|
|
||||||
virtual_screen.cursor_state = on;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct grub_term_output grub_vesafb_term =
|
|
||||||
{
|
|
||||||
.name = "vesafb",
|
|
||||||
.init = grub_vesafb_mod_init,
|
|
||||||
.fini = grub_vesafb_mod_fini,
|
|
||||||
.putchar = grub_vesafb_putchar,
|
|
||||||
.getcharwidth = grub_vesafb_getcharwidth,
|
|
||||||
.getwh = grub_virtual_screen_getwh,
|
|
||||||
.getxy = grub_virtual_screen_getxy,
|
|
||||||
.gotoxy = grub_vesafb_gotoxy,
|
|
||||||
.cls = grub_vesafb_cls,
|
|
||||||
.setcolorstate = grub_virtual_screen_setcolorstate,
|
|
||||||
.setcursor = grub_vesafb_setcursor,
|
|
||||||
.flags = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(vesafb)
|
|
||||||
{
|
|
||||||
grub_term_register_output ("vesafb", &grub_vesafb_term);
|
|
||||||
}
|
|
||||||
|
|
||||||
GRUB_MOD_FINI(vesafb)
|
|
||||||
{
|
|
||||||
grub_term_unregister_output (&grub_vesafb_term);
|
|
||||||
}
|
|
|
@ -32,6 +32,7 @@ platform=@platform@
|
||||||
host_os=@host_os@
|
host_os=@host_os@
|
||||||
font=@datadir@/@PACKAGE_TARNAME@/ascii.pf2
|
font=@datadir@/@PACKAGE_TARNAME@/ascii.pf2
|
||||||
pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
|
pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
|
||||||
|
localedir=@datadir@/locale
|
||||||
|
|
||||||
grub_setup=${sbindir}/`echo grub-setup | sed ${transform}`
|
grub_setup=${sbindir}/`echo grub-setup | sed ${transform}`
|
||||||
if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] || [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then
|
if [ "${target_cpu}-${platform}" = "i386-pc" ] || [ "${target_cpu}-${platform}" = "sparc64-ieee1275" ] || [ "${target_cpu}-${platform}" = "mips-yeeloong" ] ; then
|
||||||
|
@ -263,9 +264,9 @@ fi
|
||||||
|
|
||||||
# Copy gettext files
|
# Copy gettext files
|
||||||
mkdir -p ${grubdir}/locale/
|
mkdir -p ${grubdir}/locale/
|
||||||
for file in ${grubdir}/locale/*.mo ${pkglibdir}/locale/*.mo; do
|
for dir in ${localedir}/*; do
|
||||||
if test -f "$file"; then
|
if test -f "$dir/LC_MESSAGES/grub.mo"; then
|
||||||
cp -f "$file" ${grubdir}/locale/
|
cp -f "$dir/LC_MESSAGES/grub.mo" "${grubdir}/locale/${dir##*/}.mo"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@ -287,7 +288,10 @@ fi
|
||||||
# Then the partition map module. In order to support partition-less media,
|
# Then the partition map module. In order to support partition-less media,
|
||||||
# this command is allowed to fail (--target=fs already grants us that the
|
# this command is allowed to fail (--target=fs already grants us that the
|
||||||
# filesystem will be accessible).
|
# filesystem will be accessible).
|
||||||
partmap_module=`$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`
|
partmap_module=
|
||||||
|
for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do
|
||||||
|
partmap_module="$partmap_module part_$x";
|
||||||
|
done
|
||||||
|
|
||||||
# Device abstraction module, if any (lvm, raid).
|
# Device abstraction module, if any (lvm, raid).
|
||||||
devabstraction_module=`$grub_probe --target=abstraction --device ${grub_device}`
|
devabstraction_module=`$grub_probe --target=abstraction --device ${grub_device}`
|
||||||
|
|
|
@ -82,13 +82,16 @@ grub_refresh (void)
|
||||||
static void
|
static void
|
||||||
probe_partmap (grub_disk_t disk)
|
probe_partmap (grub_disk_t disk)
|
||||||
{
|
{
|
||||||
|
grub_partition_t part;
|
||||||
|
|
||||||
if (disk->partition == NULL)
|
if (disk->partition == NULL)
|
||||||
{
|
{
|
||||||
grub_util_info ("no partition map found for %s", disk->name);
|
grub_util_info ("no partition map found for %s", disk->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("%s\n", disk->partition->partmap->name);
|
for (part = disk->partition; part; part = part->parent)
|
||||||
|
printf ("%s\n", part->partmap->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -379,11 +379,14 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags)
|
||||||
{
|
{
|
||||||
int is_partition = 0;
|
int is_partition = 0;
|
||||||
char dev[PATH_MAX];
|
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);
|
strcpy (dev, map[disk->id].device);
|
||||||
if (disk->partition && sector >= disk->partition->start
|
if (disk->partition && sector >= part_start
|
||||||
&& strncmp (map[disk->id].device, "/dev/", 5) == 0)
|
&& 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);
|
||||||
|
|
||||||
if (data->dev && strcmp (data->dev, dev) == 0 &&
|
if (data->dev && strcmp (data->dev, dev) == 0 &&
|
||||||
data->access_mode == (flags & O_ACCMODE))
|
data->access_mode == (flags & O_ACCMODE))
|
||||||
|
@ -416,7 +419,7 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_partition)
|
if (is_partition)
|
||||||
sector -= disk->partition->start;
|
sector -= part_start;
|
||||||
}
|
}
|
||||||
#else /* ! __linux__ */
|
#else /* ! __linux__ */
|
||||||
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
|
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||||
|
@ -1077,39 +1080,25 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
|
||||||
int find_partition (grub_disk_t dsk __attribute__ ((unused)),
|
int find_partition (grub_disk_t dsk __attribute__ ((unused)),
|
||||||
const grub_partition_t partition)
|
const grub_partition_t partition)
|
||||||
{
|
{
|
||||||
struct grub_msdos_partition *pcdata = NULL;
|
grub_disk_addr_t part_start = 0;
|
||||||
|
grub_util_info ("Partition %d starts from %lu",
|
||||||
|
partition->number, partition->start);
|
||||||
|
|
||||||
if (strcmp (partition->partmap->name, "part_msdos") == 0)
|
part_start = grub_partition_get_start (partition);
|
||||||
pcdata = partition->data;
|
|
||||||
|
|
||||||
if (pcdata)
|
if (hdg.start == part_start)
|
||||||
{
|
{
|
||||||
if (pcdata->bsd_part < 0)
|
if (partition->parent)
|
||||||
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_util_info ("Partition %d starts from %lu",
|
|
||||||
partition->index, partition->start);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hdg.start == partition->start)
|
|
||||||
{
|
|
||||||
if (pcdata)
|
|
||||||
{
|
{
|
||||||
dos_part = pcdata->dos_part;
|
dos_part = partition->parent->number;
|
||||||
bsd_part = pcdata->bsd_part;
|
bsd_part = partition->number;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dos_part = partition->index;
|
dos_part = partition->number;
|
||||||
bsd_part = -1;
|
bsd_part = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ target_cpu=@target_cpu@
|
||||||
platform=@platform@
|
platform=@platform@
|
||||||
host_os=@host_os@
|
host_os=@host_os@
|
||||||
pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
|
pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
|
||||||
|
localedir=@datadir@/locale
|
||||||
|
|
||||||
grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
|
grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
|
||||||
grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
|
grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
|
||||||
|
@ -182,9 +183,9 @@ done
|
||||||
|
|
||||||
# Copy gettext files
|
# Copy gettext files
|
||||||
mkdir -p ${grubdir}/locale/
|
mkdir -p ${grubdir}/locale/
|
||||||
for file in ${grubdir}/locale/*.mo ${pkglibdir}/locale/*.mo; do
|
for dir in ${localedir}/*; do
|
||||||
if test -f "$file"; then
|
if test -f "$dir/LC_MESSAGES/grub.mo"; then
|
||||||
cp -f "$file" ${grubdir}/locale/
|
cp -f "$dir/LC_MESSAGES/grub.mo" "${grubdir}/locale/${dir##*/}.mo"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@ -202,7 +203,10 @@ fi
|
||||||
# Then the partition map module. In order to support partition-less media,
|
# Then the partition map module. In order to support partition-less media,
|
||||||
# this command is allowed to fail (--target=fs already grants us that the
|
# this command is allowed to fail (--target=fs already grants us that the
|
||||||
# filesystem will be accessible).
|
# filesystem will be accessible).
|
||||||
partmap_module=`$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null`
|
partmap_module=
|
||||||
|
for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do
|
||||||
|
partmap_module="$partmap_module part_$x";
|
||||||
|
done
|
||||||
|
|
||||||
# Device abstraction module, if any (lvm, raid).
|
# Device abstraction module, if any (lvm, raid).
|
||||||
devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}`
|
devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}`
|
||||||
|
|
|
@ -116,15 +116,10 @@ setup (const char *dir,
|
||||||
int NESTED_FUNC_ATTR find_usable_region_msdos (grub_disk_t disk __attribute__ ((unused)),
|
int NESTED_FUNC_ATTR find_usable_region_msdos (grub_disk_t disk __attribute__ ((unused)),
|
||||||
const grub_partition_t p)
|
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. */
|
/* There's always an embed region, and it starts right after the MBR. */
|
||||||
embed_region.start = 1;
|
embed_region.start = 1;
|
||||||
|
|
||||||
/* For its end offset, include as many dummy partitions as we can. */
|
if (embed_region.end > p->start)
|
||||||
if (! grub_msdos_partition_is_empty (pcdata->dos_type)
|
|
||||||
&& ! grub_msdos_partition_is_bsd (pcdata->dos_type)
|
|
||||||
&& embed_region.end > p->start)
|
|
||||||
embed_region.end = p->start;
|
embed_region.end = p->start;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -135,17 +130,21 @@ setup (const char *dir,
|
||||||
int NESTED_FUNC_ATTR find_usable_region_gpt (grub_disk_t disk __attribute__ ((unused)),
|
int NESTED_FUNC_ATTR find_usable_region_gpt (grub_disk_t disk __attribute__ ((unused)),
|
||||||
const grub_partition_t p)
|
const grub_partition_t p)
|
||||||
{
|
{
|
||||||
struct grub_gpt_partentry *gptdata = p->data;
|
struct grub_gpt_partentry gptdata;
|
||||||
|
|
||||||
|
disk->partition = p->parent;
|
||||||
|
if (grub_disk_read (disk, p->offset, p->index,
|
||||||
|
sizeof (gptdata), &gptdata))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* If there's an embed region, it is in a dedicated partition. */
|
/* If there's an embed region, it is in a dedicated partition. */
|
||||||
if (! memcmp (&gptdata->type, &grub_gpt_partition_type_bios_boot, 16))
|
if (! memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16))
|
||||||
{
|
{
|
||||||
embed_region.start = p->start;
|
embed_region.start = p->start;
|
||||||
embed_region.end = p->start + p->len;
|
embed_region.end = p->start + p->len;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,22 +288,19 @@ setup (const char *dir,
|
||||||
/* Embed information about the installed location. */
|
/* Embed information about the installed location. */
|
||||||
if (root_dev->disk->partition)
|
if (root_dev->disk->partition)
|
||||||
{
|
{
|
||||||
if (strcmp (root_dev->disk->partition->partmap->name,
|
if (root_dev->disk->partition->parent)
|
||||||
"part_msdos") == 0)
|
{
|
||||||
{
|
if (root_dev->disk->partition->parent->parent)
|
||||||
struct grub_msdos_partition *pcdata =
|
grub_util_error ("Installing on doubly nested partitions is "
|
||||||
root_dev->disk->partition->data;
|
"not supported");
|
||||||
dos_part = pcdata->dos_part;
|
dos_part = root_dev->disk->partition->parent->number;
|
||||||
bsd_part = pcdata->bsd_part;
|
bsd_part = root_dev->disk->partition->number;
|
||||||
}
|
}
|
||||||
else if (strcmp (root_dev->disk->partition->partmap->name,
|
|
||||||
"part_gpt") == 0)
|
|
||||||
{
|
|
||||||
dos_part = root_dev->disk->partition->index;
|
|
||||||
bsd_part = -1;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
grub_util_error (_("no DOS-style partitions found"));
|
{
|
||||||
|
dos_part = root_dev->disk->partition->number;
|
||||||
|
bsd_part = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dos_part = bsd_part = -1;
|
dos_part = bsd_part = -1;
|
||||||
|
@ -337,6 +333,8 @@ setup (const char *dir,
|
||||||
int NESTED_FUNC_ATTR identify_partmap (grub_disk_t disk __attribute__ ((unused)),
|
int NESTED_FUNC_ATTR identify_partmap (grub_disk_t disk __attribute__ ((unused)),
|
||||||
const grub_partition_t p)
|
const grub_partition_t p)
|
||||||
{
|
{
|
||||||
|
if (p->parent)
|
||||||
|
return 0;
|
||||||
dest_partmap = p->partmap->name;
|
dest_partmap = p->partmap->name;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -349,16 +347,16 @@ setup (const char *dir,
|
||||||
goto unable_to_embed;
|
goto unable_to_embed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp (dest_partmap, "part_msdos") == 0)
|
if (strcmp (dest_partmap, "msdos") == 0)
|
||||||
grub_partition_iterate (dest_dev->disk, find_usable_region_msdos);
|
grub_partition_iterate (dest_dev->disk, find_usable_region_msdos);
|
||||||
else if (strcmp (dest_partmap, "part_gpt") == 0)
|
else if (strcmp (dest_partmap, "gpt") == 0)
|
||||||
grub_partition_iterate (dest_dev->disk, find_usable_region_gpt);
|
grub_partition_iterate (dest_dev->disk, find_usable_region_gpt);
|
||||||
else
|
else
|
||||||
grub_util_error (_("No DOS-style partitions found"));
|
grub_util_error (_("No DOS-style partitions found"));
|
||||||
|
|
||||||
if (embed_region.end == embed_region.start)
|
if (embed_region.end == embed_region.start)
|
||||||
{
|
{
|
||||||
if (! strcmp (dest_partmap, "part_msdos"))
|
if (! strcmp (dest_partmap, "msdos"))
|
||||||
grub_util_warn (_("This msdos-style partition label has no post-MBR gap; embedding won't be possible!"));
|
grub_util_warn (_("This msdos-style partition label has no post-MBR gap; embedding won't be possible!"));
|
||||||
else
|
else
|
||||||
grub_util_warn (_("This GPT partition label has no BIOS Boot Partition; embedding won't be possible!"));
|
grub_util_warn (_("This GPT partition label has no BIOS Boot Partition; embedding won't be possible!"));
|
||||||
|
|
|
@ -179,7 +179,10 @@ fi
|
||||||
# Then the partition map module. In order to support partition-less media,
|
# Then the partition map module. In order to support partition-less media,
|
||||||
# this command is allowed to fail (--target=fs already grants us that the
|
# this command is allowed to fail (--target=fs already grants us that the
|
||||||
# filesystem will be accessible).
|
# filesystem will be accessible).
|
||||||
partmap_module=`$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null`
|
partmap_module=
|
||||||
|
for x in `$grub_probe --target=partmap --device ${grub_device} 2> /dev/null`; do
|
||||||
|
partmap_module="$partmap_module part_$x";
|
||||||
|
done
|
||||||
|
|
||||||
# Device abstraction module, if any (lvm, raid).
|
# Device abstraction module, if any (lvm, raid).
|
||||||
devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}`
|
devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}`
|
||||||
|
|
|
@ -1170,10 +1170,15 @@ grub_video_fbblit_blend_XXXA8888_1bit (struct grub_video_fbblit_info *dst,
|
||||||
grub_uint8_t a;
|
grub_uint8_t a;
|
||||||
|
|
||||||
if (*srcptr & srcmask)
|
if (*srcptr & srcmask)
|
||||||
color = fgcolor;
|
{
|
||||||
|
color = fgcolor;
|
||||||
|
a = src->mode_info->fg_alpha;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
color = bgcolor;
|
{
|
||||||
a = (color >> 24) & 0xff;
|
color = bgcolor;
|
||||||
|
a = src->mode_info->bg_alpha;
|
||||||
|
}
|
||||||
|
|
||||||
if (a == 255)
|
if (a == 255)
|
||||||
*(grub_uint32_t *) dstptr = color;
|
*(grub_uint32_t *) dstptr = color;
|
||||||
|
|
Loading…
Reference in a new issue