Merge mainline into net
This commit is contained in:
commit
760a7e5aed
521 changed files with 54590 additions and 8041 deletions
43
.bzrignore
43
.bzrignore
|
@ -4,6 +4,8 @@
|
|||
30_os-prober
|
||||
40_custom
|
||||
41_custom
|
||||
*.1
|
||||
*.8
|
||||
aclocal.m4
|
||||
ascii.bitmaps
|
||||
ascii.h
|
||||
|
@ -13,13 +15,12 @@ build_env.mk
|
|||
config.cache
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config-util.h
|
||||
config-util.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
conf/*.mk
|
||||
*.d
|
||||
DISTLIST
|
||||
docs/*.info
|
||||
docs/stamp-vti
|
||||
|
@ -39,7 +40,9 @@ grub-fstest
|
|||
grub_fstest_init.c
|
||||
grub_fstest_init.h
|
||||
grub-install
|
||||
grub-kbdcomp
|
||||
grub-macho2img
|
||||
grub-menulst2cfg
|
||||
grub-mk*
|
||||
grub-pbkdf2
|
||||
grub-pe2elf
|
||||
|
@ -58,23 +61,30 @@ grub-set-default
|
|||
grub-setup
|
||||
grub_setup_init.c
|
||||
grub_setup_init.h
|
||||
grub-shell
|
||||
grub-shell-tester
|
||||
*.img
|
||||
*.image
|
||||
include/grub/cpu
|
||||
include/grub/machine
|
||||
install-sh
|
||||
lib/libgcrypt-grub
|
||||
libgrub_a_init.c
|
||||
*.lst
|
||||
*.marker
|
||||
Makefile
|
||||
*.mod
|
||||
mod-*.c
|
||||
missing
|
||||
*.pf2
|
||||
*.pp
|
||||
po/*.mo
|
||||
po/grub.pot
|
||||
stamp-h
|
||||
stamp-h1
|
||||
stamp-h.in
|
||||
symlist.c
|
||||
symlist.h
|
||||
trigtables.c
|
||||
update-grub_lib
|
||||
unidata.c
|
||||
|
@ -89,9 +99,36 @@ depcomp
|
|||
mdate-sh
|
||||
texinfo.tex
|
||||
grub-core/lib/libgcrypt-grub
|
||||
**/.deps
|
||||
**/.deps-util
|
||||
**/.deps-core
|
||||
**/.dirstamp
|
||||
Makefile.util.am
|
||||
grub-core/Makefile.core.am
|
||||
grub-core/Makefile.gcry.am
|
||||
grub-core/Makefile.gcry.def
|
||||
grub-core/genmod.sh
|
||||
grub-core/gensyminfo.sh
|
||||
grub-core/*.module
|
||||
grub-core/*.pp
|
||||
util/bash-completion.d/grub
|
||||
grub-core/gnulib/alloca.h
|
||||
grub-core/gnulib/arg-nonnull.h
|
||||
grub-core/gnulib/c++defs.h
|
||||
grub-core/gnulib/charset.alias
|
||||
grub-core/gnulib/configmake.h
|
||||
grub-core/gnulib/getopt.h
|
||||
grub-core/gnulib/langinfo.h
|
||||
grub-core/gnulib/ref-add.sed
|
||||
grub-core/gnulib/ref-del.sed
|
||||
grub-core/gnulib/stdio.h
|
||||
grub-core/gnulib/stdlib.h
|
||||
grub-core/gnulib/string.h
|
||||
grub-core/gnulib/strings.h
|
||||
grub-core/gnulib/sys
|
||||
grub-core/gnulib/unistd.h
|
||||
grub-core/gnulib/warn-on-use.h
|
||||
grub-core/gnulib/wchar.h
|
||||
grub-core/gnulib/wctype.h
|
||||
widthspec.bin
|
||||
widthspec.h
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
2010-09-02 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
grub-mknetdir script.
|
||||
|
||||
* Makefile.util.def (grub-mknetdir): New module.
|
||||
* tests/util/grub-shell.in: Support boot=net
|
||||
* util/grub-mknetdir.in: New file.
|
2
INSTALL
2
INSTALL
|
@ -21,7 +21,7 @@ configuring the GRUB.
|
|||
|
||||
On GNU/Linux, you also need:
|
||||
|
||||
* libdevmapper (recommended)
|
||||
* libdevmapper 1.02.34 or later (recommended)
|
||||
|
||||
To build grub-emu, you need:
|
||||
|
||||
|
|
24
Makefile.am
24
Makefile.am
|
@ -1,7 +1,7 @@
|
|||
AUTOMAKE_OPTIONS = subdir-objects
|
||||
|
||||
DEPDIR = .deps-util
|
||||
SUBDIRS = . grub-core po docs
|
||||
SUBDIRS = grub-core/gnulib . grub-core po docs util/bash-completion.d
|
||||
|
||||
include $(top_srcdir)/conf/Makefile.common
|
||||
include $(top_srcdir)/conf/Makefile.extra-dist
|
||||
|
@ -11,6 +11,8 @@ AM_LDFLAGS = $(HOST_LDFLAGS)
|
|||
AM_CPPFLAGS = $(HOST_CPPFLAGS) $(CPPFLAGS_DEFAULT)
|
||||
AM_CCASFLAGS = $(HOST_CCASFLAGS) $(CCASFLAGS_DEFAULT)
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
CFLAGS_PROGRAM += $(CFLAGS_GNULIB)
|
||||
LDFLAGS_PROGRAM += $(LDFLAGS_GNULIB)
|
||||
CPPFLAGS_PROGRAM += $(CPPFLAGS_GNULIB)
|
||||
|
@ -44,9 +46,23 @@ libgrub_a_init.c: libgrub_a_init.lst $(top_srcdir)/geninit.sh
|
|||
sh $(top_srcdir)/geninit.sh `cat $<` > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += libgrub_a_init.c
|
||||
|
||||
# For grub-fstest
|
||||
grub_fstest.pp: $(grub_fstest_SOURCES)
|
||||
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(grub_fstest_CPPFLAGS) $(CPPFLAGS) \
|
||||
-D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += grub_fstest.pp
|
||||
|
||||
grub_fstest_init.lst: libgrub.pp grub_fstest.pp
|
||||
cat $^ | grep '@MARKER@' | sed 's/@MARKER@\(.*\)@/\1/g' | sort -u > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += grub_fstest_init.lst
|
||||
|
||||
grub_fstest_init.c: grub_fstest_init.lst $(top_srcdir)/geninit.sh
|
||||
sh $(top_srcdir)/geninit.sh `cat $<` > $@ || (rm -f $@; exit 1)
|
||||
CLEANFILES += grub_fstest_init.c
|
||||
|
||||
if COND_GRUB_MKFONT
|
||||
if COND_HAVE_FONT_SOURCE
|
||||
grubdata_DATA = unicode.pf2 ascii.pf2 ascii.h widthspec.h
|
||||
grubdata_DATA = unicode.pf2 ascii.pf2 euro.pf2 ascii.h widthspec.h
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -62,6 +78,10 @@ ascii.pf2: $(FONT_SOURCE) grub-mkfont
|
|||
$(builddir)/grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES)
|
||||
CLEANFILES += ascii.pf2
|
||||
|
||||
euro.pf2: $(FONT_SOURCE) grub-mkfont
|
||||
$(builddir)/grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x4ff,0x1e00-0x1fff,$(UNICODE_ARROWS),$(UNICODE_LINES)
|
||||
CLEANFILES += euro.pf2
|
||||
|
||||
ascii.bitmaps: $(FONT_SOURCE) grub-mkfont
|
||||
$(builddir)/grub-mkfont --ascii-bitmaps -o $@ $(FONT_SOURCE)
|
||||
CLEANFILES += ascii.bitmaps
|
||||
|
|
|
@ -11,19 +11,10 @@ library = {
|
|||
common_nodist = grub_script.yy.h;
|
||||
common_nodist = grub_script.tab.h;
|
||||
|
||||
common = grub-core/gnulib/error.c;
|
||||
common = grub-core/gnulib/fnmatch.c;
|
||||
common = grub-core/gnulib/getdelim.c;
|
||||
common = grub-core/gnulib/getline.c;
|
||||
common = grub-core/gnulib/getopt1.c;
|
||||
common = grub-core/gnulib/getopt.c;
|
||||
common = grub-core/gnulib/progname.c;
|
||||
|
||||
common = util/misc.c;
|
||||
common = grub-core/kern/misc.c;
|
||||
common = grub-core/kern/emu/mm.c;
|
||||
common = grub-core/kern/emu/misc.c;
|
||||
common = grub-core/kern/emu/hostfs.c;
|
||||
common = grub-core/kern/emu/getroot.c;
|
||||
common = grub-core/kern/emu/hostdisk.c;
|
||||
|
||||
|
@ -32,10 +23,10 @@ library = {
|
|||
common = grub-core/commands/ls.c;
|
||||
common = grub-core/net/net.c;
|
||||
common = grub-core/disk/dmraid_nvidia.c;
|
||||
common = grub-core/disk/host.c;
|
||||
common = grub-core/disk/loopback.c;
|
||||
common = grub-core/disk/lvm.c;
|
||||
common = grub-core/disk/mdraid_linux.c;
|
||||
common = grub-core/disk/mdraid1x_linux.c;
|
||||
common = grub-core/disk/raid5_recover.c;
|
||||
common = grub-core/disk/raid6_recover.c;
|
||||
common = grub-core/disk/raid.c;
|
||||
|
@ -44,6 +35,7 @@ library = {
|
|||
common = grub-core/fs/afs.c;
|
||||
common = grub-core/fs/befs_be.c;
|
||||
common = grub-core/fs/befs.c;
|
||||
common = grub-core/fs/btrfs.c;
|
||||
common = grub-core/fs/cpio.c;
|
||||
common = grub-core/fs/ext2.c;
|
||||
common = grub-core/fs/fat.c;
|
||||
|
@ -53,6 +45,7 @@ library = {
|
|||
common = grub-core/fs/iso9660.c;
|
||||
common = grub-core/fs/jfs.c;
|
||||
common = grub-core/fs/minix.c;
|
||||
common = grub-core/fs/minix2.c;
|
||||
common = grub-core/fs/nilfs2.c;
|
||||
common = grub-core/fs/ntfs.c;
|
||||
common = grub-core/fs/ntfscomp.c;
|
||||
|
@ -73,11 +66,11 @@ library = {
|
|||
common = grub-core/kern/list.c;
|
||||
common = grub-core/kern/partition.c;
|
||||
common = grub-core/lib/arg.c;
|
||||
common = grub-core/lib/crc.c;
|
||||
common = grub-core/lib/crypto.c;
|
||||
common = grub-core/lib/envblk.c;
|
||||
common = grub-core/lib/hexdump.c;
|
||||
common = grub-core/lib/libgcrypt-grub/cipher/sha512.c;
|
||||
common = grub-core/lib/libgcrypt-grub/cipher/crc.c;
|
||||
common = grub-core/lib/LzFind.c;
|
||||
common = grub-core/lib/LzmaEnc.c;
|
||||
common = grub-core/lib/pbkdf2.c;
|
||||
|
@ -90,6 +83,7 @@ library = {
|
|||
common = grub-core/partmap/msdos.c;
|
||||
common = grub-core/partmap/sun.c;
|
||||
common = grub-core/partmap/sunpc.c;
|
||||
common = grub-core/partmap/bsdlabel.c;
|
||||
common = grub-core/script/function.c;
|
||||
common = grub-core/script/lexer.c;
|
||||
common = grub-core/script/main.c;
|
||||
|
@ -102,6 +96,7 @@ program = {
|
|||
common = util/bin2h.c;
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
mansection = 1;
|
||||
};
|
||||
|
||||
|
@ -115,6 +110,7 @@ program = {
|
|||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
cppflags = '-DGRUB_PKGLIBROOTDIR=\"$(pkglibrootdir)\"';
|
||||
};
|
||||
|
||||
|
@ -126,6 +122,7 @@ program = {
|
|||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
};
|
||||
|
||||
program = {
|
||||
|
@ -136,6 +133,7 @@ program = {
|
|||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
};
|
||||
|
||||
program = {
|
||||
|
@ -146,6 +144,7 @@ program = {
|
|||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
};
|
||||
|
||||
program = {
|
||||
|
@ -156,6 +155,7 @@ program = {
|
|||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
cflags = '$(CFLAGS_GCRY)';
|
||||
cppflags = '$(CPPFLAGS_GCRY)';
|
||||
};
|
||||
|
@ -174,17 +174,24 @@ program = {
|
|||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL)';
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
condition = COND_GRUB_PE2ELF;
|
||||
};
|
||||
|
||||
program = {
|
||||
name = grub-fstest;
|
||||
mansection = 1;
|
||||
common_nodist = grub_fstest_init.c;
|
||||
common = util/grub-fstest.c;
|
||||
common = grub-core/kern/emu/hostfs.c;
|
||||
common = grub-core/disk/host.c;
|
||||
|
||||
cflags = '$(CFLAGS_GCRY)';
|
||||
cppflags = '$(CPPFLAGS_GCRY)';
|
||||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||
condition = COND_GRUB_FSTEST;
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
};
|
||||
|
||||
program = {
|
||||
|
@ -197,6 +204,7 @@ program = {
|
|||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
ldadd = '$(freetype_libs)';
|
||||
condition = COND_GRUB_MKFONT;
|
||||
};
|
||||
|
@ -215,6 +223,7 @@ program = {
|
|||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)';
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
};
|
||||
|
||||
program = {
|
||||
|
@ -225,23 +234,22 @@ program = {
|
|||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)';
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
};
|
||||
|
||||
program = {
|
||||
name = grub-setup;
|
||||
installdir = sbin;
|
||||
mansection = 8;
|
||||
i386_pc = util/i386/pc/grub-setup.c;
|
||||
i386_pc = util/raid.c;
|
||||
i386_pc = util/lvm.c;
|
||||
common = util/grub-setup.c;
|
||||
common = util/raid.c;
|
||||
common = util/lvm.c;
|
||||
|
||||
sparc64_ieee1275 = util/ieee1275/ofpath.c;
|
||||
sparc64_ieee1275 = util/sparc64/ieee1275/grub-setup.c;
|
||||
sparc64_ieee1275 = util/raid.c;
|
||||
sparc64_ieee1275 = util/lvm.c;
|
||||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)';
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
|
||||
enable = i386_pc;
|
||||
enable = sparc64_ieee1275;
|
||||
|
@ -255,9 +263,21 @@ program = {
|
|||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL)';
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
enable = sparc64_ieee1275;
|
||||
};
|
||||
|
||||
program = {
|
||||
name = grub-mklayout;
|
||||
mansection = 1;
|
||||
|
||||
common = util/grub-mklayout.c;
|
||||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
};
|
||||
|
||||
data = {
|
||||
common = util/grub.d/README;
|
||||
installdir = grubconf;
|
||||
|
@ -347,17 +367,7 @@ script = {
|
|||
installdir = sbin;
|
||||
name = grub-install;
|
||||
|
||||
mips = util/grub-install.in;
|
||||
i386_pc = util/grub-install.in;
|
||||
i386_qemu = util/grub-install.in;
|
||||
i386_coreboot = util/grub-install.in;
|
||||
i386_multiboot = util/grub-install.in;
|
||||
sparc64_ieee1275 = util/grub-install.in;
|
||||
|
||||
x86_efi = util/i386/efi/grub-install.in;
|
||||
i386_ieee1275 = util/ieee1275/grub-install.in;
|
||||
powerpc_ieee1275 = util/ieee1275/grub-install.in;
|
||||
|
||||
common = util/grub-install.in;
|
||||
enable = noemu;
|
||||
};
|
||||
|
||||
|
@ -402,6 +412,11 @@ script = {
|
|||
installdir = noinst;
|
||||
};
|
||||
|
||||
script = {
|
||||
name = grub-kbdcomp;
|
||||
common = util/grub-kbdcomp.in;
|
||||
};
|
||||
|
||||
script = {
|
||||
name = grub-shell;
|
||||
common = tests/util/grub-shell.in;
|
||||
|
@ -510,6 +525,54 @@ script = {
|
|||
common = tests/grub_script_shift.in;
|
||||
};
|
||||
|
||||
script = {
|
||||
testcase;
|
||||
name = grub_script_blockarg;
|
||||
common = tests/grub_script_blockarg.in;
|
||||
};
|
||||
|
||||
script = {
|
||||
testcase;
|
||||
name = grub_script_setparams;
|
||||
common = tests/grub_script_setparams.in;
|
||||
};
|
||||
|
||||
script = {
|
||||
testcase;
|
||||
name = grub_script_return;
|
||||
common = tests/grub_script_return.in;
|
||||
};
|
||||
|
||||
script = {
|
||||
testcase;
|
||||
name = grub_cmd_regexp;
|
||||
common = tests/grub_cmd_regexp.in;
|
||||
};
|
||||
|
||||
script = {
|
||||
testcase;
|
||||
name = grub_script_expansion;
|
||||
common = tests/grub_script_expansion.in;
|
||||
};
|
||||
|
||||
script = {
|
||||
testcase;
|
||||
name = grub_script_not;
|
||||
common = tests/grub_script_not.in;
|
||||
};
|
||||
|
||||
script = {
|
||||
testcase;
|
||||
name = partmap_test;
|
||||
common = tests/partmap_test.in;
|
||||
};
|
||||
|
||||
script = {
|
||||
testcase;
|
||||
name = grub_cmd_echo;
|
||||
common = tests/grub_cmd_echo.in;
|
||||
};
|
||||
|
||||
program = {
|
||||
testcase;
|
||||
name = example_unit_test;
|
||||
|
@ -522,3 +585,15 @@ program = {
|
|||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBDEVMAPPER)';
|
||||
};
|
||||
|
||||
program = {
|
||||
name = grub-menulst2cfg;
|
||||
mansection = 1;
|
||||
common = util/grub-menulst2cfg.c;
|
||||
common = grub-core/lib/legacy_parse.c;
|
||||
common = grub-core/lib/i386/pc/vesa_modes_table.c;
|
||||
|
||||
ldadd = libgrub.a;
|
||||
ldflags = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||
ldadd = grub-core/gnulib/libgnu.a;
|
||||
};
|
||||
|
|
50
NEWS
50
NEWS
|
@ -1,5 +1,47 @@
|
|||
New in 1.99:
|
||||
|
||||
* Keyboard layouts support.
|
||||
|
||||
* New `lsapm' command (i386-pc only).
|
||||
|
||||
* Parser for GRUB Legacy configuration files.
|
||||
|
||||
* Support RAID on virtio devices.
|
||||
|
||||
* Remove deprecated `root' command.
|
||||
|
||||
* New `euro.pf2' font which supports most European languages.
|
||||
|
||||
* Avoid opening the same device twice on Open Firmware platforms.
|
||||
|
||||
* Extend `vbeinfo' and `vbetest' commands to non-VBE graphics, as
|
||||
`videoinfo' and `videotest'.
|
||||
|
||||
* New `lsefisystab', `lssal', and `lsefimmap' commands on EFI platforms.
|
||||
|
||||
* Support explicit user claim that a device is BIOS-visible. Devices
|
||||
listed in device.map will be assumed to be readable using only BIOS
|
||||
facilities, rather than anything more complex such as LVM or RAID.
|
||||
|
||||
* New bash-completion script for GRUB utilities.
|
||||
|
||||
* Use ACPI to shut down if possible.
|
||||
|
||||
* New `lsacpi' command.
|
||||
|
||||
* Basic btrfs support (detection and UUID).
|
||||
|
||||
* New `--boot-directory' option to `grub-install', `grub-reboot', and
|
||||
`grub-set-default', with clearer semantics than the previous
|
||||
`--root-directory' option.
|
||||
|
||||
* Rename CD-ROM device to "cd" on BIOS platforms.
|
||||
|
||||
* Transparent decompression filters.
|
||||
|
||||
* Simpler PXE image generation. New `grub-mknetdir' utility to generate
|
||||
netboot directory trees.
|
||||
|
||||
* New relocator. Allows for more kernel support and more
|
||||
straightforward loader writing.
|
||||
|
||||
|
@ -60,7 +102,8 @@ New in 1.99:
|
|||
|
||||
* `grub-mkrescue' support for EFI, coreboot, and QEMU platforms.
|
||||
|
||||
* Unify `grub-mkimage' source code across platforms.
|
||||
* Unify `grub-mkimage', `grub-setup', and `grub-install' source code
|
||||
across platforms.
|
||||
|
||||
* Fix VGA (as opposed to VBE) video driver, formerly a terminal driver.
|
||||
|
||||
|
@ -83,8 +126,9 @@ New in 1.99:
|
|||
* sunpc partition table support.
|
||||
|
||||
* Add a number of new language features to GRUB script: `for', `while',
|
||||
`until', `elif', function parameters, `break', `continue', and
|
||||
`shift'.
|
||||
`until', `elif', function parameters, `break', `continue', `shift',
|
||||
multi-line quoted strings, positional parameters with `setparams',
|
||||
`return', filename wildcard expansion, and `!'.
|
||||
|
||||
* Support nested partition tables. GRUB now prefers to name partitions
|
||||
in the form `(hd0,msdos1,bsd1)' rather than `(hd0,1,a)'.
|
||||
|
|
61
acinclude.m4
61
acinclude.m4
|
@ -58,18 +58,15 @@ else
|
|||
fi
|
||||
|
||||
if $EGREP '(^|[^_[:alnum]])_func' conftest.s >/dev/null 2>&1; then
|
||||
HAVE_ASM_USCORE=1
|
||||
grub_cv_asm_uscore=yes
|
||||
else
|
||||
HAVE_ASM_USCORE=0
|
||||
grub_cv_asm_uscore=no
|
||||
fi
|
||||
|
||||
rm -f conftest*])
|
||||
|
||||
if test "x$grub_cv_asm_uscore" = xyes; then
|
||||
AC_DEFINE_UNQUOTED([HAVE_ASM_USCORE], $grub_cv_asm_uscore,
|
||||
[Define if C symbols get an underscore after compilation])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_asm_uscore])
|
||||
])
|
||||
|
||||
|
@ -237,44 +234,12 @@ else
|
|||
grub_tmp_data32="data32;"
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED([ADDR32], $grub_tmp_addr32,
|
||||
[Define it to \"addr32\" or \"addr32;\" to make GAS happy])
|
||||
AC_DEFINE_UNQUOTED([DATA32], $grub_tmp_data32,
|
||||
[Define it to \"data32\" or \"data32;\" to make GAS happy])
|
||||
ADDR32=$grub_tmp_addr32
|
||||
DATA32=$grub_tmp_data32
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_i386_asm_prefix_requirement])])
|
||||
|
||||
|
||||
dnl Older versions of GAS require that absolute indirect calls/jumps are
|
||||
dnl not prefixed with `*', while later versions warn if not prefixed.
|
||||
AC_DEFUN([grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING(dnl
|
||||
[whether an absolute indirect call/jump must not be prefixed with an asterisk])
|
||||
AC_CACHE_VAL(grub_cv_i386_asm_absolute_without_asterisk,
|
||||
[cat > conftest.s <<\EOF
|
||||
lcall *(offset)
|
||||
offset:
|
||||
.long 0
|
||||
.word 0
|
||||
EOF
|
||||
|
||||
if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
|
||||
grub_cv_i386_asm_absolute_without_asterisk=no
|
||||
else
|
||||
grub_cv_i386_asm_absolute_without_asterisk=yes
|
||||
fi
|
||||
|
||||
rm -f conftest*])
|
||||
|
||||
if test "x$grub_cv_i386_asm_absolute_without_asterisk" = xyes; then
|
||||
AC_DEFINE([ABSOLUTE_WITHOUT_ASTERISK], 1,
|
||||
[Define it if GAS requires that absolute indirect calls/jumps are not prefixed with an asterisk])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$grub_cv_i386_asm_absolute_without_asterisk])])
|
||||
|
||||
|
||||
dnl Check what symbol is defined as a bss start symbol.
|
||||
dnl Written by Michael Hohmoth and Yoshinori K. Okuji.
|
||||
AC_DEFUN([grub_CHECK_BSS_START_SYMBOL],
|
||||
|
@ -306,14 +271,12 @@ AC_CACHE_VAL(grub_cv_check_uscore_edata_symbol,
|
|||
|
||||
AC_MSG_RESULT([$grub_cv_check_uscore_edata_symbol])
|
||||
|
||||
AH_TEMPLATE([BSS_START_SYMBOL], [Define it to one of __bss_start, edata and _edata])
|
||||
|
||||
if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" = xyes; then
|
||||
AC_DEFINE([BSS_START_SYMBOL], [__bss_start])
|
||||
BSS_START_SYMBOL=__bss_start
|
||||
elif test "x$grub_cv_check_edata_symbol" = xyes; then
|
||||
AC_DEFINE([BSS_START_SYMBOL], [edata])
|
||||
BSS_START_SYMBOL=edata
|
||||
elif test "x$grub_cv_check_uscore_edata_symbol" = xyes; then
|
||||
AC_DEFINE([BSS_START_SYMBOL], [_edata])
|
||||
BSS_START_SYMBOL=_edata
|
||||
else
|
||||
AC_MSG_ERROR([none of __bss_start, edata or _edata is defined])
|
||||
fi
|
||||
|
@ -341,12 +304,10 @@ AC_CACHE_VAL(grub_cv_check_uscore_end_symbol,
|
|||
|
||||
AC_MSG_RESULT([$grub_cv_check_uscore_end_symbol])
|
||||
|
||||
AH_TEMPLATE([END_SYMBOL], [Define it to either end or _end])
|
||||
|
||||
if test "x$grub_cv_check_end_symbol" = xyes; then
|
||||
AC_DEFINE([END_SYMBOL], [end])
|
||||
END_SYMBOL=end
|
||||
elif test "x$grub_cv_check_uscore_end_symbol" = xyes; then
|
||||
AC_DEFINE([END_SYMBOL], [_end])
|
||||
END_SYMBOL=_end
|
||||
else
|
||||
AC_MSG_ERROR([neither end nor _end is defined])
|
||||
fi
|
||||
|
@ -369,10 +330,10 @@ else
|
|||
AC_MSG_ERROR([${CC-cc} failed to produce assembly code])
|
||||
fi
|
||||
if grep __enable_execute_stack conftest.s >/dev/null 2>&1; then
|
||||
AC_DEFINE([NEED_ENABLE_EXECUTE_STACK], 1,
|
||||
[Define to 1 if GCC generates calls to __enable_execute_stack()])
|
||||
NEED_ENABLE_EXECUTE_STACK=1
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
NEED_ENABLE_EXECUTE_STACK=0
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
rm -f conftest*
|
||||
|
|
26
build-aux/arg-nonnull.h
Normal file
26
build-aux/arg-nonnull.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* A C macro for declaring that specific arguments must not be NULL.
|
||||
Copyright (C) 2009, 2010 Free Software Foundation, Inc.
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools
|
||||
that the values passed as arguments n, ..., m must be non-NULL pointers.
|
||||
n = 1 stands for the first argument, n = 2 for the second argument etc. */
|
||||
#ifndef _GL_ARG_NONNULL
|
||||
# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3
|
||||
# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))
|
||||
# else
|
||||
# define _GL_ARG_NONNULL(params)
|
||||
# endif
|
||||
#endif
|
271
build-aux/c++defs.h
Normal file
271
build-aux/c++defs.h
Normal file
|
@ -0,0 +1,271 @@
|
|||
/* C++ compatible function declaration macros.
|
||||
Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _GL_CXXDEFS_H
|
||||
#define _GL_CXXDEFS_H
|
||||
|
||||
/* The three most frequent use cases of these macros are:
|
||||
|
||||
* For providing a substitute for a function that is missing on some
|
||||
platforms, but is declared and works fine on the platforms on which
|
||||
it exists:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if !@HAVE_FOO@
|
||||
_GL_FUNCDECL_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
|
||||
* For providing a replacement for a function that exists on all platforms,
|
||||
but is broken/insufficient and needs to be replaced on some platforms:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if @REPLACE_FOO@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef foo
|
||||
# define foo rpl_foo
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (foo, ...);
|
||||
_GL_CXXALIAS_RPL (foo, ...);
|
||||
# else
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
|
||||
* For providing a replacement for a function that exists on some platforms
|
||||
but is broken/insufficient and needs to be replaced on some of them and
|
||||
is additionally either missing or undeclared on some other platforms:
|
||||
|
||||
#if @GNULIB_FOO@
|
||||
# if @REPLACE_FOO@
|
||||
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
|
||||
# undef foo
|
||||
# define foo rpl_foo
|
||||
# endif
|
||||
_GL_FUNCDECL_RPL (foo, ...);
|
||||
_GL_CXXALIAS_RPL (foo, ...);
|
||||
# else
|
||||
# if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@
|
||||
_GL_FUNCDECL_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIAS_SYS (foo, ...);
|
||||
# endif
|
||||
_GL_CXXALIASWARN (foo);
|
||||
#elif defined GNULIB_POSIXCHECK
|
||||
...
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* _GL_EXTERN_C declaration;
|
||||
performs the declaration with C linkage. */
|
||||
#if defined __cplusplus
|
||||
# define _GL_EXTERN_C extern "C"
|
||||
#else
|
||||
# define _GL_EXTERN_C extern
|
||||
#endif
|
||||
|
||||
/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);
|
||||
declares a replacement function, named rpl_func, with the given prototype,
|
||||
consisting of return type, parameters, and attributes.
|
||||
Example:
|
||||
_GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
|
||||
_GL_ARG_NONNULL ((1)));
|
||||
*/
|
||||
#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
|
||||
_GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
|
||||
#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C rettype rpl_func parameters_and_attributes
|
||||
|
||||
/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
|
||||
declares the system function, named func, with the given prototype,
|
||||
consisting of return type, parameters, and attributes.
|
||||
Example:
|
||||
_GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
|
||||
_GL_ARG_NONNULL ((1)));
|
||||
*/
|
||||
#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C rettype func parameters_and_attributes
|
||||
|
||||
/* _GL_CXXALIAS_RPL (func, rettype, parameters);
|
||||
declares a C++ alias called GNULIB_NAMESPACE::func
|
||||
that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
|
||||
Example:
|
||||
_GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
|
||||
*/
|
||||
#define _GL_CXXALIAS_RPL(func,rettype,parameters) \
|
||||
_GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
rettype (*const func) parameters = ::rpl_func; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
|
||||
is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
|
||||
except that the C function rpl_func may have a slightly different
|
||||
declaration. A cast is used to silence the "invalid conversion" error
|
||||
that would otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
rettype (*const func) parameters = \
|
||||
reinterpret_cast<rettype(*)parameters>(::rpl_func); \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
declares a C++ alias called GNULIB_NAMESPACE::func
|
||||
that redirects to the system provided function func, if GNULIB_NAMESPACE
|
||||
is defined.
|
||||
Example:
|
||||
_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
|
||||
*/
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
/* If we were to write
|
||||
rettype (*const func) parameters = ::func;
|
||||
like above in _GL_CXXALIAS_RPL_1, the compiler could optimize calls
|
||||
better (remove an indirection through a 'static' pointer variable),
|
||||
but then the _GL_CXXALIASWARN macro below would cause a warning not only
|
||||
for uses of ::func but also for uses of GNULIB_NAMESPACE::func. */
|
||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static rettype (*func) parameters = ::func; \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
|
||||
is like _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
except that the C function func may have a slightly different declaration.
|
||||
A cast is used to silence the "invalid conversion" error that would
|
||||
otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static rettype (*func) parameters = \
|
||||
reinterpret_cast<rettype(*)parameters>(::func); \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
|
||||
is like _GL_CXXALIAS_SYS (func, rettype, parameters);
|
||||
except that the C function is picked among a set of overloaded functions,
|
||||
namely the one with rettype2 and parameters2. Two consecutive casts
|
||||
are used to silence the "cannot find a match" and "invalid conversion"
|
||||
errors that would otherwise occur. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
/* The outer cast must be a reinterpret_cast.
|
||||
The inner cast: When the function is defined as a set of overloaded
|
||||
functions, it works as a static_cast<>, choosing the designated variant.
|
||||
When the function is defined as a single variant, it works as a
|
||||
reinterpret_cast<>. The parenthesized cast syntax works both ways. */
|
||||
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
|
||||
namespace GNULIB_NAMESPACE \
|
||||
{ \
|
||||
static rettype (*func) parameters = \
|
||||
reinterpret_cast<rettype(*)parameters>( \
|
||||
(rettype2(*)parameters2)(::func)); \
|
||||
} \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#else
|
||||
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIASWARN (func);
|
||||
causes a warning to be emitted when ::func is used but not when
|
||||
GNULIB_NAMESPACE::func is used. func must be defined without overloaded
|
||||
variants. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIASWARN(func) \
|
||||
_GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
|
||||
# define _GL_CXXALIASWARN_1(func,namespace) \
|
||||
_GL_CXXALIASWARN_2 (func, namespace)
|
||||
/* To work around GCC bug <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
|
||||
we enable the warning only when not optimizing. */
|
||||
# if !__OPTIMIZE__
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
_GL_WARN_ON_USE (func, \
|
||||
"The symbol ::" #func " refers to the system function. " \
|
||||
"Use " #namespace "::" #func " instead.")
|
||||
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
extern __typeof__ (func) func
|
||||
# else
|
||||
# define _GL_CXXALIASWARN_2(func,namespace) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
# endif
|
||||
#else
|
||||
# define _GL_CXXALIASWARN(func) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
|
||||
causes a warning to be emitted when the given overloaded variant of ::func
|
||||
is used but not when GNULIB_NAMESPACE::func is used. */
|
||||
#if defined __cplusplus && defined GNULIB_NAMESPACE
|
||||
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
|
||||
_GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
|
||||
GNULIB_NAMESPACE)
|
||||
# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
|
||||
/* To work around GCC bug <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
|
||||
we enable the warning only when not optimizing. */
|
||||
# if !__OPTIMIZE__
|
||||
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \
|
||||
"The symbol ::" #func " refers to the system function. " \
|
||||
"Use " #namespace "::" #func " instead.")
|
||||
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
|
||||
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
|
||||
extern __typeof__ (func) func
|
||||
# else
|
||||
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
# endif
|
||||
#else
|
||||
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
|
||||
_GL_EXTERN_C int _gl_cxxalias_dummy
|
||||
#endif
|
||||
|
||||
#endif /* _GL_CXXDEFS_H */
|
|
@ -2,7 +2,7 @@
|
|||
# Output a system dependent set of variables, describing how to set the
|
||||
# run time search path of shared libraries in an executable.
|
||||
#
|
||||
# Copyright 1996-2008 Free Software Foundation, Inc.
|
||||
# Copyright 1996-2006 Free Software Foundation, Inc.
|
||||
# Taken from GNU libtool, 2001
|
||||
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
|
||||
#
|
||||
|
@ -47,7 +47,7 @@ for cc_temp in $CC""; do
|
|||
done
|
||||
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
|
||||
|
||||
# Code taken from libtool.m4's _LT_COMPILER_PIC.
|
||||
# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
|
||||
|
||||
wl=
|
||||
if test "$GCC" = yes; then
|
||||
|
@ -64,7 +64,7 @@ else
|
|||
;;
|
||||
esac
|
||||
;;
|
||||
mingw* | cygwin* | pw32* | os2* | cegcc*)
|
||||
mingw* | pw32* | os2*)
|
||||
;;
|
||||
hpux9* | hpux10* | hpux11*)
|
||||
wl='-Wl,'
|
||||
|
@ -74,15 +74,9 @@ else
|
|||
;;
|
||||
newsos6)
|
||||
;;
|
||||
linux* | k*bsd*-gnu)
|
||||
linux*)
|
||||
case $cc_basename in
|
||||
ecc*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
icc* | ifort*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
lf95*)
|
||||
icc* | ecc*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
pgcc | pgf77 | pgf90)
|
||||
|
@ -106,7 +100,7 @@ else
|
|||
osf3* | osf4* | osf5*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
rdos*)
|
||||
sco3.2v5*)
|
||||
;;
|
||||
solaris*)
|
||||
wl='-Wl,'
|
||||
|
@ -114,14 +108,11 @@ else
|
|||
sunos4*)
|
||||
wl='-Qoption ld '
|
||||
;;
|
||||
sysv4 | sysv4.2uw2* | sysv4.3*)
|
||||
sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
sysv4*MP*)
|
||||
;;
|
||||
sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
unicos*)
|
||||
wl='-Wl,'
|
||||
;;
|
||||
|
@ -130,7 +121,7 @@ else
|
|||
esac
|
||||
fi
|
||||
|
||||
# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
|
||||
# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
|
||||
|
||||
hardcode_libdir_flag_spec=
|
||||
hardcode_libdir_separator=
|
||||
|
@ -138,7 +129,7 @@ hardcode_direct=no
|
|||
hardcode_minus_L=no
|
||||
|
||||
case "$host_os" in
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
cygwin* | mingw* | pw32*)
|
||||
# FIXME: the MSVC++ port hasn't been tested in a loooong time
|
||||
# When not using gcc, we currently assume that we are using
|
||||
# Microsoft Visual C++.
|
||||
|
@ -164,7 +155,7 @@ if test "$with_gnu_ld" = yes; then
|
|||
# option of GNU ld is called -rpath, not --rpath.
|
||||
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
|
||||
case "$host_os" in
|
||||
aix[3-9]*)
|
||||
aix3* | aix4* | aix5*)
|
||||
# On AIX/PPC, the GNU linker is very broken
|
||||
if test "$host_cpu" != ia64; then
|
||||
ld_shlibs=no
|
||||
|
@ -188,7 +179,7 @@ if test "$with_gnu_ld" = yes; then
|
|||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
cygwin* | mingw* | pw32*)
|
||||
# hardcode_libdir_flag_spec is actually meaningless, as there is
|
||||
# no search path for DLLs.
|
||||
hardcode_libdir_flag_spec='-L$libdir'
|
||||
|
@ -198,11 +189,11 @@ if test "$with_gnu_ld" = yes; then
|
|||
ld_shlibs=no
|
||||
fi
|
||||
;;
|
||||
interix[3-9]*)
|
||||
interix3*)
|
||||
hardcode_direct=no
|
||||
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
|
||||
;;
|
||||
gnu* | linux* | k*bsd*-gnu)
|
||||
linux*)
|
||||
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
|
||||
:
|
||||
else
|
||||
|
@ -260,7 +251,7 @@ else
|
|||
hardcode_direct=unsupported
|
||||
fi
|
||||
;;
|
||||
aix[4-9]*)
|
||||
aix4* | aix5*)
|
||||
if test "$host_cpu" = ia64; then
|
||||
# On IA64, the linker does run time linking by default, so we don't
|
||||
# have to do anything special.
|
||||
|
@ -270,7 +261,7 @@ else
|
|||
# Test if we are trying to use run time linking or normal
|
||||
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
|
||||
# need to do runtime linking.
|
||||
case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
|
||||
case $host_os in aix4.[23]|aix4.[23].*|aix5*)
|
||||
for ld_flag in $LDFLAGS; do
|
||||
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
|
||||
aix_use_runtimelinking=yes
|
||||
|
@ -289,7 +280,7 @@ else
|
|||
strings "$collect2name" | grep resolve_lib_name >/dev/null
|
||||
then
|
||||
# We have reworked collect2
|
||||
:
|
||||
hardcode_direct=yes
|
||||
else
|
||||
# We have old collect2
|
||||
hardcode_direct=unsupported
|
||||
|
@ -332,7 +323,7 @@ else
|
|||
;;
|
||||
bsdi[45]*)
|
||||
;;
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
cygwin* | mingw* | pw32*)
|
||||
# When not using gcc, we currently assume that we are using
|
||||
# Microsoft Visual C++.
|
||||
# hardcode_libdir_flag_spec is actually meaningless, as there is
|
||||
|
@ -368,7 +359,7 @@ else
|
|||
hardcode_direct=yes
|
||||
hardcode_minus_L=yes
|
||||
;;
|
||||
freebsd* | dragonfly*)
|
||||
freebsd* | kfreebsd*-gnu | dragonfly*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
hardcode_direct=yes
|
||||
;;
|
||||
|
@ -421,22 +412,18 @@ else
|
|||
hardcode_libdir_separator=:
|
||||
;;
|
||||
openbsd*)
|
||||
if test -f /usr/libexec/ld.so; then
|
||||
hardcode_direct=yes
|
||||
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
|
||||
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
|
||||
else
|
||||
case "$host_os" in
|
||||
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
;;
|
||||
*)
|
||||
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
hardcode_direct=yes
|
||||
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
|
||||
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
|
||||
else
|
||||
ld_shlibs=no
|
||||
case "$host_os" in
|
||||
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
|
||||
hardcode_libdir_flag_spec='-R$libdir'
|
||||
;;
|
||||
*)
|
||||
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
os2*)
|
||||
|
@ -484,7 +471,7 @@ else
|
|||
ld_shlibs=yes
|
||||
fi
|
||||
;;
|
||||
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
|
||||
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
|
||||
;;
|
||||
sysv5* | sco3.2v5* | sco5v6*)
|
||||
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
|
||||
|
@ -500,52 +487,34 @@ else
|
|||
fi
|
||||
|
||||
# Check dynamic linker characteristics
|
||||
# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
|
||||
# Unlike libtool.m4, here we don't care about _all_ names of the library, but
|
||||
# only about the one the linker finds when passed -lNAME. This is the last
|
||||
# element of library_names_spec in libtool.m4, or possibly two of them if the
|
||||
# linker has special search rules.
|
||||
library_names_spec= # the last element of library_names_spec in libtool.m4
|
||||
# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
|
||||
libname_spec='lib$name'
|
||||
case "$host_os" in
|
||||
aix3*)
|
||||
library_names_spec='$libname.a'
|
||||
;;
|
||||
aix[4-9]*)
|
||||
library_names_spec='$libname$shrext'
|
||||
aix4* | aix5*)
|
||||
;;
|
||||
amigaos*)
|
||||
library_names_spec='$libname.a'
|
||||
;;
|
||||
beos*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
bsdi[45]*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
cygwin* | mingw* | pw32*)
|
||||
shrext=.dll
|
||||
library_names_spec='$libname.dll.a $libname.lib'
|
||||
;;
|
||||
darwin* | rhapsody*)
|
||||
shrext=.dylib
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
dgux*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
freebsd1*)
|
||||
;;
|
||||
kfreebsd*-gnu)
|
||||
;;
|
||||
freebsd* | dragonfly*)
|
||||
case "$host_os" in
|
||||
freebsd[123]*)
|
||||
library_names_spec='$libname$shrext$versuffix' ;;
|
||||
*)
|
||||
library_names_spec='$libname$shrext' ;;
|
||||
esac
|
||||
;;
|
||||
gnu*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
hpux9* | hpux10* | hpux11*)
|
||||
case $host_cpu in
|
||||
|
@ -559,13 +528,10 @@ case "$host_os" in
|
|||
shrext=.sl
|
||||
;;
|
||||
esac
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
interix[3-9]*)
|
||||
library_names_spec='$libname$shrext'
|
||||
interix3*)
|
||||
;;
|
||||
irix5* | irix6* | nonstopux*)
|
||||
library_names_spec='$libname$shrext'
|
||||
case "$host_os" in
|
||||
irix5* | nonstopux*)
|
||||
libsuff= shlibsuff=
|
||||
|
@ -582,59 +548,41 @@ case "$host_os" in
|
|||
;;
|
||||
linux*oldld* | linux*aout* | linux*coff*)
|
||||
;;
|
||||
linux* | k*bsd*-gnu)
|
||||
library_names_spec='$libname$shrext'
|
||||
linux*)
|
||||
;;
|
||||
knetbsd*-gnu)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
netbsd*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
newsos6)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
nto-qnx*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
openbsd*)
|
||||
library_names_spec='$libname$shrext$versuffix'
|
||||
;;
|
||||
os2*)
|
||||
libname_spec='$name'
|
||||
shrext=.dll
|
||||
library_names_spec='$libname.a'
|
||||
;;
|
||||
osf3* | osf4* | osf5*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
rdos*)
|
||||
;;
|
||||
solaris*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
sunos4*)
|
||||
library_names_spec='$libname$shrext$versuffix'
|
||||
;;
|
||||
sysv4 | sysv4.3*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
sysv4*MP*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
uts4*)
|
||||
library_names_spec='$libname$shrext'
|
||||
;;
|
||||
esac
|
||||
|
||||
sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
|
||||
escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
|
||||
shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
|
||||
escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
|
||||
escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
|
||||
escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
|
||||
|
||||
LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
|
||||
|
@ -648,12 +596,6 @@ libext="$libext"
|
|||
# Shared library suffix (normally "so").
|
||||
shlibext="$shlibext"
|
||||
|
||||
# Format of library name prefix.
|
||||
libname_spec="$escaped_libname_spec"
|
||||
|
||||
# Library names that the linker finds when passed -lNAME.
|
||||
library_names_spec="$escaped_library_names_spec"
|
||||
|
||||
# Flag to hardcode \$libdir into a binary during linking.
|
||||
# This must work even if \$libdir does not exist.
|
||||
hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
|
109
build-aux/warn-on-use.h
Normal file
109
build-aux/warn-on-use.h
Normal file
|
@ -0,0 +1,109 @@
|
|||
/* A C macro for emitting warnings if a function is used.
|
||||
Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* _GL_WARN_ON_USE (function, "literal string") issues a declaration
|
||||
for FUNCTION which will then trigger a compiler warning containing
|
||||
the text of "literal string" anywhere that function is called, if
|
||||
supported by the compiler. If the compiler does not support this
|
||||
feature, the macro expands to an unused extern declaration.
|
||||
|
||||
This macro is useful for marking a function as a potential
|
||||
portability trap, with the intent that "literal string" include
|
||||
instructions on the replacement function that should be used
|
||||
instead. However, one of the reasons that a function is a
|
||||
portability trap is if it has the wrong signature. Declaring
|
||||
FUNCTION with a different signature in C is a compilation error, so
|
||||
this macro must use the same type as any existing declaration so
|
||||
that programs that avoid the problematic FUNCTION do not fail to
|
||||
compile merely because they included a header that poisoned the
|
||||
function. But this implies that _GL_WARN_ON_USE is only safe to
|
||||
use if FUNCTION is known to already have a declaration. Use of
|
||||
this macro implies that there must not be any other macro hiding
|
||||
the declaration of FUNCTION; but undefining FUNCTION first is part
|
||||
of the poisoning process anyway (although for symbols that are
|
||||
provided only via a macro, the result is a compilation error rather
|
||||
than a warning containing "literal string"). Also note that in
|
||||
C++, it is only safe to use if FUNCTION has no overloads.
|
||||
|
||||
For an example, it is possible to poison 'getline' by:
|
||||
- adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],
|
||||
[getline]) in configure.ac, which potentially defines
|
||||
HAVE_RAW_DECL_GETLINE
|
||||
- adding this code to a header that wraps the system <stdio.h>:
|
||||
#undef getline
|
||||
#if HAVE_RAW_DECL_GETLINE
|
||||
_GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but"
|
||||
"not universally present; use the gnulib module getline");
|
||||
#endif
|
||||
|
||||
It is not possible to directly poison global variables. But it is
|
||||
possible to write a wrapper accessor function, and poison that
|
||||
(less common usage, like &environ, will cause a compilation error
|
||||
rather than issue the nice warning, but the end result of informing
|
||||
the developer about their portability problem is still achieved):
|
||||
#if HAVE_RAW_DECL_ENVIRON
|
||||
static inline char ***rpl_environ (void) { return &environ; }
|
||||
_GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared");
|
||||
# undef environ
|
||||
# define environ (*rpl_environ ())
|
||||
#endif
|
||||
*/
|
||||
#ifndef _GL_WARN_ON_USE
|
||||
|
||||
# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
|
||||
/* A compiler attribute is available in gcc versions 4.3.0 and later. */
|
||||
# define _GL_WARN_ON_USE(function, message) \
|
||||
extern __typeof__ (function) function __attribute__ ((__warning__ (message)))
|
||||
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
|
||||
/* Verify the existence of the function. */
|
||||
# define _GL_WARN_ON_USE(function, message) \
|
||||
extern __typeof__ (function) function
|
||||
# else /* Unsupported. */
|
||||
# define _GL_WARN_ON_USE(function, message) \
|
||||
_GL_WARN_EXTERN_C int _gl_warn_on_use
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string")
|
||||
is like _GL_WARN_ON_USE (function, "string"), except that the function is
|
||||
declared with the given prototype, consisting of return type, parameters,
|
||||
and attributes.
|
||||
This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does
|
||||
not work in this case. */
|
||||
#ifndef _GL_WARN_ON_USE_CXX
|
||||
# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
|
||||
# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
|
||||
extern rettype function parameters_and_attributes \
|
||||
__attribute__ ((__warning__ (msg)))
|
||||
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
|
||||
/* Verify the existence of the function. */
|
||||
# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
|
||||
extern rettype function parameters_and_attributes
|
||||
# else /* Unsupported. */
|
||||
# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
|
||||
_GL_WARN_EXTERN_C int _gl_warn_on_use
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* _GL_WARN_EXTERN_C declaration;
|
||||
performs the declaration with C linkage. */
|
||||
#ifndef _GL_WARN_EXTERN_C
|
||||
# if defined __cplusplus
|
||||
# define _GL_WARN_EXTERN_C extern "C"
|
||||
# else
|
||||
# define _GL_WARN_EXTERN_C extern
|
||||
# endif
|
||||
#endif
|
|
@ -1,8 +1,10 @@
|
|||
# -*- makefile -*-
|
||||
|
||||
CFLAGS_PLATFORM=
|
||||
|
||||
# Platform specific options
|
||||
if COND_i386_pc
|
||||
CFLAGS_PLATFORM = -mrtd -mregparm=3
|
||||
CFLAGS_PLATFORM += -mrtd -mregparm=3
|
||||
endif
|
||||
if COND_i386_efi
|
||||
LDFLAGS_PLATFORM = -melf_i386
|
||||
|
@ -11,21 +13,24 @@ if COND_x86_64_efi
|
|||
LDFLAGS_PLATFORM = -melf_x86_64
|
||||
endif
|
||||
if COND_i386_qemu
|
||||
CFLAGS_PLATFORM = -mrtd -mregparm=3
|
||||
CFLAGS_PLATFORM += -mrtd -mregparm=3
|
||||
endif
|
||||
if COND_i386_coreboot
|
||||
CFLAGS_PLATFORM = -mrtd -mregparm=3
|
||||
CFLAGS_PLATFORM += -mrtd -mregparm=3
|
||||
endif
|
||||
if COND_i386_ieee1275
|
||||
CFLAGS_PLATFORM = -mrtd -mregparm=3
|
||||
CFLAGS_PLATFORM += -mrtd -mregparm=3
|
||||
endif
|
||||
if COND_mips_yeeloong
|
||||
CFLAGS_PLATFORM = -march=mips3 -mexplicit-relocs -mflush-func=grub_cpu_flush_cache
|
||||
CFLAGS_PLATFORM += -march=mips3 -mexplicit-relocs
|
||||
CPPFLAGS_PLATFORM = -DUSE_ASCII_FAILBACK
|
||||
CCASFLAGS_PLATFORM = -march=mips3
|
||||
endif
|
||||
if COND_mips
|
||||
CFLAGS_PLATFORM += -mflush-func=grub_cpu_flush_cache
|
||||
endif
|
||||
if COND_sparc64_ieee1275
|
||||
CFLAGS_PLATFORM = -mno-app-regs
|
||||
CFLAGS_PLATFORM += -mno-app-regs
|
||||
LDFLAGS_PLATFORM = -melf64_sparc -mno-relax
|
||||
endif
|
||||
|
||||
|
@ -75,28 +80,34 @@ platformdir = $(pkglibrootdir)/$(target_cpu)-$(platform)
|
|||
CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers
|
||||
CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap
|
||||
|
||||
CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -D_GL_UNUSED="__attribute__ ((unused))"
|
||||
CPPFLAGS_GNULIB = -I$(top_srcdir)/grub-core/gnulib
|
||||
CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused
|
||||
CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib
|
||||
|
||||
CFLAGS_POSIX = -fno-builtin
|
||||
CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap
|
||||
|
||||
CPPFLAGS_EFIEMU = -I$(top_srcdir)/grub-core/efiemu/runtime
|
||||
|
||||
# List file macros for recognizing /interesting/ modules
|
||||
CPPFLAGS_FS_LIST = -Dgrub_fs_register=FS_LIST_MARKER
|
||||
CPPFLAGS_VIDEO_LIST= -Dgrub_video_register=VIDEO_LIST_MARKER
|
||||
CPPFLAGS_PARTMAP_LIST = -Dgrub_partition_map_register=PARTMAP_LIST_MARKER
|
||||
CPPFLAGS_PARTTOOL_LIST = -Dgrub_parttool_register=PARTTOOL_LIST_MARKER
|
||||
CPPFLAGS_TERMINAL_LIST = '-Dgrub_term_register_input(...)=INPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)'
|
||||
CPPFLAGS_TERMINAL_LIST += '-Dgrub_term_register_output(...)=OUTPUT_TERMINAL_LIST_MARKER(__VA_ARGS__)'
|
||||
CPPFLAGS_COMMAND_LIST = '-Dgrub_register_command(...)=COMMAND_LIST_MARKER(__VA_ARGS__)'
|
||||
CPPFLAGS_COMMAND_LIST += '-Dgrub_register_extcmd(...)=EXTCOMMAND_LIST_MARKER(__VA_ARGS__)'
|
||||
CPPFLAGS_COMMAND_LIST += '-Dgrub_register_command_p1(...)=P1COMMAND_LIST_MARKER(__VA_ARGS__)'
|
||||
CPPFLAGS_MARKER = $(CPPFLAGS_FS_LIST) $(CPPFLAGS_VIDEO_LIST) \
|
||||
$(CPPFLAGS_PARTTOOL_LIST) $(CPPFLAGS_PARTMAP_LIST) \
|
||||
$(CPPFLAGS_TERMINAL_LIST) $(CPPFLAGS_COMMAND_LIST)
|
||||
|
||||
# Define these variables to calm down automake
|
||||
|
||||
FS_FILES =
|
||||
DEF_FILES =
|
||||
UND_FILES =
|
||||
IMG_FILES =
|
||||
MOD_FILES =
|
||||
VIDEO_FILES =
|
||||
MODULE_FILES =
|
||||
HANDLER_FILES =
|
||||
PARTMAP_FILES =
|
||||
COMMAND_FILES =
|
||||
PARTTOOL_FILES =
|
||||
TERMINAL_FILES =
|
||||
MARKER_FILES =
|
||||
KERNEL_HEADER_FILES =
|
||||
|
||||
man_MANS =
|
||||
|
@ -115,6 +126,7 @@ pkglib_SCRIPTS =
|
|||
noinst_PROGRAMS =
|
||||
grubconf_SCRIPTS =
|
||||
noinst_LIBRARIES =
|
||||
dist_noinst_DATA =
|
||||
|
||||
TESTS =
|
||||
EXTRA_DIST =
|
||||
|
|
|
@ -5,6 +5,11 @@ EXTRA_DIST += gentpl.py
|
|||
EXTRA_DIST += Makefile.tpl
|
||||
EXTRA_DIST += Makefile.util.def
|
||||
|
||||
EXTRA_DIST += unicode
|
||||
|
||||
EXTRA_DIST += util/import_gcry.py
|
||||
EXTRA_DIST += util/import_unicode.py
|
||||
|
||||
EXTRA_DIST += docs/man
|
||||
EXTRA_DIST += docs/grub.cfg
|
||||
|
||||
|
@ -14,20 +19,16 @@ EXTRA_DIST += grub-core/Makefile.core.def
|
|||
EXTRA_DIST += grub-core/Makefile.gcry.def
|
||||
|
||||
EXTRA_DIST += grub-core/genmoddep.awk
|
||||
EXTRA_DIST += grub-core/genmodsrc.sh
|
||||
EXTRA_DIST += grub-core/genfslist.sh
|
||||
EXTRA_DIST += grub-core/gencmdlist.sh
|
||||
EXTRA_DIST += grub-core/genmod.sh.in
|
||||
EXTRA_DIST += grub-core/gensyminfo.sh.in
|
||||
EXTRA_DIST += grub-core/gensymlist.sh
|
||||
EXTRA_DIST += grub-core/genemuinit.sh
|
||||
EXTRA_DIST += grub-core/genvideolist.sh
|
||||
EXTRA_DIST += grub-core/genhandlerlist.sh
|
||||
EXTRA_DIST += grub-core/genpartmaplist.sh
|
||||
EXTRA_DIST += grub-core/genterminallist.sh
|
||||
EXTRA_DIST += grub-core/genparttoollist.sh
|
||||
EXTRA_DIST += grub-core/genemuinitheader.sh
|
||||
|
||||
EXTRA_DIST += grub-core/lib/libgcrypt/cipher
|
||||
EXTRA_DIST += $(shell find $(top_srcdir)/include -name '*.h')
|
||||
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib -name '*.h')
|
||||
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/gnulib -name '*.h')
|
||||
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/efiemu -name '*.h')
|
||||
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib/posix_wrap -name '*.h')
|
||||
EXTRA_DIST += $(shell find $(top_srcdir)/grub-core/lib/libgcrypt_wrap -name '*.h')
|
||||
|
||||
EXTRA_DIST += m4/gnulib-cache.m4
|
||||
|
|
42
config.h.in
Normal file
42
config.h.in
Normal file
|
@ -0,0 +1,42 @@
|
|||
#if defined (GRUB_UTIL) || !defined (GRUB_MACHINE)
|
||||
#include <config-util.h>
|
||||
#define NESTED_FUNC_ATTR
|
||||
#else
|
||||
/* Define if C symbols get an underscore after compilation. */
|
||||
#define HAVE_ASM_USCORE @HAVE_ASM_USCORE@
|
||||
/* Define it to \"addr32\" or \"addr32;\" to make GAS happy. */
|
||||
#define ADDR32 @ADDR32@
|
||||
/* Define it to \"data32\" or \"data32;\" to make GAS happy. */
|
||||
#define DATA32 @DATA32@
|
||||
/* Define it to one of __bss_start, edata and _edata. */
|
||||
#define BSS_START_SYMBOL @BSS_START_SYMBOL@
|
||||
/* Define it to either end or _end. */
|
||||
#define END_SYMBOL @END_SYMBOL@
|
||||
/* Name of package. */
|
||||
#define PACKAGE "@PACKAGE@"
|
||||
/* Version number of package. */
|
||||
#define VERSION "@VERSION@"
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "@PACKAGE_STRING@"
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "@PACKAGE_VERSION@"
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "@PACKAGE_NAME@"
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"
|
||||
/* Default boot directory name" */
|
||||
#define GRUB_BOOT_DIR_NAME "@bootdirname@"
|
||||
/* Default grub directory name */
|
||||
#define GRUB_DIR_NAME "@grubdirname@"
|
||||
/* Define to 1 if GCC generates calls to __enable_execute_stack(). */
|
||||
#define NEED_ENABLE_EXECUTE_STACK @NEED_ENABLE_EXECUTE_STACK@
|
||||
/* Define to 1 if GCC generates calls to __register_frame_info(). */
|
||||
#define NEED_REGISTER_FRAME_INFO @NEED_REGISTER_FRAME_INFO@
|
||||
|
||||
#if defined(__i386__)
|
||||
#define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1)))
|
||||
#else
|
||||
#define NESTED_FUNC_ATTR
|
||||
#endif
|
||||
|
||||
#endif
|
138
configure.ac
138
configure.ac
|
@ -32,7 +32,9 @@ dnl type, so there is no conflict. Variables with the prefix "TARGET_"
|
|||
dnl (such as TARGET_CC, TARGET_CFLAGS, etc.) are used for the target
|
||||
dnl type.
|
||||
|
||||
AC_INIT([GRUB],[1.98],[bug-grub@gnu.org])
|
||||
AC_INIT([GRUB],[1.99~beta0],[bug-grub@gnu.org])
|
||||
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
|
||||
# We don't want -g -O2 by default in CFLAGS
|
||||
: ${CFLAGS=""}
|
||||
|
@ -44,7 +46,7 @@ AC_CANONICAL_TARGET
|
|||
AM_INIT_AUTOMAKE()
|
||||
AC_PREREQ(2.60)
|
||||
AC_CONFIG_SRCDIR([include/grub/dl.h])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
AC_CONFIG_HEADER([config-util.h])
|
||||
|
||||
# Program name transformations
|
||||
AC_ARG_PROGRAM
|
||||
|
@ -164,7 +166,7 @@ case "$target_cpu" in
|
|||
mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS=1" ;;
|
||||
sparc64) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_SPARC64=1" ;;
|
||||
esac
|
||||
machine_CPPFLAGS="$machine_CPPFLAGS -DMACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`"
|
||||
machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`"
|
||||
|
||||
HOST_CPPFLAGS="$HOST_CPPFLAGS $machine_CPPFLAGS"
|
||||
TARGET_CPPFLAGS="$TARGET_CPPFLAGS $machine_CPPFLAGS"
|
||||
|
@ -176,6 +178,23 @@ AC_SUBST(host_kernel)
|
|||
AC_SUBST(target_cpu)
|
||||
AC_SUBST(platform)
|
||||
|
||||
# Define default variables
|
||||
case "$host_os" in
|
||||
netbsd* | openbsd*)
|
||||
# Because /boot is used for the boot block in NetBSD and OpenBSD,
|
||||
bootdirname='' ;;
|
||||
*) bootdirname='boot' ;;
|
||||
esac
|
||||
bootdirname=`echo "$bootdirname" | sed "$program_transform_name"`
|
||||
AC_SUBST(bootdirname)
|
||||
AC_DEFINE_UNQUOTED(GRUB_BOOT_DIR_NAME, "$bootdirname",
|
||||
[Default boot directory name]")
|
||||
|
||||
grubdirname=`echo "$PACKAGE" | sed "$program_transform_name"`
|
||||
AC_SUBST(grubdirname)
|
||||
AC_DEFINE_UNQUOTED(GRUB_DIR_NAME, "$grubdirname",
|
||||
[Default grub directory name])
|
||||
|
||||
#
|
||||
# Checks for build programs.
|
||||
#
|
||||
|
@ -236,6 +255,7 @@ AC_PATH_PROG(MAKEINFO, makeinfo)
|
|||
#
|
||||
|
||||
AC_PROG_CC
|
||||
gl_EARLY
|
||||
AM_PROG_CC_C_O
|
||||
AM_PROG_AS
|
||||
|
||||
|
@ -264,8 +284,16 @@ else
|
|||
fi
|
||||
|
||||
# Check for functions and headers.
|
||||
AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf)
|
||||
AC_CHECK_HEADERS(libzfs.h libnvpair.h sys/param.h sys/mount.h)
|
||||
AC_CHECK_FUNCS(posix_memalign memalign asprintf vasprintf getextmntent)
|
||||
AC_CHECK_HEADERS(libzfs.h libnvpair.h sys/param.h sys/mount.h sys/mnttab.h sys/mkdev.h)
|
||||
|
||||
AC_CHECK_MEMBERS([struct statfs.f_fstypename],,,[$ac_includes_default
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>])
|
||||
|
||||
AC_CHECK_MEMBERS([struct statfs.f_mntfromname],,,[$ac_includes_default
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>])
|
||||
|
||||
# For opendisk() and getrawpartition() on NetBSD.
|
||||
# Used in util/deviceiter.c and in util/hostdisk.c.
|
||||
|
@ -288,6 +316,9 @@ HOST_CC=$CC
|
|||
AC_CHECK_PROGS(BUILD_CC, [gcc egcs cc],
|
||||
[AC_MSG_ERROR([none of gcc, egcs and cc is found. set BUILD_CC manually.])])
|
||||
|
||||
# For gnulib.
|
||||
gl_INIT
|
||||
|
||||
#
|
||||
# Check for target programs.
|
||||
#
|
||||
|
@ -410,10 +441,9 @@ AC_MSG_CHECKING([for command to convert module to ELF format])
|
|||
case "${host_os}" in
|
||||
cygwin) TARGET_OBJ2ELF='$(grub_utildir)/grub-pe2elf';
|
||||
# FIXME: put proper test here
|
||||
AC_DEFINE([NEED_REGISTER_FRAME_INFO], 1,
|
||||
[Define to 1 if GCC generates calls to __register_frame_info()])
|
||||
NEED_REGISTER_FRAME_INFO=1
|
||||
;;
|
||||
*) ;;
|
||||
*) NEED_REGISTER_FRAME_INFO=0 ;;
|
||||
esac
|
||||
AC_MSG_RESULT([$TARGET_OBJ2ELF])
|
||||
|
||||
|
@ -569,17 +599,8 @@ if test "x$target_cpu" = xi386; then
|
|||
CFLAGS="$TARGET_CFLAGS"
|
||||
grub_I386_ASM_PREFIX_REQUIREMENT
|
||||
grub_I386_ASM_ADDR32
|
||||
grub_I386_ASM_ABSOLUTE_WITHOUT_ASTERISK
|
||||
else
|
||||
AC_DEFINE([NESTED_FUNC_ATTR], [], [Catch gcc bug])
|
||||
fi
|
||||
|
||||
AH_BOTTOM([#if defined(__i386__) && !defined(GRUB_UTIL)
|
||||
#define NESTED_FUNC_ATTR __attribute__ ((__regparm__ (1)))
|
||||
#else
|
||||
#define NESTED_FUNC_ATTR
|
||||
#endif])
|
||||
|
||||
AC_ARG_ENABLE([efiemu],
|
||||
[AS_HELP_STRING([--enable-efiemu],
|
||||
[build and install the efiemu runtimes (default=guessed)])])
|
||||
|
@ -677,8 +698,8 @@ if test x"$missing_ncurses" = xtrue ; then
|
|||
AC_MSG_ERROR([grub-emu can't be compiled without ncurses])
|
||||
fi
|
||||
|
||||
if test x"$enable_grub_emu_usb" = xno ; then
|
||||
grub_emu_usb_excuse="explicitly disabled"
|
||||
if test x"$enable_grub_emu_usb" != xyes ; then
|
||||
grub_emu_usb_excuse="not enabled"
|
||||
fi
|
||||
|
||||
if test x"$enable_grub_emu_pci" = xyes ; then
|
||||
|
@ -762,19 +783,6 @@ AC_SUBST([enable_grub_emu_usb])
|
|||
AC_SUBST([enable_grub_emu_pci])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE([grub-fstest],
|
||||
[AS_HELP_STRING([--enable-grub-fstest],
|
||||
[build and install the `grub-fstest' debugging utility (default=guessed)])])
|
||||
if test x"$enable_grub_fstest" = xno ; then
|
||||
grub_fstest_excuse="explicitly disabled"
|
||||
fi
|
||||
if test x"$grub_fstest_excuse" = x ; then
|
||||
enable_grub_fstest=yes
|
||||
else
|
||||
enable_grub_fstest=no
|
||||
fi
|
||||
AC_SUBST([enable_grub_fstest])
|
||||
|
||||
AC_ARG_ENABLE([grub-mkfont],
|
||||
[AS_HELP_STRING([--enable-grub-mkfont],
|
||||
[build and install the `grub-mkfont' utility (default=guessed)])])
|
||||
|
@ -788,12 +796,12 @@ if test x"$grub_mkfont_excuse" = x ; then
|
|||
if test "x$FREETYPE" = x ; then
|
||||
grub_mkfont_excuse=["need freetype2 library"]
|
||||
fi
|
||||
freetype_cflags=`freetype-config --cflags`
|
||||
freetype_libs=`freetype-config --libs`
|
||||
fi
|
||||
|
||||
if test x"$grub_mkfont_excuse" = x ; then
|
||||
# Check for freetype libraries.
|
||||
freetype_cflags=`freetype-config --cflags`
|
||||
freetype_libs=`freetype-config --libs`
|
||||
SAVED_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $freetype_cflags"
|
||||
AC_CHECK_HEADERS([ft2build.h], [],
|
||||
|
@ -822,12 +830,23 @@ fi
|
|||
|
||||
if test x"$device_mapper_excuse" = x ; then
|
||||
# Check for device-mapper library.
|
||||
AC_CHECK_LIB([devmapper], [dm_task_create],
|
||||
[LIBDEVMAPPER="-ldevmapper"
|
||||
AC_DEFINE([HAVE_DEVICE_MAPPER], [1],
|
||||
[Define to 1 if you have the devmapper library.])],
|
||||
AC_CHECK_LIB([devmapper], [dm_task_create], [],
|
||||
[device_mapper_excuse="need devmapper library"])
|
||||
fi
|
||||
|
||||
if test x"$device_mapper_excuse" = x ; then
|
||||
# Check for device-mapper library.
|
||||
AC_CHECK_LIB([devmapper], [dm_log_with_errno_init],
|
||||
[],
|
||||
[device_mapper_excuse="need devmapper library"])
|
||||
fi
|
||||
|
||||
if test x"$device_mapper_excuse" = x ; then
|
||||
LIBDEVMAPPER="-ldevmapper";
|
||||
AC_DEFINE([HAVE_DEVICE_MAPPER], [1],
|
||||
[Define to 1 if you have the devmapper library.])
|
||||
fi
|
||||
|
||||
AC_SUBST([LIBDEVMAPPER])
|
||||
|
||||
AC_CHECK_LIB([zfs], [libzfs_init],
|
||||
|
@ -842,27 +861,27 @@ AC_CHECK_LIB([nvpair], [nvlist_print],
|
|||
[Define to 1 if you have the NVPAIR library.])],)
|
||||
AC_SUBST([LIBNVPAIR])
|
||||
|
||||
LIBS=""
|
||||
|
||||
pkglibrootdir='$(libdir)'/`echo $PACKAGE | sed "$program_transform_name"`
|
||||
AC_SUBST(pkglibrootdir)
|
||||
|
||||
AC_SUBST([FONT_SOURCE])
|
||||
AS_IF([test x$target_cpu = xi386 -a x$platform = xpc],
|
||||
[AC_SUBST([GRUB_KERNEL_MACHINE_LINK_ADDR], 0x8200)])
|
||||
AS_IF([test x$target_cpu = xi386 -a x$platform = xcoreboot],
|
||||
[AC_SUBST([GRUB_KERNEL_MACHINE_LINK_ADDR], 0x8200)])
|
||||
AS_IF([test x$target_cpu = xi386 -a x$platform = xmultiboot],
|
||||
[AC_SUBST([GRUB_KERNEL_MACHINE_LINK_ADDR], 0x8200)])
|
||||
AS_IF([test x$target_cpu = xmips -a x$platform = xyeeloong],
|
||||
[AC_SUBST([GRUB_KERNEL_MACHINE_LINK_ADDR], 0x80200000)])
|
||||
AS_IF([test x$target_cpu = xpowerpc -a x$platform = xieee1275],
|
||||
[AC_SUBST([GRUB_KERNEL_MACHINE_LINK_ADDR], 0x200000)])
|
||||
AS_IF([test x$target_cpu = xi386 -a x$platform = xqemu],
|
||||
[AC_SUBST([GRUB_BOOT_MACHINE_LINK_ADDR], 0xffe00)])
|
||||
AS_IF([test x$target_cpu = xi386 -a x$platform = xieee1275],
|
||||
[AC_SUBST([GRUB_KERNEL_MACHINE_LINK_ADDR], 0x10000)])
|
||||
AS_IF([test x$TARGET_APPLE_CC = x1],
|
||||
[AC_SUBST([USE_APPLE_CC_FIXES], yes)])
|
||||
|
||||
AC_SUBST(HAVE_ASM_USCORE)
|
||||
AC_SUBST(ADDR32)
|
||||
AC_SUBST(DATA32)
|
||||
AC_SUBST(BSS_START_SYMBOL)
|
||||
AC_SUBST(END_SYMBOL)
|
||||
AC_SUBST(PACKAGE)
|
||||
AC_SUBST(VERSION)
|
||||
AC_SUBST(NEED_ENABLE_EXECUTE_STACK)
|
||||
AC_SUBST(NEED_REGISTER_FRAME_INFO)
|
||||
|
||||
#
|
||||
# Automake conditionals
|
||||
#
|
||||
|
@ -879,6 +898,7 @@ AM_CONDITIONAL([COND_mips_yeeloong], [test x$target_cpu = xmips -a x$platform =
|
|||
AM_CONDITIONAL([COND_mips_qemu_mips], [test x$target_cpu = xmips -a x$platform = xqemu_mips])
|
||||
AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275])
|
||||
AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275])
|
||||
AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips])
|
||||
|
||||
AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd])
|
||||
AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux])
|
||||
|
@ -892,11 +912,12 @@ AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes])
|
|||
AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes])
|
||||
AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes])
|
||||
AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x])
|
||||
AM_CONDITIONAL([COND_GRUB_FSTEST], [test x$enable_grub_fstest = xyes])
|
||||
AM_CONDITIONAL([COND_GRUB_PE2ELF], [test x$TARGET_OBJ2ELF != x])
|
||||
AM_CONDITIONAL([COND_APPLE_CC], [test x$TARGET_APPLE_CC = x1])
|
||||
AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes])
|
||||
|
||||
AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1])
|
||||
|
||||
# Output files.
|
||||
grub_CHECK_LINK_DIR
|
||||
if test x"$link_dir" = xyes ; then
|
||||
|
@ -916,9 +937,12 @@ fi
|
|||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_CONFIG_FILES([grub-core/Makefile])
|
||||
AC_CONFIG_FILES([po/Makefile])
|
||||
AC_CONFIG_FILES([grub-core/gnulib/Makefile])
|
||||
AC_CONFIG_FILES([po/Makefile.in])
|
||||
AC_CONFIG_FILES([docs/Makefile])
|
||||
AC_CONFIG_FILES([util/bash-completion.d/Makefile])
|
||||
AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h])
|
||||
AC_CONFIG_FILES([config.h])
|
||||
|
||||
AC_OUTPUT
|
||||
[
|
||||
|
@ -942,6 +966,11 @@ else
|
|||
echo PCI support for grub-emu: No "($grub_emu_pci_excuse)"
|
||||
fi
|
||||
fi
|
||||
if test x"$device_mapper_excuse" = x ; then
|
||||
echo With devmapper support: Yes
|
||||
else
|
||||
echo With devmapper support: No "($device_mapper_excuse)"
|
||||
fi
|
||||
if [ x"$enable_mm_debug" = xyes ]; then
|
||||
echo With memory debugging: Yes
|
||||
else
|
||||
|
@ -952,11 +981,6 @@ echo efiemu runtime: Yes
|
|||
else
|
||||
echo efiemu runtime: No "($efiemu_excuse)"
|
||||
fi
|
||||
if [ x"$grub_fstest_excuse" = x ]; then
|
||||
echo grub-fstest: Yes
|
||||
else
|
||||
echo grub-fstest: No "($grub_fstest_excuse)"
|
||||
fi
|
||||
if [ x"$grub_mkfont_excuse" = x ]; then
|
||||
echo grub-mkfont: Yes
|
||||
else
|
||||
|
|
441
docs/grub.texi
441
docs/grub.texi
|
@ -47,6 +47,7 @@ Invariant Sections.
|
|||
@author Gordon Matzigkeit
|
||||
@author Yoshinori K. Okuji
|
||||
@author Colin Watson
|
||||
@author Colin D. Bennett
|
||||
@c The following two commands start the copyright page.
|
||||
@page
|
||||
@vskip 0pt plus 1filll
|
||||
|
@ -78,6 +79,7 @@ This edition documents version @value{VERSION}.
|
|||
* Installation:: Installing GRUB on your drive
|
||||
* Booting:: How to boot different operating systems
|
||||
* Configuration:: Writing your own configuration file
|
||||
* Theme file format:: Format of GRUB theme files
|
||||
* Network:: Downloading OS images from a network
|
||||
* Serial terminal:: Using GRUB via a serial line
|
||||
* Vendor power-on keys:: Changing GRUB behaviour on vendor power-on keys
|
||||
|
@ -965,7 +967,6 @@ need to write the whole thing by hand.
|
|||
* Simple configuration:: Recommended for most users
|
||||
* Shell-like scripting:: For power users and developers
|
||||
* Embedded configuration:: Embedding a configuration file into GRUB
|
||||
* Themes:: Graphical menu themes
|
||||
@end menu
|
||||
|
||||
|
||||
|
@ -1127,7 +1128,6 @@ The image will be scaled if necessary to fit the screen.
|
|||
|
||||
@item GRUB_THEME
|
||||
Set a theme for use with the @samp{gfxterm} graphical terminal.
|
||||
@xref{Themes}.
|
||||
|
||||
@item GRUB_GFXPAYLOAD_LINUX
|
||||
Set to @samp{text} to force the Linux kernel to boot in normal text mode,
|
||||
|
@ -1227,8 +1227,10 @@ The @samp{$} character retains its special meaning within double quotes.
|
|||
The backslash retains its special meaning only when followed by one of the
|
||||
following characters: @samp{$}, @samp{"}, @samp{\}, or newline. A
|
||||
backslash-newline pair is treated as a line continuation (that is, it is
|
||||
removed from the input stream and effectively ignored). A double quote may
|
||||
be quoted within double quotes by preceding it with a backslash.
|
||||
removed from the input stream and effectively ignored@footnote{Currently a
|
||||
backslash-newline pair within a variable name is not handled properly, so
|
||||
use this feature with some care.}). A double quote may be quoted within
|
||||
double quotes by preceding it with a backslash.
|
||||
|
||||
@heading Variable expansion
|
||||
|
||||
|
@ -1240,11 +1242,15 @@ which could be interpreted as part of the name.
|
|||
Normal variable names begin with an alphabetic character, followed by zero
|
||||
or more alphanumeric characters.
|
||||
|
||||
Positional variable names consist of one or more digits. These are reserved
|
||||
for future expansion.
|
||||
Positional variable names consist of one or more digits. They represent
|
||||
parameters passed to function calls, with @samp{$1} representing the first
|
||||
parameter, and so on.
|
||||
|
||||
The special variable name @samp{?} expands to the exit status of the most
|
||||
recently executed command.
|
||||
recently executed command. When positional variable names are active, other
|
||||
special variable names @samp{@@}, @samp{*} and @samp{#} are defined and they
|
||||
expand to all positional parameters with necessary quoting, positional
|
||||
parameters without any quoting, and positional parameter count respectively.
|
||||
|
||||
@heading Comments
|
||||
|
||||
|
@ -1258,7 +1264,9 @@ and terminated by a semicolon or a newline. The first word specifies the
|
|||
command to be executed. The remaining words are passed as arguments to the
|
||||
invoked command.
|
||||
|
||||
The return value of a simple command is its exit status.
|
||||
The return value of a simple command is its exit status. If the reserved
|
||||
word @code{!} precedes the command, then the return value is instead the
|
||||
logical negation of the command's exit status.
|
||||
|
||||
@heading Compound commands
|
||||
|
||||
|
@ -1305,6 +1313,45 @@ the body.
|
|||
@xref{menuentry}.
|
||||
@end table
|
||||
|
||||
@heading Built-in Commands
|
||||
|
||||
Some built-in commands are also provided by GRUB script to help script
|
||||
writers perform actions that are otherwise not possible. For example, these
|
||||
include commands to jump out of a loop without fully completing it, etc.
|
||||
|
||||
@table @asis
|
||||
@item break [@code{n}]
|
||||
Exit from within a @code{for}, @code{while}, or @code{until} loop. If
|
||||
@code{n} is specified, break @code{n} levels. @code{n} must be greater than
|
||||
or equal to 1. If @code{n} is greater than the number of enclosing loops,
|
||||
all enclosing loops are exited. The return value is 0 unless @code{n} is
|
||||
not greater than or equal to 1.
|
||||
|
||||
@item continue [@code{n}]
|
||||
Resume the next iteration of the enclosing @code{for}, @code{while} or
|
||||
@code{until} loop. If @code{n} is specified, resume at the @code{n}th
|
||||
enclosing loop. @code{n} must be greater than or equal to 1. If @code{n}
|
||||
is greater than the number of enclosing loops, the last enclosing loop (the
|
||||
@dfn{top-level} loop) is resumed. The return value is 0 unless @code{n} is
|
||||
not greater than or equal to 1.
|
||||
|
||||
@item return [@code{n}]
|
||||
Causes a function to exit with the return value specified by @code{n}. If
|
||||
@code{n} is omitted, the return status is that of the last command executed
|
||||
in the function body. If used outside a function the return status is
|
||||
false.
|
||||
|
||||
@item shift [@code{n}]
|
||||
The positional parameters from @code{n}+1 @dots{} are renamed to
|
||||
@code{$1}@dots{}. Parameters represented by the numbers @code{$#} down to
|
||||
@code{$#}-@code{n}+1 are unset. @code{n} must be a non-negative number less
|
||||
than or equal to @code{$#}. If @code{n} is 0, no parameters are changed.
|
||||
If @code{n} is not given, it is assumed to be 1. If @code{n} is greater
|
||||
than @code{$#}, the positional parameters are not changed. The return
|
||||
status is greater than zero if @code{n} is greater than @code{$#} or less
|
||||
than zero; otherwise 0.
|
||||
|
||||
@end table
|
||||
|
||||
@node Embedded configuration
|
||||
@section Embedding a configuration file into GRUB
|
||||
|
@ -1373,9 +1420,372 @@ fi
|
|||
The embedded configuration file may not contain menu entries directly, but
|
||||
may only read them from elsewhere using @command{configfile}.
|
||||
|
||||
@node Theme file format
|
||||
@chapter Theme file format
|
||||
@section Introduction
|
||||
The GRUB graphical menu supports themes that can customize the layout and
|
||||
appearance of the GRUB boot menu. The theme is configured through a plain
|
||||
text file that specifies the layout of the various GUI components (including
|
||||
the boot menu, timeout progress bar, and text messages) as well as the
|
||||
appearance using colors, fonts, and images. Example is available in docs/example_theme.txt
|
||||
|
||||
@section Theme Elements
|
||||
@subsection Colors
|
||||
|
||||
Colors can be specified in several ways:
|
||||
|
||||
@itemize
|
||||
@item HTML-style ``#RRGGBB'' or ``#RGB'' format, where *R*, *G*, and *B* are hexadecimal digits (e.g., ``#8899FF'')
|
||||
@item as comma-separated decimal RGB values (e.g., ``128, 128, 255'')
|
||||
@item with ``SVG 1.0 color names'' (e.g., ``cornflowerblue'') which must be specified in lowercase.
|
||||
@end itemize
|
||||
@subsection Fonts
|
||||
The fonts GRUB uses ``PFF2 font format'' bitmap fonts. Fonts are specified
|
||||
with full font names. Currently there is no
|
||||
provision for a preference list of fonts, or deriving one font from another.
|
||||
Fonts are loaded with the ``loadfont'' command in GRUB. To see the list of
|
||||
loaded fonts, execute the ``lsfonts'' command. If there are too many fonts to
|
||||
fit on screen, do ``set pager=1'' before executing ``lsfonts''.
|
||||
|
||||
|
||||
@subsection Progress Bar
|
||||
|
||||
@float Figure, Pixmap-styled progress bar
|
||||
@c @image{Theme_progress_bar,,,,.png}
|
||||
@end float
|
||||
|
||||
@float Figure, Plain progress bar, drawn with solid color.
|
||||
@c @image{Theme_progress_bar_filled,,,,.png}
|
||||
@end float
|
||||
|
||||
Progress bars are used to display the remaining time before GRUB boots the
|
||||
default menu entry. To create a progress bar that will display the remaining
|
||||
time before automatic boot, simply create a ``progress_bar'' component with
|
||||
the id ``__timeout__''. This indicates to GRUB that the progress bar should
|
||||
be updated as time passes, and it should be made invisible if the countdown to
|
||||
automatic boot is interrupted by the user.
|
||||
|
||||
Progress bars may optionally have text displayed on them. This is controlled
|
||||
through the ``show_text'' property, which can be set to either ``true'' or
|
||||
``false'' to control whether text is displayed. When GRUB is counting down to
|
||||
automatic boot, the text informs the user of the number of seconds remaining.
|
||||
|
||||
|
||||
@subsection Circular Progress Indicator
|
||||
|
||||
@c @image{Theme_circular_progress,,,,.png}
|
||||
|
||||
The circular progress indicator functions similarly to the progress bar. When
|
||||
given an id of ``__timeout__'', GRUB updates the circular progress indicator's
|
||||
value to indicate the time remaining. For the circular progress indicator,
|
||||
there are two images used to render it: the *center* image, and the *tick*
|
||||
image. The center image is rendered in the center of the component, while the
|
||||
tick image is used to render each mark along the circumference of the
|
||||
indicator.
|
||||
|
||||
|
||||
@subsection Labels
|
||||
|
||||
Text labels can be placed on the boot screen. The font, color, and horizontal
|
||||
alignment can be specified for labels. If a label is given the id
|
||||
``__timeout__'', then the ``text'' property for that label is also updated
|
||||
with a message informing the user of the number of seconds remaining until
|
||||
automatic boot. This is useful in case you want the text displayed somewhere
|
||||
else instead of directly on the progress bar.
|
||||
|
||||
|
||||
@subsection Boot Menu
|
||||
|
||||
@c @image{Theme_boot_menu,,,,.png}
|
||||
|
||||
The boot menu where GRUB displays the menu entries from the ``grub.cfg'' file.
|
||||
It is a list of items, where each item has a title and an optional icon. The
|
||||
icon is selected based on the *classes* specified for the menu entry. If
|
||||
there is a PNG file named ``myclass.png'' in the ``grub/themes/icons''
|
||||
directory, it will be displayed for items which have the class *myclass*. The
|
||||
boot menu can be customized in several ways, such as the font and color used
|
||||
for the menu entry title, and by specifying styled boxes for the menu itself
|
||||
and for the selected item highlight.
|
||||
|
||||
|
||||
@subsection Styled Boxes
|
||||
|
||||
One of the most important features for customizing the layout is the use of
|
||||
*styled boxes*. A styled box is composed of 9 rectangular (and potentially
|
||||
empty) regions, which are used to seamlessly draw the styled box on screen:
|
||||
|
||||
@multitable @columnfractions 0.3 0.3 0.3
|
||||
@item Northwest (nw) @tab North (n) @tab Northeast (ne)
|
||||
@item West (w) @tab Center (c) @tab East (e)
|
||||
@item Southwest (sw) @tab South (s) @tab Southeast (se)
|
||||
@end multitable
|
||||
|
||||
To support any size of box on screen, the center slice and the slices for the
|
||||
top, bottom, and sides are all scaled to the correct size for the component on
|
||||
screen, using the following rules:
|
||||
|
||||
@enumerate
|
||||
@item The edge slices (north, south, east, and west) are scaled in the direction of the edge they are adjacent to. For instance, the west slice is scaled vertically.
|
||||
@item The corner slices (northwest, northeast, southeast, and southwest) are not scaled.
|
||||
@item The center slice is scaled to fill the remaining space in the middle.
|
||||
@end enumerate
|
||||
|
||||
As an example of how an image might be sliced up, consider the styled box
|
||||
used for a terminal view.
|
||||
|
||||
@float Figure, An example of the slices (in red) used for a terminal window. This drawing was created and sliced in Inkscape_, as the next section explains.
|
||||
@c @image{Box_slice_example_terminal,,,,.png}
|
||||
@end float
|
||||
|
||||
@subsection Creating Styled Box Images
|
||||
|
||||
The Inkscape_ scalable vector graphics editor is a very useful tool for
|
||||
creating styled box images. One process that works well for slicing a drawing
|
||||
into the necessary image slices is:
|
||||
|
||||
@enumerate
|
||||
@item Create or open the drawing you'd like use.
|
||||
@item Create a new layer on the top of the layer stack. Make it visible. Select this layer as the current layer.
|
||||
@item Draw 9 rectangles on your drawing where you'd like the slices to be. Clear the fill option, and set the stroke to 1 pixel wide solid stroke. The corners of the slices must meet precisely; if it is off by a single pixel, it will probably be evident when the styled box is rendered in the GRUB menu. You should probably go to File | Document Properties | Grids and enable a grid or create a guide (click on one of the rulers next to the drawing and drag over the drawing; release the mouse button to place the guide) to help place the rectangles precisely.
|
||||
@item Right click on the center slice rectangle and choose Object Properties. Change the "Id" to ``slice_c`` and click Set. Repeat this for the remaining 8 rectangles, giving them Id values of ``slice_n``, ``slice_ne``, ``slice_e``, and so on according to the location.
|
||||
@item Save the drawing.
|
||||
@item Select all the slice rectangles. With the slice layer selected, you can simply press Ctrl+A to select all rectangles. The status bar should indicate that 9 rectangles are selected.
|
||||
@item Click the layer hide icon for the slice layer in the layer palette. The rectangles will remain selected, even though they are hidden.
|
||||
@item Choose File | Export Bitmap and check the *Batch export 9 selected objects* box. Make sure that *Hide all except selected* is unchecked. click *Export*. This will create PNG files in the same directory as the drawing, named after the slices. These can now be used for a styled box in a GRUB theme.
|
||||
@end enumerate
|
||||
|
||||
@section Theme File Manual
|
||||
|
||||
The theme file is a plain text file. Lines that begin with ``#`` are ignored
|
||||
and considered comments. (Note: This may not be the case if the previous line
|
||||
ended where a value was expected.)
|
||||
|
||||
The theme file contains two types of statements:
|
||||
@enumerate
|
||||
@item Global properties.
|
||||
@item Component construction.
|
||||
@end enumerate
|
||||
|
||||
@subsection Global Properties
|
||||
|
||||
@subsection Format
|
||||
|
||||
Global properties are specified with the simple format:
|
||||
@itemize
|
||||
@item name1: value1
|
||||
@item name2: "value which may contain spaces"
|
||||
@item name3: #88F
|
||||
@end itemize
|
||||
|
||||
In this example, name3 is assigned a color value.
|
||||
|
||||
|
||||
@subsection Global Property List
|
||||
|
||||
@multitable @columnfractions 0.3 0.6
|
||||
@item title-text @tab Specifies the text to display at the top center of the screen as a title.
|
||||
@item title-font @tab Defines the font used for the title message at the top of the screen.
|
||||
@item title-color @tab Defines the color of the title message.
|
||||
@item message-font @tab Defines the font used for messages, such as when GRUB is unable to automatically boot an entry.
|
||||
@item message-color @tab Defines the color of the message text.
|
||||
@item message-bg-color @tab Defines the background color of the message text area.
|
||||
@item desktop-image @tab Specifies the image to use as the background. It will be scaled to fit the screen size.
|
||||
@item desktop-color @tab Specifies the color for the background if *desktop-image* is not specified.
|
||||
@item terminal-box @tab Specifies the file name pattern for the styled box slices used for the command line terminal window. For example, ``terminal-box: terminal_*.png'' will use the images ``terminal_c.png`` as the center area, ``terminal_n.png`` as the north (top) edge, ``terminal_nw.png`` as the northwest (upper left) corner, and so on. If the image for any slice is not found, it will simply be left empty.
|
||||
@end multitable
|
||||
|
||||
|
||||
@subsection Component Construction
|
||||
|
||||
Greater customizability comes is provided by components. A tree of components
|
||||
forms the user interface. *Containers* are components that can contain other
|
||||
components, and there is always a single root component which is an instance
|
||||
of a *canvas* container.
|
||||
|
||||
Components are created in the theme file by prefixing the type of component
|
||||
with a '+' sign:
|
||||
|
||||
@code{ + label @{ text="GRUB" font="aqui 11" color="#8FF" @} }
|
||||
|
||||
properties of a component are specified as "name = value" (whitespace
|
||||
surrounding tokens is optional and is ignored) where *value* may be:
|
||||
@itemize
|
||||
@item a single word (e.g., ``align = center``, ``color = #FF8080``),
|
||||
@item a quoted string (e.g., ``text = "Hello, World!"``), or
|
||||
@item a tuple (e.g., ``preferred_size = (120, 80)``).
|
||||
@end itemize
|
||||
|
||||
@subsection Component List
|
||||
|
||||
The following is a list of the components and the properties they support.
|
||||
|
||||
@itemize
|
||||
@item label
|
||||
A label displays a line of text.
|
||||
|
||||
Properties:
|
||||
@multitable @columnfractions 0.2 0.7
|
||||
@item text @tab The text to display.
|
||||
@item font @tab The font to use for text display.
|
||||
@item color @tab The color of the text.
|
||||
@item align @tab The horizontal alignment of the text within the component. Options are ``left``, ``center``, and ``right``.
|
||||
@end multitable
|
||||
|
||||
@item image
|
||||
A component that displays an image. The image is scaled to fit the
|
||||
component, although the preferred size defaults to the image's original
|
||||
size unless the ``preferred_size`` property is explicitly set.
|
||||
|
||||
Properties:
|
||||
|
||||
@multitable @columnfractions 0.2 0.7
|
||||
@item file @tab The full path to the image file to load.
|
||||
@end multitable
|
||||
|
||||
@item progress_bar
|
||||
Displays a horizontally oriented progress bar. It can be rendered using
|
||||
simple solid filled rectangles, or using a pair of pixmap styled boxes.
|
||||
|
||||
Properties:
|
||||
|
||||
@multitable @columnfractions 0.2 0.7
|
||||
@item fg_color @tab The foreground color for plain solid color rendering.
|
||||
@item bg_color @tab The background color for plain solid color rendering.
|
||||
@item border_color @tab The border color for plain solid color rendering.
|
||||
@item text_color @tab The text color.
|
||||
@item show_text @tab Boolean value indicating whether or not text should be displayed on the progress bar. If set to *false*, then no text will be displayed on the bar. If set to any other value, text will be displayed on the bar.
|
||||
@item bar_style @tab The styled box specification for the frame of the progress bar. Example: ``progress_frame_*.png``
|
||||
@item highlight_style @tab The styled box specification for the highlighted region of the progress bar. This box will be used to paint just the highlighted region of the bar, and will be increased in size as the bar nears completion. Example: ``progress_hl_*.png``.
|
||||
@item text @tab The text to display on the progress bar. If the progress bar's ID is set to ``__timeout__``, then GRUB will updated this property with an informative message as the timeout approaches.
|
||||
@item value @tab The progress bar current value. Normally not set manually.
|
||||
@item start @tab The progress bar start value. Normally not set manually.
|
||||
@item end @tab The progress bar end value. Normally not set manually.
|
||||
@end multitable
|
||||
|
||||
@item circular_progress
|
||||
Displays a circular progress indicator. The appearance of this component
|
||||
is determined by two images: the *center* image and the *tick* image. The
|
||||
center image is generally larger and will be drawn in the center of the
|
||||
component. Around the circumference of a circle within the component, the
|
||||
tick image will be drawn a certain number of times, depending on the
|
||||
properties of the component.
|
||||
|
||||
Properties:
|
||||
|
||||
@multitable @columnfractions 0.3 0.6
|
||||
@item center_bitmap
|
||||
@tab The file name of the image to draw in the center of the component.
|
||||
@item tick_bitmap
|
||||
@tab The file name of the image to draw for the tick marks.
|
||||
@item num_ticks
|
||||
@tab The number of ticks that make up a full circle.
|
||||
@item ticks_disappear
|
||||
@tab Boolean value indicating whether tick marks should progressively appear,
|
||||
or progressively disappear as *value* approaches *end*. Specify
|
||||
``true`` or ``false``.
|
||||
@item value
|
||||
@tab The progress indicator current value. Normally not set manually.
|
||||
@item start
|
||||
@tab The progress indicator start value. Normally not set manually.
|
||||
@item end
|
||||
@tab The progress indicator end value. Normally not set manually.
|
||||
@end multitable
|
||||
@item boot_menu
|
||||
Displays the GRUB boot menu. It allows selecting items and executing them.
|
||||
|
||||
Properties:
|
||||
|
||||
@multitable @columnfractions 0.4 0.5
|
||||
@item item_font
|
||||
@tab The font to use for the menu item titles.
|
||||
@item selected_item_font
|
||||
@tab The font to use for the selected menu item, or ``inherit`` (the default)
|
||||
to use ``item_font`` for the selected menu item as well.
|
||||
@item item_color
|
||||
@tab The color to use for the menu item titles.
|
||||
@item selected_item_color
|
||||
@tab The color to use for the selected menu item, or ``inherit`` (the default)
|
||||
to use ``item_color`` for the selected menu item as well.
|
||||
@item icon_width
|
||||
@tab The width of menu item icons. Icons are scaled to the specified size.
|
||||
@item icon_height
|
||||
@tab The height of menu item icons.
|
||||
@item item_height
|
||||
@tab The height of each menu item in pixels.
|
||||
@item item_padding
|
||||
@tab The amount of space in pixels to leave on each side of the menu item
|
||||
contents.
|
||||
@item item_icon_space
|
||||
@tab The space between an item's icon and the title text, in pixels.
|
||||
@item item_spacing
|
||||
@tab The amount of space to leave between menu items, in pixels.
|
||||
@item menu_pixmap_style
|
||||
@tab The image file pattern for the menu frame styled box.
|
||||
Example: ``menu_*.png`` (this will use images such as ``menu_c.png``,
|
||||
``menu_w.png``, `menu_nw.png``, etc.)
|
||||
@item selected_item_pixmap_style
|
||||
@tab The image file pattern for the selected item highlight styled box.
|
||||
@item scrollbar
|
||||
@tab Boolean value indicating whether the scroll bar should be drawn if the
|
||||
frame and thumb styled boxes are configured.
|
||||
@item scrollbar_frame
|
||||
@tab The image file pattern for the entire scroll bar.
|
||||
Example: ``scrollbar_*.png``
|
||||
@item scrollbar_thumb
|
||||
@tab The image file pattern for the scroll bar thumb (the part of the scroll
|
||||
bar that moves as scrolling occurs).
|
||||
Example: ``scrollbar_thumb_*.png``
|
||||
@item max_items_shown
|
||||
@tab The maximum number of items to show on the menu. If there are more than
|
||||
*max_items_shown* items in the menu, the list will scroll to make all
|
||||
items accessible.
|
||||
@end multitable
|
||||
|
||||
@item canvas
|
||||
Canvas is a container that allows manual placement of components within it.
|
||||
It does not alter the positions of its child components. It assigns all
|
||||
child components their preferred sizes.
|
||||
|
||||
@item hbox
|
||||
The *hbox* container lays out its children from left to right, giving each
|
||||
one its preferred width. The height of each child is set to the maximum of
|
||||
the preferred heights of all children.
|
||||
|
||||
@item vbox
|
||||
The *vbox* container lays out its children from top to bottom, giving each
|
||||
one its preferred height. The width of each child is set to the maximum of
|
||||
the preferred widths of all children.
|
||||
@end itemize
|
||||
|
||||
|
||||
@subsection Common properties
|
||||
|
||||
The following properties are supported by all components:
|
||||
@table @samp
|
||||
@item left
|
||||
The distance from the left border of container to left border of the object in either of three formats:
|
||||
@multitable @columnfractions 0.2 0.7
|
||||
@item x @tab Value in pixels
|
||||
@item p% @tab Percentage
|
||||
@item p%+x @tab mixture of both
|
||||
@end multitable
|
||||
@item top
|
||||
The distance from the left border of container to left border of the object in same format.
|
||||
@item width
|
||||
The width of object in same format.
|
||||
@item height
|
||||
The height of object in same format.
|
||||
@item id
|
||||
The identifier for the component. This can be any arbitrary string.
|
||||
The ID can be used by scripts to refer to various components in the GUI
|
||||
component tree. Currently, there is one special ID value that GRUB
|
||||
recognizes:
|
||||
|
||||
@multitable @columnfractions 0.2 0.7
|
||||
@item ``__timeout__`` @tab Any component with this ID will have its *text*, *start*, *end*, *value*, and *visible* properties set by GRUB when it is counting down to an automatic boot of the default menu entry.
|
||||
@end multitable
|
||||
@end table
|
||||
|
||||
@node Themes
|
||||
@section Graphical menu themes
|
||||
|
||||
|
||||
@node Network
|
||||
|
@ -1388,8 +1798,7 @@ To generate a PXE boot image, run:
|
|||
|
||||
@example
|
||||
@group
|
||||
grub-mkimage --format=i386-pc --output=core.img --prefix='(pxe)/boot/grub' pxe pxecmd
|
||||
cat /boot/grub/pxeboot.img core.img >grub.pxe
|
||||
grub-mkimage --format=i386-pc-pxe --output=grub.pxe --prefix='(pxe)/boot/grub' pxe pxecmd
|
||||
@end group
|
||||
@end example
|
||||
|
||||
|
@ -1399,6 +1808,9 @@ accessible via the @file{/boot/grub/} path from the TFTP server root. Set
|
|||
the DHCP server configuration to offer @file{grub.pxe} as the boot file (the
|
||||
@samp{filename} option in ISC dhcpd).
|
||||
|
||||
You can also use the @command{grub-mknetdir} utility to generate an image
|
||||
and a GRUB directory tree, rather than copying files around manually.
|
||||
|
||||
After GRUB has started, files on the TFTP server will be accessible via the
|
||||
@samp{(pxe)} device.
|
||||
|
||||
|
@ -2007,8 +2419,7 @@ The serial port is not used as a communication channel unless the
|
|||
@command{terminal_input} or @command{terminal_output} command is used
|
||||
(@pxref{terminal_input}, @pxref{terminal_output}).
|
||||
|
||||
This command is only available if GRUB is compiled with serial
|
||||
support. See also @ref{Serial terminal}.
|
||||
See also @ref{Serial terminal}.
|
||||
@end deffn
|
||||
|
||||
|
||||
|
@ -2499,7 +2910,7 @@ This command is only available on x86 systems.
|
|||
@node ls
|
||||
@subsection ls
|
||||
|
||||
@deffn Command ls [arg]
|
||||
@deffn Command ls [arg @dots{}]
|
||||
List devices or files.
|
||||
|
||||
With no arguments, print all devices known to GRUB.
|
||||
|
|
3
docs/man/grub-menulst2cfg.h2m
Normal file
3
docs/man/grub-menulst2cfg.h2m
Normal file
|
@ -0,0 +1,3 @@
|
|||
[NAME]
|
||||
grub-menulst2cfg \- transform legacy menu.lst into grub.cfg
|
||||
|
2
docs/man/grub-mklayout.h2m
Normal file
2
docs/man/grub-mklayout.h2m
Normal file
|
@ -0,0 +1,2 @@
|
|||
[NAME]
|
||||
grub-mklayout \- generate a GRUB keyboard layout file
|
2
docs/man/grub-mknetdir.h2m
Normal file
2
docs/man/grub-mknetdir.h2m
Normal file
|
@ -0,0 +1,2 @@
|
|||
[NAME]
|
||||
grub-mknetdir \- prepare a GRUB netboot directory.
|
79
gentpl.py
79
gentpl.py
|
@ -276,75 +276,13 @@ def module(platform):
|
|||
r += gvar_add("BUILT_SOURCES", "$(nodist_" + cname() + "_SOURCES)")
|
||||
r += gvar_add("CLEANFILES", "$(nodist_" + cname() + "_SOURCES)")
|
||||
|
||||
r += gvar_add("DEF_FILES", "def-[+ name +].lst")
|
||||
r += gvar_add("UND_FILES", "und-[+ name +].lst")
|
||||
r += gvar_add("MOD_FILES", "[+ name +].mod")
|
||||
r += gvar_add("platform_DATA", "[+ name +].mod")
|
||||
r += gvar_add("CLEANFILES", "def-[+ name +].lst und-[+ name +].lst mod-[+ name +].c mod-[+ name +].o [+ name +].mod")
|
||||
|
||||
r += gvar_add("COMMAND_FILES", "command-[+ name +].lst")
|
||||
r += gvar_add("FS_FILES", "fs-[+ name +].lst")
|
||||
r += gvar_add("VIDEO_FILES", "video-[+ name +].lst")
|
||||
r += gvar_add("PARTMAP_FILES", "partmap-[+ name +].lst")
|
||||
r += gvar_add("HANDLER_FILES", "handler-[+ name +].lst")
|
||||
r += gvar_add("PARTTOOL_FILES", "parttool-[+ name +].lst")
|
||||
r += gvar_add("TERMINAL_FILES", "terminal-[+ name +].lst")
|
||||
r += gvar_add("CLEANFILES", "command-[+ name +].lst fs-[+ name +].lst")
|
||||
r += gvar_add("CLEANFILES", "handler-[+ name +].lst terminal-[+ name +].lst")
|
||||
r += gvar_add("CLEANFILES", "video-[+ name +].lst partmap-[+ name +].lst parttool-[+ name +].lst")
|
||||
|
||||
r += gvar_add("CLEANFILES", "[+ name +].pp")
|
||||
r += gvar_add("MARKER_FILES", "[+ name +].marker")
|
||||
r += gvar_add("CLEANFILES", "[+ name +].marker")
|
||||
r += """
|
||||
[+ name +].pp: $(""" + cname() + """_SOURCES) $(nodist_""" + cname() + """_SOURCES)
|
||||
$(TARGET_CPP) -DGRUB_LST_GENERATOR $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname() + """_CPPFLAGS) $(CPPFLAGS) $^ > $@ || (rm -f $@; exit 1)
|
||||
|
||||
def-[+ name +].lst: [+ name +].module$(EXEEXT)
|
||||
if test x$(USE_APPLE_CC_FIXES) = xyes; then \
|
||||
$(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]' | sed "s/^\\([^ ]*\\).*/\\1 [+ name +]/" >> $@; \
|
||||
else \
|
||||
$(NM) -g --defined-only -P -p $< | sed "s/^\\([^ ]*\\).*/\\1 [+ name +]/" >> $@; \
|
||||
fi
|
||||
|
||||
und-[+ name +].lst: [+ name +].module$(EXEEXT)
|
||||
$(NM) -u -P -p $< | sed "s/^\\([^ ]*\\).*/\\1 [+ name +]/" >> $@
|
||||
|
||||
mod-[+ name +].c: [+ name +].module$(EXEEXT) moddep.lst genmodsrc.sh
|
||||
sh $(srcdir)/genmodsrc.sh [+ name +] moddep.lst > $@ || (rm -f $@; exit 1)
|
||||
|
||||
mod-[+ name +].o: mod-[+ name +].c
|
||||
$(TARGET_CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname() + """_CPPFLAGS) $(CPPFLAGS) $(""" + cname() + """_CFLAGS) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
[+ name +].mod: [+ name +].module$(EXEEXT) mod-[+ name +].o
|
||||
if test x$(USE_APPLE_CC_FIXES) = xyes; then \
|
||||
$(CCLD) $(""" + cname() + """_LDFLAGS) $(LDFLAGS) -o $@.bin $^; \
|
||||
$(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@; \
|
||||
rm -f $@.bin; \
|
||||
else \
|
||||
$(CCLD) -o $@ $(""" + cname() + """_LDFLAGS) $(LDFLAGS) $^; \
|
||||
if test ! -z '$(TARGET_OBJ2ELF)'; then $(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi; \
|
||||
$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@; \
|
||||
fi
|
||||
|
||||
command-[+ name +].lst: [+ name +].pp $(srcdir)/gencmdlist.sh
|
||||
cat $< | sh $(srcdir)/gencmdlist.sh [+ name +] > $@ || (rm -f $@; exit 1)
|
||||
|
||||
fs-[+ name +].lst: [+ name +].pp $(srcdir)/genfslist.sh
|
||||
cat $< | sh $(srcdir)/genfslist.sh [+ name +] > $@ || (rm -f $@; exit 1)
|
||||
|
||||
video-[+ name +].lst: [+ name +].pp $(srcdir)/genvideolist.sh
|
||||
cat $< | sh $(srcdir)/genvideolist.sh [+ name +] > $@ || (rm -f $@; exit 1)
|
||||
|
||||
partmap-[+ name +].lst: [+ name +].pp $(srcdir)/genpartmaplist.sh
|
||||
cat $< | sh $(srcdir)/genpartmaplist.sh [+ name +] > $@ || (rm -f $@; exit 1)
|
||||
|
||||
parttool-[+ name +].lst: [+ name +].pp $(srcdir)/genparttoollist.sh
|
||||
cat $< | sh $(srcdir)/genparttoollist.sh [+ name +] > $@ || (rm -f $@; exit 1)
|
||||
|
||||
handler-[+ name +].lst: [+ name +].pp $(srcdir)/genhandlerlist.sh
|
||||
cat $< | sh $(srcdir)/genhandlerlist.sh [+ name +] > $@ || (rm -f $@; exit 1)
|
||||
|
||||
terminal-[+ name +].lst: [+ name +].pp $(srcdir)/genterminallist.sh
|
||||
cat $< | sh $(srcdir)/genterminallist.sh [+ name +] > $@ || (rm -f $@; exit 1)
|
||||
[+ name +].marker: $(""" + cname() + """_SOURCES) $(nodist_""" + cname() + """_SOURCES)
|
||||
$(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname() + """_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1)
|
||||
grep 'MARKER' $@.new > $@; rm -f $@.new
|
||||
"""
|
||||
return r
|
||||
|
||||
|
@ -471,14 +409,13 @@ def script(platform):
|
|||
r += "[+ IF mansection +]" + manpage() + "[+ ENDIF +]"
|
||||
r += "[+ ENDIF +]"
|
||||
|
||||
r += rule("[+ name +]", "$(top_builddir)/config.status " + platform_sources(platform), """
|
||||
$(top_builddir)/config.status --file=-:""" + platform_sources(platform) + """ \
|
||||
| sed -e 's,@pkglib_DATA@,$(pkglib_DATA),g' > $@
|
||||
r += rule("[+ name +]", platform_sources(platform) + " $(top_builddir)/config.status", """
|
||||
$(top_builddir)/config.status --file=-:$< | sed -e 's,@pkglib_DATA@,$(pkglib_DATA),g' > $@
|
||||
chmod a+x [+ name +]
|
||||
""")
|
||||
|
||||
r += gvar_add("CLEANFILES", "[+ name +]")
|
||||
r += gvar_add("EXTRA_DIST", platform_sources(platform))
|
||||
r += gvar_add("dist_noinst_DATA", platform_sources(platform))
|
||||
return r
|
||||
|
||||
def module_rules():
|
||||
|
|
|
@ -75,9 +75,10 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
|
|||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/boot.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h
|
||||
|
||||
if COND_i386_pc
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loader.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h
|
||||
|
@ -93,24 +94,20 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
|||
endif
|
||||
|
||||
if COND_i386_coreboot
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
||||
endif
|
||||
|
||||
if COND_i386_multiboot
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
||||
endif
|
||||
|
||||
if COND_i386_qemu
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
||||
endif
|
||||
|
||||
if COND_i386_ieee1275
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
||||
endif
|
||||
|
@ -123,8 +120,8 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pit.h
|
|||
endif
|
||||
|
||||
if COND_mips_yeeloong
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/cache.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bitmap.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h
|
||||
|
@ -133,19 +130,17 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h
|
|||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bitmap_scale.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cs5536.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pci.h
|
||||
KERNEL_HEADER_FILES += $(top_builddir)/include/grub/serial.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h
|
||||
endif
|
||||
|
||||
if COND_powerpc_ieee1275
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
|
||||
endif
|
||||
|
||||
if COND_sparc64_ieee1275
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libgcc.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h
|
||||
endif
|
||||
|
@ -179,13 +174,19 @@ symlist.c: symlist.h gensymlist.sh
|
|||
CLEANFILES += symlist.c
|
||||
BUILT_SOURCES += symlist.c
|
||||
|
||||
if COND_HAVE_ASM_USCORE
|
||||
ASM_PREFIX=1
|
||||
else
|
||||
ASM_PREFIX=
|
||||
endif
|
||||
|
||||
noinst_DATA += kernel_syms.lst
|
||||
|
||||
kernel_syms.lst: $(KERNEL_HEADER_FILES) $(top_builddir)/config.h
|
||||
$(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) $(CFLAGS) -DGRUB_SYMBOL_GENERATOR=1 $^ >kernel_syms.input
|
||||
if grep "^#define HAVE_ASM_USCORE" $(top_builddir)/config.h; then u="_"; else u=""; fi; \
|
||||
cat kernel_syms.input | grep -v '^#' | sed -n \
|
||||
-e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/'"$$u"'\1 kernel/;p;}' \
|
||||
-e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/'"$$u"'\1 kernel/;p;}' \
|
||||
-e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined '"$(ASM_PREFIX)"'kernel \1/;p;}' \
|
||||
-e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined '"$(ASM_PREFIX)"' kernel \1/;p;}' \
|
||||
| sort -u >$@
|
||||
rm -f kernel_syms.input
|
||||
CLEANFILES += kernel_syms.lst
|
||||
|
@ -205,61 +206,91 @@ grub_emu_init.c: grub_emu_init.h genemuinit.sh $(MOD_FILES)
|
|||
CLEANFILES += grub_emu_init.c
|
||||
endif
|
||||
|
||||
# .lst files
|
||||
platform_DATA += moddep.lst
|
||||
platform_DATA += fs.lst
|
||||
platform_DATA += command.lst
|
||||
platform_DATA += partmap.lst
|
||||
platform_DATA += handler.lst
|
||||
platform_DATA += terminal.lst
|
||||
platform_DATA += parttool.lst
|
||||
platform_DATA += video.lst
|
||||
platform_DATA += crypto.lst
|
||||
CLEANFILES += moddep.lst
|
||||
CLEANFILES += handler.lst
|
||||
CLEANFILES += terminal.lst
|
||||
CLEANFILES += parttool.lst
|
||||
CLEANFILES += video.lst
|
||||
CLEANFILES += crypto.lst
|
||||
# List files
|
||||
|
||||
fs.lst: $(FS_FILES)
|
||||
cat $^ /dev/null | sort | uniq > $@
|
||||
fs.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
if grep 'FS_LIST_MARKER' $$pp >/dev/null 2>&1; then \
|
||||
echo $$b; \
|
||||
fi; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += fs.lst
|
||||
CLEANFILES += fs.lst
|
||||
|
||||
command.lst: $(COMMAND_FILES)
|
||||
cat $^ /dev/null | sort | uniq > $@
|
||||
command.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
sed -n \
|
||||
-e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" \
|
||||
-e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \
|
||||
-e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" $$pp; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += command.lst
|
||||
CLEANFILES += command.lst
|
||||
|
||||
partmap.lst: $(PARTMAP_FILES)
|
||||
cat $^ /dev/null | sort | uniq > $@
|
||||
partmap.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
if grep 'PARTMAP_LIST_MARKER' $$pp >/dev/null 2>&1; then \
|
||||
echo $$b; \
|
||||
fi; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += partmap.lst
|
||||
CLEANFILES += partmap.lst
|
||||
|
||||
handler.lst: $(HANDLER_FILES)
|
||||
cat $^ /dev/null | sort | uniq > $@
|
||||
CLEANFILES += handler.lst
|
||||
|
||||
terminal.lst: $(TERMINAL_FILES)
|
||||
cat $^ /dev/null | sort | uniq > $@
|
||||
terminal.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
sed -n \
|
||||
-e "/INPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \
|
||||
-e "/OUTPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += terminal.lst
|
||||
CLEANFILES += terminal.lst
|
||||
|
||||
parttool.lst: $(PARTTOOL_FILES)
|
||||
cat $^ /dev/null | sort | uniq > $@
|
||||
parttool.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
sed -n \
|
||||
-e "/PARTTOOL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += parttool.lst
|
||||
CLEANFILES += parttool.lst
|
||||
|
||||
video.lst: $(VIDEO_FILES)
|
||||
cat $^ /dev/null | sort | uniq > $@
|
||||
video.lst: $(MARKER_FILES)
|
||||
(for pp in $^; do \
|
||||
b=`basename $$pp .marker`; \
|
||||
if grep 'VIDEO_LIST_MARKER' $$pp >/dev/null 2>&1; then \
|
||||
echo $$b; \
|
||||
fi; \
|
||||
done) | sort -u > $@
|
||||
platform_DATA += video.lst
|
||||
CLEANFILES += video.lst
|
||||
|
||||
# but, crypto.lst is simply copied
|
||||
crypto.lst: $(srcdir)/lib/libgcrypt-grub/cipher/crypto.lst
|
||||
cp $^ $@
|
||||
platform_DATA += crypto.lst
|
||||
CLEANFILES += crypto.lst
|
||||
|
||||
syminfo.lst: gensyminfo.sh kernel_syms.lst $(MODULE_FILES)
|
||||
cat kernel_syms.lst > $@.new
|
||||
for m in $(MODULE_FILES); do \
|
||||
sh $< $$m >> $@.new || exit 1; \
|
||||
done
|
||||
mv $@.new $@
|
||||
|
||||
# generate global module dependencies list
|
||||
moddep.lst: kernel_syms.lst genmoddep.awk $(DEF_FILES) $(UND_FILES)
|
||||
cat $(DEF_FILES) kernel_syms.lst /dev/null \
|
||||
| $(AWK) -f $(srcdir)/genmoddep.awk $(UND_FILES) > $@ \
|
||||
|| (rm -f $@; exit 1)
|
||||
moddep.lst: syminfo.lst genmoddep.awk
|
||||
cat $< | sort | awk -f $(srcdir)/genmoddep.awk > $@ || (rm -f $@; exit 1)
|
||||
platform_DATA += moddep.lst
|
||||
CLEANFILES += config.log syminfo.lst moddep.lst
|
||||
|
||||
$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT)
|
||||
sh $^ $@
|
||||
platform_DATA += $(MOD_FILES)
|
||||
CLEANFILES += $(MOD_FILES)
|
||||
|
||||
if COND_ENABLE_EFIEMU
|
||||
efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
AutoGen definitions Makefile.tpl;
|
||||
|
||||
script = {
|
||||
installdir = noinst;
|
||||
name = gensyminfo.sh;
|
||||
common = gensyminfo.sh.in;
|
||||
};
|
||||
|
||||
script = {
|
||||
installdir = noinst;
|
||||
name = genmod.sh;
|
||||
common = genmod.sh.in;
|
||||
};
|
||||
|
||||
kernel = {
|
||||
name = kernel;
|
||||
|
||||
|
@ -10,20 +22,20 @@ kernel = {
|
|||
x86_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment';
|
||||
|
||||
i386_pc_ldflags = '$(TARGET_IMG_LDFLAGS)';
|
||||
i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
|
||||
i386_pc_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200';
|
||||
|
||||
i386_qemu_ldflags = '$(TARGET_IMG_LDFLAGS)';
|
||||
i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
|
||||
i386_qemu_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x8200';
|
||||
|
||||
i386_coreboot_ldflags = '-Wl,-Ttext=$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
|
||||
i386_multiboot_ldflags = '-Wl,-Ttext=$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
|
||||
i386_ieee1275_ldflags = '-Wl,-Ttext=$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
|
||||
mips_yeeloong_ldflags = '-Wl,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
|
||||
powerpc_ieee1275_ldflags = '-Wl,-Ttext,$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
|
||||
i386_coreboot_ldflags = '-Wl,-Ttext=0x8200';
|
||||
i386_multiboot_ldflags = '-Wl,-Ttext=0x8200';
|
||||
i386_ieee1275_ldflags = '-Wl,-Ttext=0x10000';
|
||||
mips_yeeloong_ldflags = '-Wl,-Ttext,0x80200000';
|
||||
powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000';
|
||||
sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400';
|
||||
|
||||
mips_yeeloong_cppflags = '-DUSE_ASCII_FAILBACK';
|
||||
i386_qemu_cppflags = '-DGRUB_BOOT_MACHINE_LINK_ADDR=$(GRUB_BOOT_MACHINE_LINK_ADDR)';
|
||||
i386_qemu_ccasflags = '-DGRUB_KERNEL_MACHINE_LINK_ADDR=$(GRUB_KERNEL_MACHINE_LINK_ADDR)';
|
||||
emu_cflags = '$(CFLAGS_GNULIB)';
|
||||
emu_cppflags = '$(CPPFLAGS_GNULIB)';
|
||||
|
||||
|
@ -137,6 +149,8 @@ kernel = {
|
|||
mips_yeeloong = term/at_keyboard.c;
|
||||
mips_yeeloong = term/serial.c;
|
||||
mips_yeeloong = video/sm712.c;
|
||||
extra_dist = video/sm712_init.c;
|
||||
mips_yeeloong = commands/keylayouts.c;
|
||||
|
||||
powerpc_ieee1275 = kern/ieee1275/init.c;
|
||||
powerpc_ieee1275 = kern/powerpc/cache.S;
|
||||
|
@ -149,6 +163,7 @@ kernel = {
|
|||
|
||||
emu = disk/host.c;
|
||||
emu = gnulib/progname.c;
|
||||
emu = gnulib/error.c;
|
||||
emu = kern/emu/console.c;
|
||||
emu = kern/emu/getroot.c;
|
||||
emu = kern/emu/hostdisk.c;
|
||||
|
@ -172,6 +187,8 @@ kernel = {
|
|||
videoinkernel = video/fb/video_fb.c;
|
||||
videoinkernel = video/video.c;
|
||||
|
||||
videoinkernel = commands/boot.c;
|
||||
|
||||
extra_dist = kern/i386/realmode.S;
|
||||
extra_dist = kern/i386/pc/lzma_decode.S;
|
||||
extra_dist = kern/mips/cache_flush.S;
|
||||
|
@ -186,7 +203,7 @@ program = {
|
|||
|
||||
ldadd = 'kernel.img$(EXEEXT)';
|
||||
ldadd = '$(MODULE_FILES)';
|
||||
ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER)';
|
||||
ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
|
||||
|
||||
enable = emu;
|
||||
};
|
||||
|
@ -199,7 +216,7 @@ program = {
|
|||
emu_nodist = symlist.c;
|
||||
|
||||
ldadd = 'kernel.img$(EXEEXT)';
|
||||
ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER)';
|
||||
ldadd = '$(LIBUTIL) $(LIBCURSES) $(LIBSDL) $(LIBUSB) $(LIBPCIACCESS) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR)';
|
||||
|
||||
enable = emu;
|
||||
};
|
||||
|
@ -318,25 +335,19 @@ module = {
|
|||
module = {
|
||||
name = usbserial_common;
|
||||
common = bus/usb/serial/common.c;
|
||||
enable = emu;
|
||||
enable = usb;
|
||||
emu_condition = COND_GRUB_EMU_USB;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = usbserial_pl2303;
|
||||
common = bus/usb/serial/pl2303.c;
|
||||
enable = emu;
|
||||
enable = usb;
|
||||
emu_condition = COND_GRUB_EMU_USB;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = usbserial_ftdi;
|
||||
common = bus/usb/serial/ftdi.c;
|
||||
enable = emu;
|
||||
enable = usb;
|
||||
emu_condition = COND_GRUB_EMU_USB;
|
||||
};
|
||||
|
||||
module = {
|
||||
|
@ -369,12 +380,6 @@ module = {
|
|||
library = {
|
||||
name = libgnulib.a;
|
||||
common = gnulib/regex.c;
|
||||
|
||||
extra_dist = gnulib/regcomp.c;
|
||||
extra_dist = gnulib/regexec.c;
|
||||
extra_dist = gnulib/fnmatch_loop.c;
|
||||
extra_dist = gnulib/regex_internal.c;
|
||||
|
||||
cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
|
||||
cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)';
|
||||
};
|
||||
|
@ -394,6 +399,7 @@ module = {
|
|||
module = {
|
||||
name = regexp;
|
||||
common = commands/regexp.c;
|
||||
common = commands/wildcard.c;
|
||||
ldadd = libgnulib.a;
|
||||
cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
|
||||
cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)';
|
||||
|
@ -402,7 +408,7 @@ module = {
|
|||
module = {
|
||||
name = acpi;
|
||||
|
||||
x86 = commands/acpi.c;
|
||||
common = commands/acpi.c;
|
||||
x86_efi = commands/efi/acpi.c;
|
||||
i386_pc = commands/i386/pc/acpi.c;
|
||||
i386_coreboot = commands/i386/pc/acpi.c;
|
||||
|
@ -414,6 +420,41 @@ module = {
|
|||
enable = i386_multiboot;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = lsacpi;
|
||||
|
||||
common = commands/lsacpi.c;
|
||||
|
||||
enable = x86_efi;
|
||||
enable = i386_pc;
|
||||
enable = i386_coreboot;
|
||||
enable = i386_multiboot;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = lsefisystab;
|
||||
|
||||
common = commands/efi/lsefisystab.c;
|
||||
|
||||
enable = x86_efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = lssal;
|
||||
|
||||
common = commands/efi/lssal.c;
|
||||
|
||||
enable = x86_efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = lsefimmap;
|
||||
|
||||
common = commands/efi/lsefimmap.c;
|
||||
|
||||
enable = x86_efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = blocklist;
|
||||
common = commands/blocklist.c;
|
||||
|
@ -423,6 +464,7 @@ module = {
|
|||
name = boot;
|
||||
common = commands/boot.c;
|
||||
i386_pc = lib/i386/pc/biosnum.c;
|
||||
enable = videomodules;
|
||||
};
|
||||
|
||||
module = {
|
||||
|
@ -446,12 +488,6 @@ module = {
|
|||
enable = x86;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = crc;
|
||||
common = commands/crc.c;
|
||||
common = lib/crc.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = date;
|
||||
common = commands/date.c;
|
||||
|
@ -491,6 +527,10 @@ module = {
|
|||
name = halt;
|
||||
nopc = commands/halt.c;
|
||||
i386_pc = commands/i386/pc/halt.c;
|
||||
i386_pc = commands/acpihalt.c;
|
||||
i386_coreboot = commands/acpihalt.c;
|
||||
i386_multiboot = commands/acpihalt.c;
|
||||
x86_efi = commands/acpihalt.c;
|
||||
i386_multiboot = lib/i386/halt.c;
|
||||
i386_coreboot = lib/i386/halt.c;
|
||||
i386_qemu = lib/i386/halt.c;
|
||||
|
@ -671,15 +711,8 @@ module = {
|
|||
};
|
||||
|
||||
module = {
|
||||
name = vbeinfo;
|
||||
i386_pc = commands/i386/pc/vbeinfo.c;
|
||||
enable = i386_pc;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = vbetest;
|
||||
i386_pc = commands/i386/pc/vbetest.c;
|
||||
enable = i386_pc;
|
||||
name = videoinfo;
|
||||
common = commands/videoinfo.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
|
@ -708,10 +741,15 @@ module = {
|
|||
};
|
||||
|
||||
module = {
|
||||
name = mdraid;
|
||||
name = mdraid09;
|
||||
common = disk/mdraid_linux.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = mdraid1x;
|
||||
common = disk/mdraid1x_linux.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = raid;
|
||||
common = disk/raid.c;
|
||||
|
@ -833,6 +871,11 @@ module = {
|
|||
common = fs/befs_be.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = btrfs;
|
||||
common = fs/btrfs.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = cpio;
|
||||
common = fs/cpio.c;
|
||||
|
@ -878,6 +921,11 @@ module = {
|
|||
common = fs/minix.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = minix2;
|
||||
common = fs/minix2.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = nilfs2;
|
||||
common = fs/nilfs2.c;
|
||||
|
@ -1009,6 +1057,9 @@ module = {
|
|||
powerpc = lib/powerpc/relocator_asm.S;
|
||||
powerpc = lib/powerpc/relocator.c;
|
||||
|
||||
extra_dist = lib/i386/relocator_common.S;
|
||||
extra_dist = kern/powerpc/cache_flush.S;
|
||||
|
||||
enable = mips;
|
||||
enable = powerpc;
|
||||
enable = x86;
|
||||
|
@ -1084,6 +1135,7 @@ module = {
|
|||
module = {
|
||||
name = linux;
|
||||
x86 = loader/i386/linux.c;
|
||||
i386_pc = lib/i386/pc/vesa_modes_table.c;
|
||||
mips = loader/mips/linux.c;
|
||||
powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
|
||||
sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
|
||||
|
@ -1160,6 +1212,8 @@ module = {
|
|||
common = script/lexer.c;
|
||||
common = script/argv.c;
|
||||
|
||||
common = commands/menuentry.c;
|
||||
|
||||
common = unidata.c;
|
||||
common_nodist = grub_script.tab.c;
|
||||
common_nodist = grub_script.yy.c;
|
||||
|
@ -1404,3 +1458,43 @@ module = {
|
|||
emu = net/drivers/emu/emunet.c;
|
||||
enable = ieee1275;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = legacycfg;
|
||||
common = commands/legacycfg.c;
|
||||
common = lib/legacy_parse.c;
|
||||
emu = lib/i386/pc/vesa_modes_table.c;
|
||||
enable = i386_pc;
|
||||
enable = emu;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = test_blockarg;
|
||||
common = tests/test_blockarg.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = xzio;
|
||||
common = io/xzio.c;
|
||||
common = lib/xzembed/xz_dec_bcj.c;
|
||||
common = lib/xzembed/xz_dec_lzma2.c;
|
||||
common = lib/xzembed/xz_dec_stream.c;
|
||||
cppflags = '-I$(srcdir)/lib/posix_wrap -I$(srcdir)/lib/xzembed';
|
||||
};
|
||||
|
||||
module = {
|
||||
name = testload;
|
||||
common = commands/testload.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = lsapm;
|
||||
common = commands/i386/pc/lsapm.c;
|
||||
enable = i386_pc;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = keylayouts;
|
||||
common = commands/keylayouts.c;
|
||||
enable = videomodules;
|
||||
};
|
||||
|
|
|
@ -112,12 +112,16 @@ LOCAL(after_BPB):
|
|||
*/
|
||||
. = _start + GRUB_BOOT_MACHINE_DRIVE_CHECK
|
||||
boot_drive_check:
|
||||
jmp 1f /* grub-setup may overwrite this jump */
|
||||
jmp 3f /* grub-setup may overwrite this jump */
|
||||
testb $0x80, %dl
|
||||
jnz 1f
|
||||
jz 2f
|
||||
3:
|
||||
/* Ignore %dl different from 0-0x0f and 0x80-0x8f. */
|
||||
testb $0x70, %dl
|
||||
jz 1f
|
||||
2:
|
||||
movb $0x80, %dl
|
||||
1:
|
||||
|
||||
/*
|
||||
* ljmp to the next instruction because some bogus BIOSes
|
||||
* jump to 07C0:0000 instead of 0000:7C00.
|
||||
|
|
|
@ -185,7 +185,7 @@ real_code_2:
|
|||
call LOCAL(move_memory)
|
||||
|
||||
/* Check for multiboot signature. */
|
||||
cmpl $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_DATA_END)
|
||||
cmpl $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_I386_PC_MULTIBOOT_SIGNATURE)
|
||||
jz 1f
|
||||
|
||||
movl (ramdisk_image - start), %esi
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <config.h>
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/i386/pc/memory.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/machine/boot.h>
|
||||
#include <grub/machine/kernel.h>
|
||||
|
|
|
@ -98,7 +98,6 @@ struct grub_ohci
|
|||
struct grub_pci_dma_chunk *td_chunk;
|
||||
struct grub_ohci *next;
|
||||
grub_ohci_td_t td_free; /* Pointer to first free TD */
|
||||
int bad_OHCI;
|
||||
};
|
||||
|
||||
static struct grub_ohci *ohci;
|
||||
|
@ -149,8 +148,8 @@ typedef enum
|
|||
#define GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE (1 << 4)
|
||||
|
||||
#define GRUB_OHCI_RESET_CONNECT_CHANGE (1 << 16)
|
||||
#define GRUB_OHCI_CTRL_EDS 16
|
||||
#define GRUB_OHCI_BULK_EDS 16
|
||||
#define GRUB_OHCI_CTRL_EDS 256
|
||||
#define GRUB_OHCI_BULK_EDS 510
|
||||
#define GRUB_OHCI_TDS 256
|
||||
|
||||
#define GRUB_OHCI_ED_ADDR_MASK 0x7ff
|
||||
|
@ -442,8 +441,10 @@ grub_ohci_pci_iter (grub_pci_device_t dev,
|
|||
(grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA)
|
||||
& ~GRUB_OHCI_RHUB_PORT_POWER_MASK)
|
||||
| GRUB_OHCI_RHUB_PORT_ALL_POWERED);
|
||||
#if 0 /* We don't need it at all, handled via hotplugging */
|
||||
/* Now we have hot-plugging, we need to wait for stable power only */
|
||||
grub_millisleep (100);
|
||||
#endif
|
||||
|
||||
/* Link to ohci now that initialisation is successful. */
|
||||
o->next = ohci;
|
||||
|
@ -623,7 +624,8 @@ grub_ohci_transaction (grub_ohci_td_t td,
|
|||
break;
|
||||
}
|
||||
|
||||
/* Set the token (Always generate interrupt - bits 21-23 = 0). */
|
||||
/* Set the token */
|
||||
token |= ( 7 << 21); /* Never generate interrupt */
|
||||
token |= toggle << 24;
|
||||
token |= 1 << 25;
|
||||
|
||||
|
@ -652,36 +654,31 @@ grub_ohci_transaction (grub_ohci_td_t td,
|
|||
td->next_td = 0;
|
||||
}
|
||||
|
||||
struct grub_ohci_transfer_controller_data
|
||||
{
|
||||
grub_uint32_t tderr_phys;
|
||||
grub_uint32_t td_last_phys;
|
||||
grub_ohci_ed_t ed_virt;
|
||||
grub_ohci_td_t td_current_virt;
|
||||
grub_ohci_td_t td_head_virt;
|
||||
};
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_ohci_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer, int timeout,
|
||||
grub_size_t *actual)
|
||||
grub_ohci_setup_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer)
|
||||
{
|
||||
struct grub_ohci *o = (struct grub_ohci *) dev->data;
|
||||
grub_ohci_ed_t ed_virt;
|
||||
int bulk = 0;
|
||||
grub_ohci_td_t td_head_virt;
|
||||
grub_ohci_td_t td_current_virt;
|
||||
grub_ohci_td_t td_next_virt;
|
||||
grub_ohci_td_t tderr_virt = NULL;
|
||||
grub_uint32_t target;
|
||||
grub_uint32_t td_head_phys;
|
||||
grub_uint32_t td_tail_phys;
|
||||
grub_uint32_t td_last_phys;
|
||||
grub_uint32_t tderr_phys = 0;
|
||||
grub_uint32_t status;
|
||||
grub_uint32_t control;
|
||||
grub_uint8_t errcode = 0;
|
||||
grub_usb_err_t err = GRUB_USB_ERR_NONE;
|
||||
int i;
|
||||
grub_uint64_t maxtime;
|
||||
grub_uint64_t bad_OHCI_delay = 0;
|
||||
int err_halt = 0;
|
||||
int err_timeout = 0;
|
||||
int err_unrec = 0;
|
||||
grub_uint32_t intstatus;
|
||||
struct grub_ohci_transfer_controller_data *cdata;
|
||||
|
||||
*actual = 0;
|
||||
cdata = grub_zalloc (sizeof (*cdata));
|
||||
if (!cdata)
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
|
||||
/* Pre-set target for ED - we need it to find proper ED */
|
||||
/* Set the device address. */
|
||||
|
@ -703,21 +700,23 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
case GRUB_USB_TRANSACTION_TYPE_CONTROL:
|
||||
break;
|
||||
|
||||
default :
|
||||
default:
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
/* Find proper ED or add new ED */
|
||||
ed_virt = grub_ohci_find_ed (o, bulk, target);
|
||||
if (!ed_virt)
|
||||
cdata->ed_virt = grub_ohci_find_ed (o, bulk, target);
|
||||
if (!cdata->ed_virt)
|
||||
{
|
||||
grub_dprintf ("ohci","Fatal: No free ED !\n");
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
/* Take pointer to first TD from ED */
|
||||
td_head_phys = grub_le_to_cpu32 (ed_virt->td_head) & ~0xf;
|
||||
td_tail_phys = grub_le_to_cpu32 (ed_virt->td_tail) & ~0xf;
|
||||
td_head_phys = grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf;
|
||||
td_tail_phys = grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf;
|
||||
|
||||
/* Sanity check - td_head should be equal to td_tail */
|
||||
if (td_head_phys != td_tail_phys) /* Should never happen ! */
|
||||
|
@ -726,6 +725,7 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
grub_dprintf ("ohci", "HEAD = 0x%02x, TAIL = 0x%02x\n",
|
||||
td_head_phys, td_tail_phys);
|
||||
/* XXX: Fix: What to do ? */
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
|
@ -733,65 +733,62 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
* we must allocate the first TD. */
|
||||
if (!td_head_phys)
|
||||
{
|
||||
td_head_virt = grub_ohci_alloc_td (o);
|
||||
if (!td_head_virt)
|
||||
cdata->td_head_virt = grub_ohci_alloc_td (o);
|
||||
if (!cdata->td_head_virt)
|
||||
return GRUB_USB_ERR_INTERNAL; /* We don't need de-allocate ED */
|
||||
/* We can set td_head only when ED is not active, i.e.
|
||||
* when it is newly allocated. */
|
||||
ed_virt->td_head = grub_cpu_to_le32 ( grub_ohci_td_virt2phys (o,
|
||||
td_head_virt) );
|
||||
ed_virt->td_tail = ed_virt->td_head;
|
||||
cdata->ed_virt->td_head
|
||||
= grub_cpu_to_le32 (grub_ohci_td_virt2phys (o, cdata->td_head_virt));
|
||||
cdata->ed_virt->td_tail = cdata->ed_virt->td_head;
|
||||
}
|
||||
else
|
||||
td_head_virt = grub_ohci_td_phys2virt ( o, td_head_phys );
|
||||
cdata->td_head_virt = grub_ohci_td_phys2virt ( o, td_head_phys );
|
||||
|
||||
/* Set TDs */
|
||||
td_last_phys = td_head_phys; /* initial value to make compiler happy... */
|
||||
for (i = 0, td_current_virt = td_head_virt;
|
||||
cdata->td_last_phys = td_head_phys; /* initial value to make compiler happy... */
|
||||
for (i = 0, cdata->td_current_virt = cdata->td_head_virt;
|
||||
i < transfer->transcnt; i++)
|
||||
{
|
||||
grub_usb_transaction_t tr = &transfer->transactions[i];
|
||||
|
||||
grub_ohci_transaction (td_current_virt, tr->pid, tr->toggle,
|
||||
grub_ohci_transaction (cdata->td_current_virt, tr->pid, tr->toggle,
|
||||
tr->size, tr->data);
|
||||
|
||||
/* Set index of TD in transfer */
|
||||
td_current_virt->tr_index = (grub_uint32_t) i;
|
||||
|
||||
/* No IRQ request in TD if bad_OHCI set */
|
||||
if (o->bad_OHCI)
|
||||
td_current_virt->token |= grub_cpu_to_le32 ( 7 << 21);
|
||||
cdata->td_current_virt->tr_index = (grub_uint32_t) i;
|
||||
|
||||
/* Remember last used (processed) TD phys. addr. */
|
||||
td_last_phys = grub_ohci_td_virt2phys (o, td_current_virt);
|
||||
cdata->td_last_phys = grub_ohci_td_virt2phys (o, cdata->td_current_virt);
|
||||
|
||||
/* Allocate next TD */
|
||||
td_next_virt = grub_ohci_alloc_td (o);
|
||||
if (!td_next_virt) /* No free TD, cancel transfer and free TDs except head TD */
|
||||
{
|
||||
if (i) /* if i==0 we have nothing to free... */
|
||||
grub_ohci_free_tds (o,
|
||||
grub_ohci_td_phys2virt(o,
|
||||
grub_le_to_cpu32 (td_head_virt->next_td) ) );
|
||||
grub_ohci_free_tds (o, grub_ohci_td_phys2virt(o,
|
||||
grub_le_to_cpu32 (cdata->td_head_virt->next_td)));
|
||||
/* Reset head TD */
|
||||
grub_memset ( (void*)td_head_virt, 0,
|
||||
grub_memset ( (void*)cdata->td_head_virt, 0,
|
||||
sizeof(struct grub_ohci_td) );
|
||||
grub_dprintf ("ohci", "Fatal: No free TD !");
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
/* Chain TDs */
|
||||
td_current_virt->link_td = td_next_virt;
|
||||
td_current_virt->next_td = grub_cpu_to_le32 (
|
||||
|
||||
cdata->td_current_virt->link_td = td_next_virt;
|
||||
cdata->td_current_virt->next_td = grub_cpu_to_le32 (
|
||||
grub_ohci_td_virt2phys (o,
|
||||
td_next_virt) );
|
||||
td_next_virt->prev_td_phys = grub_ohci_td_virt2phys (o,
|
||||
td_current_virt);
|
||||
td_current_virt = td_next_virt;
|
||||
cdata->td_current_virt);
|
||||
cdata->td_current_virt = td_next_virt;
|
||||
}
|
||||
|
||||
grub_dprintf ("ohci", "Tail TD (not processed) = %p\n",
|
||||
td_current_virt);
|
||||
cdata->td_current_virt);
|
||||
|
||||
/* Setup the Endpoint Descriptor for transfer. */
|
||||
/* First set necessary fields in TARGET but keep (or set) skip bit */
|
||||
|
@ -799,12 +796,12 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
* size never change after first allocation of ED.
|
||||
* But unfortunately max. packet size may change during initial
|
||||
* setup sequence and we must handle it. */
|
||||
ed_virt->target = grub_cpu_to_le32 (target | (1 << 14));
|
||||
cdata->ed_virt->target = grub_cpu_to_le32 (target | (1 << 14));
|
||||
/* Set td_tail */
|
||||
ed_virt->td_tail
|
||||
= grub_cpu_to_le32 (grub_ohci_td_virt2phys (o, td_current_virt));
|
||||
cdata->ed_virt->td_tail
|
||||
= grub_cpu_to_le32 (grub_ohci_td_virt2phys (o, cdata->td_current_virt));
|
||||
/* Now reset skip bit */
|
||||
ed_virt->target = grub_cpu_to_le32 (target);
|
||||
cdata->ed_virt->target = grub_cpu_to_le32 (target);
|
||||
/* ed_virt->td_head = grub_cpu_to_le32 (td_head); Must not be changed, it is maintained by OHCI */
|
||||
/* ed_virt->next_ed = grub_cpu_to_le32 (0); Handled by grub_ohci_find_ed, do not change ! */
|
||||
|
||||
|
@ -834,93 +831,21 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
}
|
||||
}
|
||||
|
||||
/* Safety measure to avoid a hang. */
|
||||
maxtime = grub_get_time_ms () + timeout;
|
||||
|
||||
/* Wait until the transfer is completed or STALLs. */
|
||||
do
|
||||
{
|
||||
/* Check transfer status */
|
||||
intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
|
||||
if (!o->bad_OHCI && (intstatus & 0x2) != 0)
|
||||
{
|
||||
/* Remember last successful TD */
|
||||
tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf;
|
||||
/* Reset DoneHead */
|
||||
o->hcca->donehead = 0;
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
|
||||
/* Read back of register should ensure it is really written */
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
|
||||
/* if TD is last, finish */
|
||||
if (tderr_phys == td_last_phys)
|
||||
{
|
||||
if (grub_le_to_cpu32 (ed_virt->td_head) & 1)
|
||||
err_halt = 1;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
transfer->controller_data = cdata;
|
||||
|
||||
if ((intstatus & 0x10) != 0)
|
||||
{ /* Unrecoverable error - only reset can help...! */
|
||||
err_unrec = 1;
|
||||
break;
|
||||
}
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Detected a HALT. */
|
||||
if (err_halt || (grub_le_to_cpu32 (ed_virt->td_head) & 1))
|
||||
{
|
||||
err_halt = 1;
|
||||
/* ED is halted, but donehead event can happened in the meantime */
|
||||
intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
|
||||
if (!o->bad_OHCI && (intstatus & 0x2) != 0)
|
||||
/* Don't break loop now, first do donehead action(s) */
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
/* bad OHCI handling */
|
||||
if ( (grub_le_to_cpu32 (ed_virt->td_head) & ~0xf) ==
|
||||
(grub_le_to_cpu32 (ed_virt->td_tail) & ~0xf) ) /* Empty ED */
|
||||
{
|
||||
if (o->bad_OHCI) /* Bad OHCI detected previously */
|
||||
{
|
||||
/* Try get last successful TD. */
|
||||
tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf;
|
||||
if (tderr_phys)/* Reset DoneHead if we were successful */
|
||||
{
|
||||
o->hcca->donehead = 0;
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
|
||||
/* Read back of register should ensure it is really written */
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
|
||||
}
|
||||
/* Check the HALT bit */
|
||||
if (grub_le_to_cpu32 (ed_virt->td_head) & 1)
|
||||
err_halt = 1;
|
||||
break;
|
||||
}
|
||||
else /* Detection of bad OHCI */
|
||||
/* We should wait short time (~2ms) before we say that
|
||||
* it is bad OHCI to prevent some hazard -
|
||||
* donehead can react in the meantime. This waiting is done
|
||||
* only once per OHCI driver "live cycle". */
|
||||
if (!bad_OHCI_delay) /* Set delay time */
|
||||
bad_OHCI_delay = grub_get_time_ms () + 2;
|
||||
else if (grub_get_time_ms () >= bad_OHCI_delay)
|
||||
o->bad_OHCI = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Timeout ? */
|
||||
if (grub_get_time_ms () > maxtime)
|
||||
{
|
||||
err_timeout = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
grub_cpu_idle ();
|
||||
}
|
||||
while (1);
|
||||
static void
|
||||
pre_finish_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer)
|
||||
{
|
||||
struct grub_ohci *o = dev->data;
|
||||
struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
grub_uint32_t target;
|
||||
grub_uint32_t status;
|
||||
grub_uint32_t control;
|
||||
grub_uint32_t intstatus;
|
||||
|
||||
/* There are many ways how the loop above can finish:
|
||||
* - normally without any error via INTSTATUS WDH bit
|
||||
|
@ -952,8 +877,8 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
/* Remember target for debug and set skip flag in ED */
|
||||
/* It should be normaly not necessary but we need it at least
|
||||
* in case of timeout */
|
||||
target = grub_le_to_cpu32 ( ed_virt->target );
|
||||
ed_virt->target = grub_cpu_to_le32 (target | (1 << 14));
|
||||
target = grub_le_to_cpu32 ( cdata->ed_virt->target );
|
||||
cdata->ed_virt->target = grub_cpu_to_le32 (target | (1 << 14));
|
||||
/* Read registers for debug - they should be read now because
|
||||
* debug prints case unwanted delays, so something can happen
|
||||
* in the meantime... */
|
||||
|
@ -963,253 +888,321 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
/* Now print debug values - to have full info what happened */
|
||||
grub_dprintf ("ohci", "loop finished: control=0x%02x status=0x%02x\n",
|
||||
control, status);
|
||||
grub_dprintf ("ohci", "intstatus=0x%02x \n\t\t tderr_phys=0x%02x, td_last_phys=0x%02x\n",
|
||||
intstatus, tderr_phys, td_last_phys);
|
||||
grub_dprintf ("ohci", "err_unrec=%d, err_timeout=%d \n\t\t err_halt=%d, bad_OHCI=%d\n",
|
||||
err_unrec, err_timeout, err_halt, o->bad_OHCI);
|
||||
grub_dprintf ("ohci", "intstatus=0x%02x, td_last_phys=0x%02x\n",
|
||||
intstatus, cdata->td_last_phys);
|
||||
grub_dprintf ("ohci", "TARGET=0x%02x, HEAD=0x%02x, TAIL=0x%02x\n",
|
||||
target,
|
||||
grub_le_to_cpu32 (ed_virt->td_head),
|
||||
grub_le_to_cpu32 (ed_virt->td_tail) );
|
||||
grub_le_to_cpu32 (cdata->ed_virt->td_head),
|
||||
grub_le_to_cpu32 (cdata->ed_virt->td_tail) );
|
||||
|
||||
if (!err_halt && !err_unrec && !err_timeout) /* normal finish */
|
||||
{
|
||||
/* Simple workaround if donehead is not working */
|
||||
if (o->bad_OHCI &&
|
||||
( !tderr_phys || (tderr_phys != td_last_phys) ) )
|
||||
{
|
||||
grub_dprintf ("ohci", "normal finish, but tderr_phys corrected\n");
|
||||
tderr_phys = td_last_phys;
|
||||
/* I hope we can do it as transfer (most probably) finished OK */
|
||||
}
|
||||
/* Prepare pointer to last processed TD */
|
||||
tderr_virt = grub_ohci_td_phys2virt (o, tderr_phys);
|
||||
/* Set index of last processed TD */
|
||||
if (tderr_virt)
|
||||
transfer->last_trans = tderr_virt->tr_index;
|
||||
else
|
||||
transfer->last_trans = -1;
|
||||
*actual = transfer->size + 1;
|
||||
}
|
||||
}
|
||||
|
||||
else if (err_halt) /* error, ED is halted by OHCI, i.e. can be modified */
|
||||
{
|
||||
/* First we must get proper tderr_phys value */
|
||||
if (o->bad_OHCI) /* In case of bad_OHCI tderr_phys can be wrong */
|
||||
{
|
||||
if ( tderr_phys ) /* check if tderr_phys points to TD with error */
|
||||
errcode = grub_le_to_cpu32 ( grub_ohci_td_phys2virt (o,
|
||||
tderr_phys)->token )
|
||||
>> 28;
|
||||
if ( !tderr_phys || !errcode ) /* tderr_phys not valid or points to wrong TD */
|
||||
{ /* Retired TD with error should be previous TD to ED->td_head */
|
||||
tderr_phys = grub_ohci_td_phys2virt (o,
|
||||
grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf )
|
||||
->prev_td_phys;
|
||||
}
|
||||
}
|
||||
|
||||
/* Even if we have "good" OHCI, in some cases
|
||||
* tderr_phys can be zero, check it */
|
||||
else if ( !tderr_phys )
|
||||
{ /* Retired TD with error should be previous TD to ED->td_head */
|
||||
tderr_phys = grub_ohci_td_phys2virt (o,
|
||||
grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf )
|
||||
->prev_td_phys;
|
||||
}
|
||||
|
||||
/* Prepare pointer to last processed TD and get error code */
|
||||
tderr_virt = grub_ohci_td_phys2virt (o, tderr_phys);
|
||||
/* Set index of last processed TD */
|
||||
if (tderr_virt)
|
||||
{
|
||||
errcode = grub_le_to_cpu32 ( tderr_virt->token ) >> 28;
|
||||
transfer->last_trans = tderr_virt->tr_index;
|
||||
}
|
||||
else
|
||||
transfer->last_trans = -1;
|
||||
|
||||
/* Evaluation of error code */
|
||||
grub_dprintf ("ohci", "OHCI tderr_phys=0x%02x, errcode=0x%02x\n",
|
||||
tderr_phys, errcode);
|
||||
switch (errcode)
|
||||
{
|
||||
case 0:
|
||||
/* XXX: Should not happen! */
|
||||
grub_error (GRUB_ERR_IO, "OHCI failed without reporting the reason");
|
||||
err = GRUB_USB_ERR_INTERNAL;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* XXX: CRC error. */
|
||||
err = GRUB_USB_ERR_TIMEOUT;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
err = GRUB_USB_ERR_BITSTUFF;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* XXX: Data Toggle error. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
err = GRUB_USB_ERR_STALL;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
/* XXX: Not responding. */
|
||||
err = GRUB_USB_ERR_TIMEOUT;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
/* XXX: PID Check bits failed. */
|
||||
err = GRUB_USB_ERR_BABBLE;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
/* XXX: PID unexpected failed. */
|
||||
err = GRUB_USB_ERR_BABBLE;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
/* XXX: Data overrun error. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n",
|
||||
tderr_virt, tderr_virt->tr_index);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
/* XXX: Data underrun error. */
|
||||
grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n",
|
||||
tderr_virt, tderr_virt->tr_index);
|
||||
if (transfer->last_trans == -1)
|
||||
break;
|
||||
*actual = transfer->transactions[transfer->last_trans].size
|
||||
- (grub_le_to_cpu32 (tderr_virt->buffer_end)
|
||||
- grub_le_to_cpu32 (tderr_virt->buffer))
|
||||
+ transfer->transactions[transfer->last_trans].preceding;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
/* XXX: Reserved. */
|
||||
err = GRUB_USB_ERR_NAK;
|
||||
break;
|
||||
|
||||
case 11:
|
||||
/* XXX: Reserved. */
|
||||
err = GRUB_USB_ERR_NAK;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
/* XXX: Buffer overrun. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
break;
|
||||
|
||||
case 13:
|
||||
/* XXX: Buffer underrun. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
break;
|
||||
|
||||
default:
|
||||
err = GRUB_USB_ERR_NAK;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else if (err_unrec)
|
||||
{
|
||||
/* Don't try to get error code and last processed TD for proper
|
||||
* toggle bit value - anything can be invalid */
|
||||
err = GRUB_USB_ERR_UNRECOVERABLE;
|
||||
grub_dprintf("ohci", "Unrecoverable error!");
|
||||
|
||||
/* Do OHCI reset in case of unrecoverable error - maybe we will need
|
||||
* do more - re-enumerate bus etc. (?) */
|
||||
|
||||
/* Suspend the OHCI by issuing a reset. */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */
|
||||
/* Read back of register should ensure it is really written */
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
|
||||
grub_millisleep (1);
|
||||
grub_dprintf ("ohci", "Unrecoverable error - OHCI reset\n");
|
||||
|
||||
/* Misc. resets. */
|
||||
o->hcca->donehead = 0;
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, o->ed_ctrl_addr);
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0);
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, o->ed_bulk_addr);
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0);
|
||||
/* Read back of register should ensure it is really written */
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
|
||||
|
||||
/* Enable the OHCI. */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL,
|
||||
(2 << 6)
|
||||
| GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE
|
||||
| GRUB_OHCI_REG_CONTROL_BULK_ENABLE );
|
||||
}
|
||||
|
||||
else if (err_timeout)
|
||||
{
|
||||
/* In case of timeout do not detect error from TD */
|
||||
err = GRUB_ERR_TIMEOUT;
|
||||
grub_dprintf("ohci", "Timeout !\n");
|
||||
|
||||
/* We should wait for next SOF to be sure that ED is unaccessed
|
||||
* by OHCI */
|
||||
/* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2));
|
||||
/* Wait for new SOF */
|
||||
while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0);
|
||||
|
||||
/* Now we must find last processed TD if bad_OHCI == TRUE */
|
||||
if (o->bad_OHCI)
|
||||
{ /* Retired TD with error should be previous TD to ED->td_head */
|
||||
tderr_phys = grub_ohci_td_phys2virt (o,
|
||||
grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf)
|
||||
->prev_td_phys;
|
||||
}
|
||||
tderr_virt = grub_ohci_td_phys2virt (o, tderr_phys);
|
||||
if (tderr_virt)
|
||||
transfer->last_trans = tderr_virt->tr_index;
|
||||
else
|
||||
transfer->last_trans = -1;
|
||||
}
|
||||
static void
|
||||
finish_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer)
|
||||
{
|
||||
struct grub_ohci *o = dev->data;
|
||||
struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
|
||||
/* Set empty ED - set HEAD = TAIL = last (not processed) TD */
|
||||
ed_virt->td_head = grub_cpu_to_le32 (grub_le_to_cpu32 (ed_virt->td_tail) & ~0xf);
|
||||
cdata->ed_virt->td_head = grub_cpu_to_le32 (grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf);
|
||||
|
||||
/* At this point always should be:
|
||||
* ED has skip bit set and halted or empty or after next SOF,
|
||||
* i.e. it is safe to free all TDs except last not processed
|
||||
* ED HEAD == TAIL == phys. addr. of td_current_virt */
|
||||
|
||||
/* Reset DoneHead - sanity cleanup */
|
||||
/* Un-chainig of last TD */
|
||||
if (cdata->td_current_virt->prev_td_phys)
|
||||
{
|
||||
grub_ohci_td_t td_prev_virt
|
||||
= grub_ohci_td_phys2virt (o, cdata->td_current_virt->prev_td_phys);
|
||||
|
||||
if (cdata->td_current_virt == (grub_ohci_td_t) td_prev_virt->link_td)
|
||||
td_prev_virt->link_td = 0;
|
||||
|
||||
cdata->td_current_virt->prev_td_phys = 0;
|
||||
}
|
||||
|
||||
grub_dprintf ("ohci", "OHCI finished, freeing\n");
|
||||
grub_ohci_free_tds (o, cdata->td_head_virt);
|
||||
grub_free (cdata);
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
parse_halt (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
grub_size_t *actual)
|
||||
{
|
||||
struct grub_ohci *o = dev->data;
|
||||
struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
grub_uint8_t errcode = 0;
|
||||
grub_usb_err_t err = GRUB_USB_ERR_NAK;
|
||||
grub_ohci_td_t tderr_virt = NULL;
|
||||
|
||||
*actual = 0;
|
||||
|
||||
pre_finish_transfer (dev, transfer);
|
||||
|
||||
/* First we must get proper tderr_phys value */
|
||||
/* Retired TD with error should be previous TD to ED->td_head */
|
||||
cdata->tderr_phys = grub_ohci_td_phys2virt (o,
|
||||
grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf )
|
||||
->prev_td_phys;
|
||||
|
||||
/* Prepare pointer to last processed TD and get error code */
|
||||
tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys);
|
||||
/* Set index of last processed TD */
|
||||
if (tderr_virt)
|
||||
{
|
||||
errcode = grub_le_to_cpu32 (tderr_virt->token) >> 28;
|
||||
transfer->last_trans = tderr_virt->tr_index;
|
||||
}
|
||||
else
|
||||
transfer->last_trans = -1;
|
||||
|
||||
/* Evaluation of error code */
|
||||
grub_dprintf ("ohci", "OHCI tderr_phys=0x%02x, errcode=0x%02x\n",
|
||||
cdata->tderr_phys, errcode);
|
||||
switch (errcode)
|
||||
{
|
||||
case 0:
|
||||
/* XXX: Should not happen! */
|
||||
grub_error (GRUB_ERR_IO, "OHCI failed without reporting the reason");
|
||||
err = GRUB_USB_ERR_INTERNAL;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* XXX: CRC error. */
|
||||
err = GRUB_USB_ERR_TIMEOUT;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
err = GRUB_USB_ERR_BITSTUFF;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* XXX: Data Toggle error. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
err = GRUB_USB_ERR_STALL;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
/* XXX: Not responding. */
|
||||
err = GRUB_USB_ERR_TIMEOUT;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
/* XXX: PID Check bits failed. */
|
||||
err = GRUB_USB_ERR_BABBLE;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
/* XXX: PID unexpected failed. */
|
||||
err = GRUB_USB_ERR_BABBLE;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
/* XXX: Data overrun error. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n",
|
||||
tderr_virt, tderr_virt->tr_index);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
/* XXX: Data underrun error. */
|
||||
grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n",
|
||||
tderr_virt, tderr_virt->tr_index);
|
||||
if (transfer->last_trans == -1)
|
||||
break;
|
||||
*actual = transfer->transactions[transfer->last_trans].size
|
||||
- (grub_le_to_cpu32 (tderr_virt->buffer_end)
|
||||
- grub_le_to_cpu32 (tderr_virt->buffer))
|
||||
+ transfer->transactions[transfer->last_trans].preceding;
|
||||
err = GRUB_USB_ERR_NONE;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
/* XXX: Reserved. */
|
||||
err = GRUB_USB_ERR_NAK;
|
||||
break;
|
||||
|
||||
case 11:
|
||||
/* XXX: Reserved. */
|
||||
err = GRUB_USB_ERR_NAK;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
/* XXX: Buffer overrun. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
break;
|
||||
|
||||
case 13:
|
||||
/* XXX: Buffer underrun. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
break;
|
||||
|
||||
default:
|
||||
err = GRUB_USB_ERR_NAK;
|
||||
break;
|
||||
}
|
||||
|
||||
finish_transfer (dev, transfer);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
parse_success (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
grub_size_t *actual)
|
||||
{
|
||||
struct grub_ohci *o = dev->data;
|
||||
struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
grub_ohci_td_t tderr_virt = NULL;
|
||||
|
||||
pre_finish_transfer (dev, transfer);
|
||||
|
||||
/* I hope we can do it as transfer (most probably) finished OK */
|
||||
cdata->tderr_phys = cdata->td_last_phys;
|
||||
|
||||
/* Prepare pointer to last processed TD */
|
||||
tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys);
|
||||
|
||||
/* Set index of last processed TD */
|
||||
if (tderr_virt)
|
||||
transfer->last_trans = tderr_virt->tr_index;
|
||||
else
|
||||
transfer->last_trans = -1;
|
||||
*actual = transfer->size + 1;
|
||||
|
||||
finish_transfer (dev, transfer);
|
||||
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
parse_unrec (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
grub_size_t *actual)
|
||||
{
|
||||
struct grub_ohci *o = dev->data;
|
||||
|
||||
*actual = 0;
|
||||
|
||||
pre_finish_transfer (dev, transfer);
|
||||
|
||||
/* Don't try to get error code and last processed TD for proper
|
||||
* toggle bit value - anything can be invalid */
|
||||
grub_dprintf("ohci", "Unrecoverable error!");
|
||||
|
||||
/* Do OHCI reset in case of unrecoverable error - maybe we will need
|
||||
* do more - re-enumerate bus etc. (?) */
|
||||
|
||||
/* Suspend the OHCI by issuing a reset. */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */
|
||||
/* Read back of register should ensure it is really written */
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
|
||||
grub_millisleep (1);
|
||||
grub_dprintf ("ohci", "Unrecoverable error - OHCI reset\n");
|
||||
|
||||
/* Misc. resets. */
|
||||
o->hcca->donehead = 0;
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, o->ed_ctrl_addr);
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0);
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, o->ed_bulk_addr);
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0);
|
||||
/* Read back of register should ensure it is really written */
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
|
||||
|
||||
/* Un-chainig of last TD */
|
||||
if (td_current_virt->prev_td_phys)
|
||||
{
|
||||
grub_ohci_td_t td_prev_virt
|
||||
= grub_ohci_td_phys2virt (o, td_current_virt->prev_td_phys);
|
||||
/* Enable the OHCI. */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL,
|
||||
(2 << 6)
|
||||
| GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE
|
||||
| GRUB_OHCI_REG_CONTROL_BULK_ENABLE );
|
||||
finish_transfer (dev, transfer);
|
||||
|
||||
td_next_virt = (grub_ohci_td_t) td_prev_virt->link_td;
|
||||
if (td_current_virt == td_next_virt)
|
||||
td_prev_virt->link_td = 0;
|
||||
return GRUB_USB_ERR_UNRECOVERABLE;
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_ohci_check_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
grub_size_t *actual)
|
||||
{
|
||||
struct grub_ohci *o = dev->data;
|
||||
struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
grub_uint32_t intstatus;
|
||||
|
||||
/* Check transfer status */
|
||||
intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
|
||||
|
||||
if ((intstatus & 0x10) != 0)
|
||||
/* Unrecoverable error - only reset can help...! */
|
||||
return parse_unrec (dev, transfer, actual);
|
||||
|
||||
/* Detected a HALT. */
|
||||
if ((grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1))
|
||||
return parse_halt (dev, transfer, actual);
|
||||
|
||||
/* Finished ED detection */
|
||||
if ( (grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf) ==
|
||||
(grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf) ) /* Empty ED */
|
||||
{
|
||||
/* Check the HALT bit */
|
||||
/* It looks like nonsense - it was tested previously...
|
||||
* but it can change because OHCI is working
|
||||
* simultaneously via DMA... */
|
||||
if (grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1)
|
||||
return parse_halt (dev, transfer, actual);
|
||||
else
|
||||
return parse_success (dev, transfer, actual);
|
||||
}
|
||||
|
||||
grub_dprintf ("ohci", "OHCI finished, freeing, err=0x%02x, errcode=0x%02x\n",
|
||||
err, errcode);
|
||||
grub_ohci_free_tds (o, td_head_virt);
|
||||
return GRUB_USB_ERR_WAIT;
|
||||
}
|
||||
|
||||
return err;
|
||||
static grub_usb_err_t
|
||||
grub_ohci_cancel_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer)
|
||||
{
|
||||
struct grub_ohci *o = dev->data;
|
||||
struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
grub_ohci_td_t tderr_virt = NULL;
|
||||
|
||||
pre_finish_transfer (dev, transfer);
|
||||
|
||||
grub_dprintf("ohci", "Timeout !\n");
|
||||
|
||||
/* We should wait for next SOF to be sure that ED is unaccessed
|
||||
* by OHCI */
|
||||
/* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2));
|
||||
/* Wait for new SOF */
|
||||
while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0);
|
||||
|
||||
/* Possible retired TD with error should be previous TD to ED->td_head */
|
||||
cdata->tderr_phys
|
||||
= grub_ohci_td_phys2virt (o, grub_le_to_cpu32 (cdata->ed_virt->td_head)
|
||||
& ~0xf)->prev_td_phys;
|
||||
|
||||
tderr_virt = grub_ohci_td_phys2virt (o,cdata-> tderr_phys);
|
||||
|
||||
grub_dprintf ("ohci", "Cancel: tderr_phys=0x%x, tderr_virt=%p\n",
|
||||
cdata->tderr_phys, tderr_virt);
|
||||
|
||||
if (tderr_virt)
|
||||
transfer->last_trans = tderr_virt->tr_index;
|
||||
else
|
||||
transfer->last_trans = -1;
|
||||
|
||||
finish_transfer (dev, transfer);
|
||||
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
|
@ -1218,6 +1211,7 @@ grub_ohci_portstatus (grub_usb_controller_t dev,
|
|||
{
|
||||
struct grub_ohci *o = (struct grub_ohci *) dev->data;
|
||||
grub_uint64_t endtime;
|
||||
int i;
|
||||
|
||||
grub_dprintf ("ohci", "begin of portstatus=0x%02x\n",
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port));
|
||||
|
@ -1238,31 +1232,47 @@ grub_ohci_portstatus (grub_usb_controller_t dev,
|
|||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Reset the port */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_SET_PORT_RESET);
|
||||
grub_millisleep (50); /* For root hub should be nominaly 50ms */
|
||||
|
||||
/* End the reset signaling. */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE);
|
||||
grub_millisleep (10);
|
||||
/* OHCI does one reset signal 10ms long but USB spec.
|
||||
* requests 50ms for root hub (no need to be continuous).
|
||||
* So, we do reset 5 times... */
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
/* Reset the port - timing of reset is done by OHCI */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_SET_PORT_RESET);
|
||||
|
||||
/* Enable the port and wait for it. */
|
||||
/* Wait for reset completion */
|
||||
endtime = grub_get_time_ms () + 1000;
|
||||
while (! (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)
|
||||
& GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE))
|
||||
if (grub_get_time_ms () > endtime)
|
||||
return grub_error (GRUB_ERR_IO, "OHCI Timed out - reset");
|
||||
|
||||
/* End the reset signaling - reset the reset status change */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE);
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
|
||||
}
|
||||
|
||||
/* Enable port */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_SET_PORT_ENABLE);
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
|
||||
|
||||
/* Wait for signal enabled */
|
||||
endtime = grub_get_time_ms () + 1000;
|
||||
while (! (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)
|
||||
& (1 << 1)))
|
||||
if (grub_get_time_ms () > endtime)
|
||||
return grub_error (GRUB_ERR_IO, "OHCI Timed out - enable");
|
||||
|
||||
grub_millisleep (10);
|
||||
|
||||
/* Reset bit Connect Status Change */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_RESET_CONNECT_CHANGE);
|
||||
|
||||
/* "Reset recovery time" (USB spec.) */
|
||||
grub_millisleep (10);
|
||||
|
||||
grub_dprintf ("ohci", "end of portstatus=0x%02x\n",
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port));
|
||||
|
||||
|
@ -1279,8 +1289,16 @@ grub_ohci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
|
|||
|
||||
grub_dprintf ("ohci", "detect_dev status=0x%02x\n", status);
|
||||
|
||||
/* Connect Status Change bit - it detects change of connection */
|
||||
*changed = ((status & GRUB_OHCI_RESET_CONNECT_CHANGE) != 0);
|
||||
/* Connect Status Change bit - it detects change of connection */
|
||||
if (status & GRUB_OHCI_RESET_CONNECT_CHANGE)
|
||||
{
|
||||
*changed = 1;
|
||||
/* Reset bit Connect Status Change */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_RESET_CONNECT_CHANGE);
|
||||
}
|
||||
else
|
||||
*changed = 0;
|
||||
|
||||
if (! (status & 1))
|
||||
return GRUB_USB_SPEED_NONE;
|
||||
|
@ -1398,7 +1416,9 @@ static struct grub_usb_controller_dev usb_controller =
|
|||
{
|
||||
.name = "ohci",
|
||||
.iterate = grub_ohci_iterate,
|
||||
.transfer = grub_ohci_transfer,
|
||||
.setup_transfer = grub_ohci_setup_transfer,
|
||||
.check_transfer = grub_ohci_check_transfer,
|
||||
.cancel_transfer = grub_ohci_cancel_transfer,
|
||||
.hubports = grub_ohci_hubports,
|
||||
.portstatus = grub_ohci_portstatus,
|
||||
.detect_dev = grub_ohci_detect_dev
|
||||
|
|
|
@ -44,6 +44,7 @@ grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno,
|
|||
struct grub_serial_port *port;
|
||||
int j;
|
||||
struct grub_usb_desc_if *interf;
|
||||
grub_usb_err_t err = GRUB_USB_ERR_NONE;
|
||||
|
||||
interf = usbdev->config[configno].interf[interfno].descif;
|
||||
|
||||
|
@ -80,7 +81,12 @@ grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno,
|
|||
port->out_endp = endp;
|
||||
}
|
||||
}
|
||||
if (!port->out_endp || !port->in_endp)
|
||||
|
||||
/* Configure device */
|
||||
if (port->out_endp && port->in_endp)
|
||||
err = grub_usb_set_configuration (usbdev, configno + 1);
|
||||
|
||||
if (!port->out_endp || !port->in_endp || err)
|
||||
{
|
||||
grub_free (port->name);
|
||||
grub_free (port);
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#define GRUB_UHCI_IOMASK (0x7FF << 5)
|
||||
|
||||
#define N_QH 256
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GRUB_UHCI_REG_USBCMD = 0x00,
|
||||
|
@ -39,6 +41,19 @@ typedef enum
|
|||
#define GRUB_UHCI_LINK_TERMINATE 1
|
||||
#define GRUB_UHCI_LINK_QUEUE_HEAD 2
|
||||
|
||||
enum
|
||||
{
|
||||
GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED = 0x0002,
|
||||
GRUB_UHCI_REG_PORTSC_PORT_ENABLED = 0x0004,
|
||||
GRUB_UHCI_REG_PORTSC_RESUME = 0x0040,
|
||||
GRUB_UHCI_REG_PORTSC_RESET = 0x0200,
|
||||
GRUB_UHCI_REG_PORTSC_SUSPEND = 0x1000,
|
||||
GRUB_UHCI_REG_PORTSC_RW = GRUB_UHCI_REG_PORTSC_PORT_ENABLED
|
||||
| GRUB_UHCI_REG_PORTSC_RESUME | GRUB_UHCI_REG_PORTSC_RESET
|
||||
| GRUB_UHCI_REG_PORTSC_SUSPEND,
|
||||
/* These bits should not be written as 1 unless we really need it */
|
||||
GRUB_UHCI_PORTSC_RWC = ((1 << 1) | (1 << 3) | (1 << 11) | (3 << 13))
|
||||
};
|
||||
|
||||
/* UHCI Queue Head. */
|
||||
struct grub_uhci_qh
|
||||
|
@ -87,7 +102,7 @@ struct grub_uhci
|
|||
int iobase;
|
||||
grub_uint32_t *framelist;
|
||||
|
||||
/* 256 Queue Heads. */
|
||||
/* N_QH Queue Heads. */
|
||||
grub_uhci_qh_t qh;
|
||||
|
||||
/* 256 Transfer Descriptors. */
|
||||
|
@ -96,6 +111,8 @@ struct grub_uhci
|
|||
/* Free Transfer Descriptors. */
|
||||
grub_uhci_td_t tdfree;
|
||||
|
||||
int qh_busy[N_QH];
|
||||
|
||||
struct grub_uhci *next;
|
||||
};
|
||||
|
||||
|
@ -248,7 +265,7 @@ grub_uhci_pci_iter (grub_pci_device_t dev,
|
|||
(grub_uint32_t) (grub_addr_t) u->framelist);
|
||||
|
||||
/* Make the Queue Heads point to each other. */
|
||||
for (i = 0; i < 256; i++)
|
||||
for (i = 0; i < N_QH; i++)
|
||||
{
|
||||
/* Point to the next QH. */
|
||||
u->qh[i].linkptr = (grub_uint32_t) (grub_addr_t) (&u->qh[i + 1]) & (~15);
|
||||
|
@ -261,9 +278,8 @@ grub_uhci_pci_iter (grub_pci_device_t dev,
|
|||
u->qh[i].elinkptr = 1;
|
||||
}
|
||||
|
||||
/* The last Queue Head should terminate. 256 are too many QHs so
|
||||
just use 50. */
|
||||
u->qh[50 - 1].linkptr = 1;
|
||||
/* The last Queue Head should terminate. */
|
||||
u->qh[N_QH - 1].linkptr = 1;
|
||||
|
||||
/* Enable UHCI again. */
|
||||
grub_uhci_writereg16 (u, GRUB_UHCI_REG_USBCMD, 1 | (1 << 7));
|
||||
|
@ -332,11 +348,13 @@ grub_free_td (struct grub_uhci *u, grub_uhci_td_t td)
|
|||
}
|
||||
|
||||
static void
|
||||
grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td,
|
||||
grub_free_queue (struct grub_uhci *u, grub_uhci_qh_t qh, grub_uhci_td_t td,
|
||||
grub_usb_transfer_t transfer, grub_size_t *actual)
|
||||
{
|
||||
int i; /* Index of TD in transfer */
|
||||
|
||||
u->qh_busy[qh - u->qh] = 0;
|
||||
|
||||
*actual = 0;
|
||||
|
||||
/* Free the TDs in this queue and set last_trans. */
|
||||
|
@ -375,19 +393,21 @@ grub_alloc_qh (struct grub_uhci *u,
|
|||
#endif
|
||||
i = 1;
|
||||
|
||||
for (; i < 255; i++)
|
||||
for (; i < N_QH; i++)
|
||||
{
|
||||
if (u->qh[i].elinkptr & 1)
|
||||
if (!u->qh_busy[i])
|
||||
break;
|
||||
}
|
||||
qh = &u->qh[i];
|
||||
if (! (qh->elinkptr & 1))
|
||||
if (i == N_QH)
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
"no free queue heads available");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u->qh_busy[qh - u->qh] = 1;
|
||||
|
||||
return qh;
|
||||
}
|
||||
|
||||
|
@ -395,7 +415,7 @@ static grub_uhci_td_t
|
|||
grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
|
||||
grub_transfer_type_t type, unsigned int addr,
|
||||
unsigned int toggle, grub_size_t size,
|
||||
grub_uint32_t data)
|
||||
grub_uint32_t data, grub_usb_speed_t speed)
|
||||
{
|
||||
grub_uhci_td_t td;
|
||||
static const unsigned int tf[] = { 0x69, 0xE1, 0x2D };
|
||||
|
@ -420,7 +440,8 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
|
|||
td->linkptr = 1;
|
||||
|
||||
/* Active! Only retry a transfer 3 times. */
|
||||
td->ctrl_status = (1 << 23) | (3 << 27);
|
||||
td->ctrl_status = (1 << 23) | (3 << 27) |
|
||||
((speed == GRUB_USB_SPEED_LOW) ? (1 << 26) : 0);
|
||||
|
||||
/* If zero bytes are transmitted, size is 0x7FF. Otherwise size is
|
||||
size-1. */
|
||||
|
@ -438,26 +459,35 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
|
|||
return td;
|
||||
}
|
||||
|
||||
struct grub_uhci_transfer_controller_data
|
||||
{
|
||||
grub_uhci_qh_t qh;
|
||||
grub_uhci_td_t td_first;
|
||||
};
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_uhci_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
int timeout, grub_size_t *actual)
|
||||
grub_uhci_setup_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer)
|
||||
{
|
||||
struct grub_uhci *u = (struct grub_uhci *) dev->data;
|
||||
grub_uhci_qh_t qh;
|
||||
grub_uhci_td_t td;
|
||||
grub_uhci_td_t td_first = NULL;
|
||||
grub_uhci_td_t td_prev = NULL;
|
||||
grub_usb_err_t err = GRUB_USB_ERR_NONE;
|
||||
int i;
|
||||
grub_uint64_t endtime;
|
||||
struct grub_uhci_transfer_controller_data *cdata;
|
||||
|
||||
*actual = 0;
|
||||
cdata = grub_malloc (sizeof (*cdata));
|
||||
if (!cdata)
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
|
||||
cdata->td_first = NULL;
|
||||
|
||||
/* Allocate a queue head for the transfer queue. */
|
||||
qh = grub_alloc_qh (u, GRUB_USB_TRANSACTION_TYPE_CONTROL);
|
||||
if (! qh)
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
cdata->qh = grub_alloc_qh (u, GRUB_USB_TRANSACTION_TYPE_CONTROL);
|
||||
if (! cdata->qh)
|
||||
{
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
grub_dprintf ("uhci", "transfer, iobase:%08x\n", u->iobase);
|
||||
|
||||
|
@ -465,23 +495,26 @@ grub_uhci_transfer (grub_usb_controller_t dev,
|
|||
{
|
||||
grub_usb_transaction_t tr = &transfer->transactions[i];
|
||||
|
||||
td = grub_uhci_transaction (u, transfer->endpoint, tr->pid,
|
||||
td = grub_uhci_transaction (u, transfer->endpoint & 15, tr->pid,
|
||||
transfer->devaddr, tr->toggle,
|
||||
tr->size, tr->data);
|
||||
tr->size, tr->data,
|
||||
transfer->dev->speed);
|
||||
if (! td)
|
||||
{
|
||||
grub_size_t actual = 0;
|
||||
/* Terminate and free. */
|
||||
td_prev->linkptr2 = 0;
|
||||
td_prev->linkptr = 1;
|
||||
|
||||
if (td_first)
|
||||
grub_free_queue (u, td_first, NULL, actual);
|
||||
if (cdata->td_first)
|
||||
grub_free_queue (u, cdata->qh, cdata->td_first, NULL, &actual);
|
||||
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
if (! td_first)
|
||||
td_first = td;
|
||||
if (! cdata->td_first)
|
||||
cdata->td_first = td;
|
||||
else
|
||||
{
|
||||
td_prev->linkptr2 = (grub_uint32_t) (grub_addr_t) td;
|
||||
|
@ -497,81 +530,112 @@ grub_uhci_transfer (grub_usb_controller_t dev,
|
|||
|
||||
/* Link it into the queue and terminate. Now the transaction can
|
||||
take place. */
|
||||
qh->elinkptr = (grub_uint32_t) (grub_addr_t) td_first;
|
||||
cdata->qh->elinkptr = (grub_uint32_t) (grub_addr_t) cdata->td_first;
|
||||
|
||||
grub_dprintf ("uhci", "initiate transaction\n");
|
||||
|
||||
/* Wait until either the transaction completed or an error
|
||||
occurred. */
|
||||
endtime = grub_get_time_ms () + timeout;
|
||||
for (;;)
|
||||
transfer->controller_data = cdata;
|
||||
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_uhci_check_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
grub_size_t *actual)
|
||||
{
|
||||
struct grub_uhci *u = (struct grub_uhci *) dev->data;
|
||||
grub_uhci_td_t errtd;
|
||||
struct grub_uhci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
|
||||
*actual = 0;
|
||||
|
||||
errtd = (grub_uhci_td_t) (grub_addr_t) (cdata->qh->elinkptr & ~0x0f);
|
||||
|
||||
grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n",
|
||||
errtd->ctrl_status, errtd->buffer & (~15), errtd);
|
||||
|
||||
/* Check if the transaction completed. */
|
||||
if (cdata->qh->elinkptr & 1)
|
||||
{
|
||||
grub_uhci_td_t errtd;
|
||||
grub_dprintf ("uhci", "transaction complete\n");
|
||||
|
||||
errtd = (grub_uhci_td_t) (grub_addr_t) (qh->elinkptr & ~0x0f);
|
||||
/* Place the QH back in the free list and deallocate the associated
|
||||
TDs. */
|
||||
cdata->qh->elinkptr = 1;
|
||||
grub_free_queue (u, cdata->qh, cdata->td_first, transfer, actual);
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n",
|
||||
errtd->ctrl_status, errtd->buffer & (~15), errtd);
|
||||
grub_dprintf ("uhci", "t status=0x%02x\n", errtd->ctrl_status);
|
||||
|
||||
/* Check if the transaction completed. */
|
||||
if (qh->elinkptr & 1)
|
||||
break;
|
||||
|
||||
grub_dprintf ("uhci", "t status=0x%02x\n", errtd->ctrl_status);
|
||||
if (!(errtd->ctrl_status & (1 << 23)))
|
||||
{
|
||||
grub_usb_err_t err = GRUB_USB_ERR_NONE;
|
||||
|
||||
/* Check if the endpoint is stalled. */
|
||||
if (errtd->ctrl_status & (1 << 22))
|
||||
err = GRUB_USB_ERR_STALL;
|
||||
|
||||
|
||||
/* Check if an error related to the data buffer occurred. */
|
||||
if (errtd->ctrl_status & (1 << 21))
|
||||
else if (errtd->ctrl_status & (1 << 21))
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
|
||||
|
||||
/* Check if a babble error occurred. */
|
||||
if (errtd->ctrl_status & (1 << 20))
|
||||
else if (errtd->ctrl_status & (1 << 20))
|
||||
err = GRUB_USB_ERR_BABBLE;
|
||||
|
||||
|
||||
/* Check if a NAK occurred. */
|
||||
if (errtd->ctrl_status & (1 << 19))
|
||||
else if (errtd->ctrl_status & (1 << 19))
|
||||
err = GRUB_USB_ERR_NAK;
|
||||
|
||||
|
||||
/* Check if a timeout occurred. */
|
||||
if (errtd->ctrl_status & (1 << 18))
|
||||
else if (errtd->ctrl_status & (1 << 18))
|
||||
err = GRUB_USB_ERR_TIMEOUT;
|
||||
|
||||
|
||||
/* Check if a bitstuff error occurred. */
|
||||
if (errtd->ctrl_status & (1 << 17))
|
||||
else if (errtd->ctrl_status & (1 << 17))
|
||||
err = GRUB_USB_ERR_BITSTUFF;
|
||||
|
||||
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
/* Fall through, no errors occurred, so the QH might be
|
||||
updated. */
|
||||
grub_dprintf ("uhci", "transaction fallthrough\n");
|
||||
|
||||
if (grub_get_time_ms () > endtime)
|
||||
{
|
||||
err = GRUB_USB_ERR_STALL;
|
||||
grub_dprintf ("uhci", "transaction timed out\n");
|
||||
goto fail;
|
||||
grub_dprintf ("uhci", "transaction failed\n");
|
||||
|
||||
/* Place the QH back in the free list and deallocate the associated
|
||||
TDs. */
|
||||
cdata->qh->elinkptr = 1;
|
||||
grub_free_queue (u, cdata->qh, cdata->td_first, transfer, actual);
|
||||
grub_free (cdata);
|
||||
|
||||
return err;
|
||||
}
|
||||
grub_cpu_idle ();
|
||||
}
|
||||
|
||||
grub_dprintf ("uhci", "transaction complete\n");
|
||||
/* Fall through, no errors occurred, so the QH might be
|
||||
updated. */
|
||||
grub_dprintf ("uhci", "transaction fallthrough\n");
|
||||
|
||||
fail:
|
||||
return GRUB_USB_ERR_WAIT;
|
||||
}
|
||||
|
||||
if (err != GRUB_USB_ERR_NONE)
|
||||
grub_dprintf ("uhci", "transaction failed\n");
|
||||
static grub_usb_err_t
|
||||
grub_uhci_cancel_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer)
|
||||
{
|
||||
struct grub_uhci *u = (struct grub_uhci *) dev->data;
|
||||
grub_size_t actual;
|
||||
struct grub_uhci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
|
||||
grub_dprintf ("uhci", "transaction cancel\n");
|
||||
|
||||
/* Place the QH back in the free list and deallocate the associated
|
||||
TDs. */
|
||||
qh->elinkptr = 1;
|
||||
grub_free_queue (u, td_first, transfer, actual);
|
||||
cdata->qh->elinkptr = 1;
|
||||
grub_free_queue (u, cdata->qh, cdata->td_first, transfer, &actual);
|
||||
grub_free (cdata);
|
||||
|
||||
return err;
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -622,7 +686,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev,
|
|||
endtime = grub_get_time_ms () + 1000;
|
||||
while ((grub_uhci_readreg16 (u, reg) & (1 << 2)))
|
||||
if (grub_get_time_ms () > endtime)
|
||||
return grub_error (GRUB_ERR_IO, "UHCI Timed out");
|
||||
return grub_error (GRUB_ERR_IO, "UHCI Timed out - disable");
|
||||
|
||||
status = grub_uhci_readreg16 (u, reg);
|
||||
grub_dprintf ("uhci", ">3detect=0x%02x\n", status);
|
||||
|
@ -630,28 +694,37 @@ grub_uhci_portstatus (grub_usb_controller_t dev,
|
|||
}
|
||||
|
||||
/* Reset the port. */
|
||||
grub_uhci_writereg16 (u, reg, 1 << 9);
|
||||
status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_RWC;
|
||||
grub_uhci_writereg16 (u, reg, status | (1 << 9));
|
||||
grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */
|
||||
|
||||
/* Wait for the reset to complete. XXX: How long exactly? */
|
||||
grub_millisleep (50); /* For root hub should be nominaly 50ms */
|
||||
status = grub_uhci_readreg16 (u, reg);
|
||||
status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_RWC;
|
||||
grub_uhci_writereg16 (u, reg, status & ~(1 << 9));
|
||||
grub_dprintf ("uhci", "reset completed\n");
|
||||
grub_millisleep (10);
|
||||
grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */
|
||||
|
||||
/* Note: some debug prints were removed because they affected reset/enable timing. */
|
||||
|
||||
grub_millisleep (1); /* Probably not needed at all or only few microsecs. */
|
||||
|
||||
/* Reset bits Connect & Enable Status Change */
|
||||
status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_RWC;
|
||||
grub_uhci_writereg16 (u, reg, status | (1 << 3) | GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED);
|
||||
grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */
|
||||
|
||||
/* Enable the port. */
|
||||
grub_uhci_writereg16 (u, reg, 1 << 2);
|
||||
grub_millisleep (10);
|
||||
|
||||
grub_dprintf ("uhci", "waiting for the port to be enabled\n");
|
||||
status = grub_uhci_readreg16 (u, reg) & ~GRUB_UHCI_PORTSC_RWC;
|
||||
grub_uhci_writereg16 (u, reg, status | (1 << 2));
|
||||
grub_uhci_readreg16 (u, reg); /* Ensure it is writen... */
|
||||
|
||||
endtime = grub_get_time_ms () + 1000;
|
||||
while (! ((status = grub_uhci_readreg16 (u, reg)) & (1 << 2)))
|
||||
if (grub_get_time_ms () > endtime)
|
||||
return grub_error (GRUB_ERR_IO, "UHCI Timed out");
|
||||
return grub_error (GRUB_ERR_IO, "UHCI Timed out - enable");
|
||||
|
||||
/* Reset bit Connect Status Change */
|
||||
grub_uhci_writereg16 (u, reg, status | (1 << 1));
|
||||
/* Reset recovery time */
|
||||
grub_millisleep (10);
|
||||
|
||||
/* Read final port status */
|
||||
status = grub_uhci_readreg16 (u, reg);
|
||||
|
@ -683,7 +756,15 @@ grub_uhci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
|
|||
grub_dprintf ("uhci", "detect=0x%02x port=%d\n", status, port);
|
||||
|
||||
/* Connect Status Change bit - it detects change of connection */
|
||||
*changed = ((status & (1 << 1)) != 0);
|
||||
if (status & (1 << 1))
|
||||
{
|
||||
*changed = 1;
|
||||
/* Reset bit Connect Status Change */
|
||||
grub_uhci_writereg16 (u, reg, (status & GRUB_UHCI_REG_PORTSC_RW)
|
||||
| GRUB_UHCI_REG_PORTSC_CONNECT_CHANGED);
|
||||
}
|
||||
else
|
||||
*changed = 0;
|
||||
|
||||
if (! (status & 1))
|
||||
return GRUB_USB_SPEED_NONE;
|
||||
|
@ -705,7 +786,9 @@ static struct grub_usb_controller_dev usb_controller =
|
|||
{
|
||||
.name = "uhci",
|
||||
.iterate = grub_uhci_iterate,
|
||||
.transfer = grub_uhci_transfer,
|
||||
.setup_transfer = grub_uhci_setup_transfer,
|
||||
.check_transfer = grub_uhci_check_transfer,
|
||||
.cancel_transfer = grub_uhci_cancel_transfer,
|
||||
.hubports = grub_uhci_hubports,
|
||||
.portstatus = grub_uhci_portstatus,
|
||||
.detect_dev = grub_uhci_detect_dev
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
/* USB Supports 127 devices, with device 0 as special case. */
|
||||
static struct grub_usb_device *grub_usb_devs[GRUB_USBHUB_MAX_DEVICES];
|
||||
|
||||
static int rescan = 0;
|
||||
|
||||
struct grub_usb_hub
|
||||
{
|
||||
struct grub_usb_hub *next;
|
||||
|
@ -110,9 +112,6 @@ grub_usb_add_hub (grub_usb_device_t dev)
|
|||
struct grub_usb_usb_hubdesc hubdesc;
|
||||
grub_err_t err;
|
||||
int i;
|
||||
grub_uint64_t timeout;
|
||||
grub_usb_device_t next_dev;
|
||||
grub_usb_device_t *attached_devices;
|
||||
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
|
@ -131,11 +130,9 @@ grub_usb_add_hub (grub_usb_device_t dev)
|
|||
grub_dprintf ("usb", "Hub set configuration\n");
|
||||
grub_usb_set_configuration (dev, 1);
|
||||
|
||||
attached_devices = grub_zalloc (hubdesc.portcnt
|
||||
* sizeof (attached_devices[0]));
|
||||
if (!attached_devices)
|
||||
dev->children = grub_zalloc (hubdesc.portcnt * sizeof (dev->children[0]));
|
||||
if (!dev->children)
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
dev->children = attached_devices;
|
||||
dev->nports = hubdesc.portcnt;
|
||||
|
||||
/* Power on all Hub ports. */
|
||||
|
@ -143,115 +140,36 @@ grub_usb_add_hub (grub_usb_device_t dev)
|
|||
{
|
||||
grub_dprintf ("usb", "Power on - port %d\n", i);
|
||||
/* Power on the port and wait for possible device connect */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_SET_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_PORT_POWER,
|
||||
i, 0, NULL);
|
||||
/* Just ignore the device if some error happened */
|
||||
if (err)
|
||||
continue;
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_SET_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_PORT_POWER,
|
||||
i, 0, NULL);
|
||||
}
|
||||
/* Wait for port power-on */
|
||||
if (hubdesc.pwdgood >= 50)
|
||||
grub_millisleep (hubdesc.pwdgood * 2);
|
||||
else
|
||||
grub_millisleep (100);
|
||||
|
||||
/* Iterate over the Hub ports. */
|
||||
for (i = 1; i <= hubdesc.portcnt; i++)
|
||||
|
||||
/* Rest will be done on next usb poll. */
|
||||
for (i = 0; i < dev->config[0].interf[0].descif->endpointcnt;
|
||||
i++)
|
||||
{
|
||||
grub_uint32_t status;
|
||||
struct grub_usb_desc_endp *endp = NULL;
|
||||
endp = &dev->config[0].interf[0].descendp[i];
|
||||
|
||||
/* Get the port status. */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_GET_STATUS,
|
||||
0, i, sizeof (status), (char *) &status);
|
||||
/* Just ignore the device if the Hub does not report the
|
||||
status. */
|
||||
if (err)
|
||||
continue;
|
||||
grub_dprintf ("usb", "Hub port %d status: 0x%02x\n", i, status);
|
||||
|
||||
/* If connected, reset and enable the port. */
|
||||
if (status & GRUB_USB_HUB_STATUS_CONNECTED)
|
||||
if ((endp->endp_addr & 128) && grub_usb_get_ep_type(endp)
|
||||
== GRUB_USB_EP_INTERRUPT)
|
||||
{
|
||||
grub_usb_speed_t speed;
|
||||
|
||||
/* Determine the device speed. */
|
||||
if (status & GRUB_USB_HUB_STATUS_LOWSPEED)
|
||||
speed = GRUB_USB_SPEED_LOW;
|
||||
else
|
||||
{
|
||||
if (status & GRUB_USB_HUB_STATUS_HIGHSPEED)
|
||||
speed = GRUB_USB_SPEED_HIGH;
|
||||
else
|
||||
speed = GRUB_USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
/* A device is actually connected to this port.
|
||||
* Now do reset of port. */
|
||||
grub_dprintf ("usb", "Reset hub port - port %d\n", i);
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_SET_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_PORT_RESET,
|
||||
i, 0, 0);
|
||||
/* If the Hub does not cooperate for this port, just skip
|
||||
the port. */
|
||||
if (err)
|
||||
continue;
|
||||
|
||||
/* Wait for reset procedure done */
|
||||
timeout = grub_get_time_ms () + 1000;
|
||||
do
|
||||
{
|
||||
/* Get the port status. */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_GET_STATUS,
|
||||
0, i, sizeof (status), (char *) &status);
|
||||
}
|
||||
while (!err &&
|
||||
!(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) &&
|
||||
(grub_get_time_ms() < timeout) );
|
||||
if (err || !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) )
|
||||
continue;
|
||||
|
||||
/* Wait a recovery time after reset, spec. says 10ms */
|
||||
grub_millisleep (10);
|
||||
|
||||
/* Do reset of connection change bit */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_CONNECTED,
|
||||
i, 0, 0);
|
||||
/* Just ignore the device if the Hub reports some error */
|
||||
if (err)
|
||||
continue;
|
||||
grub_dprintf ("usb", "Hub port - cleared connection change\n");
|
||||
|
||||
/* Add the device and assign a device address to it. */
|
||||
grub_dprintf ("usb", "Call hub_add_dev - port %d\n", i);
|
||||
next_dev = grub_usb_hub_add_dev (&dev->controller, speed);
|
||||
if (! next_dev)
|
||||
continue;
|
||||
|
||||
attached_devices[i - 1] = next_dev;
|
||||
|
||||
/* If the device is a Hub, scan it for more devices. */
|
||||
if (next_dev->descdev.class == 0x09)
|
||||
grub_usb_add_hub (next_dev);
|
||||
dev->hub_endpoint = endp;
|
||||
dev->hub_transfer
|
||||
= grub_usb_bulk_read_background (dev, endp->endp_addr,
|
||||
grub_min (endp->maxpacket,
|
||||
sizeof (dev->statuschange)),
|
||||
(char *) &dev->statuschange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rescan = 1;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
|
@ -261,19 +179,45 @@ attach_root_port (struct grub_usb_hub *hub, int portno,
|
|||
{
|
||||
grub_usb_device_t dev;
|
||||
grub_err_t err;
|
||||
int total, i;
|
||||
grub_usb_speed_t current_speed = GRUB_USB_SPEED_NONE;
|
||||
int changed=0;
|
||||
|
||||
#if 0
|
||||
/* Specification does not say about disabling of port when device
|
||||
* connected. If disabling is really necessary for some devices,
|
||||
* delete this #if 0 and related #endif */
|
||||
/* Disable the port. XXX: Why? */
|
||||
err = hub->controller->dev->portstatus (hub->controller, portno, 0);
|
||||
if (err)
|
||||
return;
|
||||
#endif
|
||||
/* Wait for completion of insertion and stable power (USB spec.)
|
||||
* Should be at least 100ms, some devices requires more...
|
||||
* There is also another thing - some devices have worse contacts
|
||||
* and connected signal is unstable for some time - we should handle
|
||||
* it - but prevent deadlock in case when device is too faulty... */
|
||||
for (total = i = 0; (i < 250) && (total < 2000); i++, total++)
|
||||
{
|
||||
grub_millisleep (1);
|
||||
current_speed = hub->controller->dev->detect_dev
|
||||
(hub->controller, portno, &changed);
|
||||
if (current_speed == GRUB_USB_SPEED_NONE)
|
||||
i = 0;
|
||||
}
|
||||
grub_dprintf ("usb", "total=%d\n", total);
|
||||
if (total >= 2000)
|
||||
return;
|
||||
|
||||
/* Enable the port. */
|
||||
err = hub->controller->dev->portstatus (hub->controller, portno, 1);
|
||||
if (err)
|
||||
return;
|
||||
hub->controller->dev->pending_reset = grub_get_time_ms () + 5000;
|
||||
|
||||
/* Enable the port and create a device. */
|
||||
dev = grub_usb_hub_add_dev (hub->controller, speed);
|
||||
hub->controller->dev->pending_reset = 0;
|
||||
if (! dev)
|
||||
return;
|
||||
|
||||
|
@ -320,11 +264,14 @@ grub_usb_root_hub (grub_usb_controller_t controller)
|
|||
for (i = 0; i < hub->nports; i++)
|
||||
{
|
||||
grub_usb_speed_t speed;
|
||||
speed = controller->dev->detect_dev (hub->controller, i,
|
||||
&changed);
|
||||
if (!controller->dev->pending_reset)
|
||||
{
|
||||
speed = controller->dev->detect_dev (hub->controller, i,
|
||||
&changed);
|
||||
|
||||
if (speed != GRUB_USB_SPEED_NONE)
|
||||
attach_root_port (hub, i, speed);
|
||||
if (speed != GRUB_USB_SPEED_NONE)
|
||||
attach_root_port (hub, i, speed);
|
||||
}
|
||||
}
|
||||
|
||||
return GRUB_USB_ERR_NONE;
|
||||
|
@ -341,6 +288,9 @@ detach_device (grub_usb_device_t dev)
|
|||
return;
|
||||
if (dev->descdev.class == GRUB_USB_CLASS_HUB)
|
||||
{
|
||||
if (dev->hub_transfer)
|
||||
grub_usb_cancel_transfer (dev->hub_transfer);
|
||||
|
||||
for (i = 0; i < dev->nports; i++)
|
||||
detach_device (dev->children[i]);
|
||||
grub_free (dev->children);
|
||||
|
@ -359,16 +309,39 @@ detach_device (grub_usb_device_t dev)
|
|||
static void
|
||||
poll_nonroot_hub (grub_usb_device_t dev)
|
||||
{
|
||||
grub_err_t err;
|
||||
grub_usb_err_t err;
|
||||
unsigned i;
|
||||
grub_uint64_t timeout;
|
||||
grub_usb_device_t next_dev;
|
||||
grub_usb_device_t *attached_devices = dev->children;
|
||||
|
||||
grub_uint8_t changed;
|
||||
grub_size_t actual;
|
||||
int j, total;
|
||||
|
||||
if (!dev->hub_transfer)
|
||||
return;
|
||||
|
||||
err = grub_usb_check_transfer (dev->hub_transfer, &actual);
|
||||
|
||||
if (err == GRUB_USB_ERR_WAIT)
|
||||
return;
|
||||
|
||||
changed = dev->statuschange;
|
||||
|
||||
dev->hub_transfer
|
||||
= grub_usb_bulk_read_background (dev, dev->hub_endpoint->endp_addr,
|
||||
grub_min (dev->hub_endpoint->maxpacket,
|
||||
sizeof (dev->statuschange)),
|
||||
(char *) &dev->statuschange);
|
||||
|
||||
if (err || actual == 0 || changed == 0)
|
||||
return;
|
||||
|
||||
/* Iterate over the Hub ports. */
|
||||
for (i = 1; i <= dev->nports; i++)
|
||||
{
|
||||
grub_uint32_t status;
|
||||
grub_uint32_t current_status = 0;
|
||||
|
||||
if (!(changed & (1 << i)))
|
||||
continue;
|
||||
|
||||
/* Get the port status. */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
|
||||
|
@ -376,92 +349,140 @@ poll_nonroot_hub (grub_usb_device_t dev)
|
|||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_GET_STATUS,
|
||||
0, i, sizeof (status), (char *) &status);
|
||||
/* Just ignore the device if the Hub does not report the
|
||||
status. */
|
||||
|
||||
grub_printf ("dev = %p, i = %d, status = %08x\n",
|
||||
dev, i, status);
|
||||
|
||||
if (err)
|
||||
continue;
|
||||
|
||||
if (status & GRUB_USB_HUB_STATUS_C_CONNECTED)
|
||||
/* FIXME: properly handle these conditions. */
|
||||
if (status & GRUB_USB_HUB_STATUS_C_PORT_ENABLED)
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_PORT_ENABLED, i, 0, 0);
|
||||
|
||||
if (status & GRUB_USB_HUB_STATUS_C_PORT_SUSPEND)
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_PORT_SUSPEND, i, 0, 0);
|
||||
|
||||
if (status & GRUB_USB_HUB_STATUS_C_PORT_OVERCURRENT)
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_PORT_OVERCURRENT, i, 0, 0);
|
||||
|
||||
if (!dev->controller.dev->pending_reset &&
|
||||
(status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED))
|
||||
{
|
||||
detach_device (attached_devices[i-1]);
|
||||
attached_devices[i - 1] = NULL;
|
||||
}
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_PORT_CONNECTED, i, 0, 0);
|
||||
|
||||
detach_device (dev->children[i - 1]);
|
||||
dev->children[i - 1] = NULL;
|
||||
|
||||
/* Connected and status of connection changed ? */
|
||||
if ((status & GRUB_USB_HUB_STATUS_CONNECTED)
|
||||
&& (status & GRUB_USB_HUB_STATUS_C_CONNECTED))
|
||||
{
|
||||
grub_usb_speed_t speed;
|
||||
|
||||
/* Determine the device speed. */
|
||||
if (status & GRUB_USB_HUB_STATUS_LOWSPEED)
|
||||
speed = GRUB_USB_SPEED_LOW;
|
||||
else
|
||||
/* Connected and status of connection changed ? */
|
||||
if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)
|
||||
{
|
||||
if (status & GRUB_USB_HUB_STATUS_HIGHSPEED)
|
||||
speed = GRUB_USB_SPEED_HIGH;
|
||||
else
|
||||
speed = GRUB_USB_SPEED_FULL;
|
||||
/* A device is actually connected to this port. */
|
||||
/* Wait for completion of insertion and stable power (USB spec.)
|
||||
* Should be at least 100ms, some devices requires more...
|
||||
* There is also another thing - some devices have worse contacts
|
||||
* and connected signal is unstable for some time - we should handle
|
||||
* it - but prevent deadlock in case when device is too faulty... */
|
||||
for (total = j = 0; (j < 250) && (total < 2000); j++, total++)
|
||||
{
|
||||
grub_millisleep (1);
|
||||
/* Get the port status. */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_GET_STATUS,
|
||||
0, i,
|
||||
sizeof (current_status),
|
||||
(char *) ¤t_status);
|
||||
if (err)
|
||||
{
|
||||
total = 2000;
|
||||
break;
|
||||
}
|
||||
if (!(current_status & GRUB_USB_HUB_STATUS_PORT_CONNECTED))
|
||||
j = 0;
|
||||
}
|
||||
grub_dprintf ("usb", "(non-root) total=%d\n", total);
|
||||
if (total >= 2000)
|
||||
continue;
|
||||
|
||||
/* Now do reset of port. */
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_SET_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_PORT_RESET,
|
||||
i, 0, 0);
|
||||
rescan = 1;
|
||||
/* We cannot reset more than one device at the same time !
|
||||
* Resetting more devices together results in very bad
|
||||
* situation: more than one device has default address 0
|
||||
* at the same time !!!
|
||||
* Additionaly, we cannot perform another reset
|
||||
* anywhere on the same OHCI controller until
|
||||
* we will finish addressing of reseted device ! */
|
||||
dev->controller.dev->pending_reset = grub_get_time_ms () + 5000;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* A device is actually connected to this port.
|
||||
* Now do reset of port. */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_SET_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_PORT_RESET,
|
||||
i, 0, 0);
|
||||
/* If the Hub does not cooperate for this port, just skip
|
||||
the port. */
|
||||
if (err)
|
||||
continue;
|
||||
if (status & GRUB_USB_HUB_STATUS_C_PORT_RESET)
|
||||
{
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_PORT_RESET, i, 0, 0);
|
||||
|
||||
/* Wait for reset procedure done */
|
||||
timeout = grub_get_time_ms () + 1000;
|
||||
do
|
||||
{
|
||||
/* Get the port status. */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_GET_STATUS,
|
||||
0, i, sizeof (status), (char *) &status);
|
||||
}
|
||||
while (!err &&
|
||||
!(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) &&
|
||||
(grub_get_time_ms() < timeout) );
|
||||
if (err || !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) )
|
||||
continue;
|
||||
if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)
|
||||
{
|
||||
grub_usb_speed_t speed;
|
||||
grub_usb_device_t next_dev;
|
||||
|
||||
/* Wait a recovery time after reset, spec. says 10ms */
|
||||
grub_millisleep (10);
|
||||
/* Determine the device speed. */
|
||||
if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED)
|
||||
speed = GRUB_USB_SPEED_LOW;
|
||||
else
|
||||
{
|
||||
if (status & GRUB_USB_HUB_STATUS_PORT_HIGHSPEED)
|
||||
speed = GRUB_USB_SPEED_HIGH;
|
||||
else
|
||||
speed = GRUB_USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
/* Do reset of connection change bit */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_CONNECTED,
|
||||
i, 0, 0);
|
||||
/* Just ignore the device if the Hub reports some error */
|
||||
if (err)
|
||||
continue;
|
||||
/* Wait a recovery time after reset, spec. says 10ms */
|
||||
grub_millisleep (10);
|
||||
|
||||
/* Add the device and assign a device address to it. */
|
||||
next_dev = grub_usb_hub_add_dev (&dev->controller, speed);
|
||||
if (! next_dev)
|
||||
continue;
|
||||
/* Add the device and assign a device address to it. */
|
||||
next_dev = grub_usb_hub_add_dev (&dev->controller, speed);
|
||||
dev->controller.dev->pending_reset = 0;
|
||||
if (! next_dev)
|
||||
continue;
|
||||
|
||||
attached_devices[i - 1] = next_dev;
|
||||
dev->children[i - 1] = next_dev;
|
||||
|
||||
/* If the device is a Hub, scan it for more devices. */
|
||||
if (next_dev->descdev.class == 0x09)
|
||||
grub_usb_add_hub (next_dev);
|
||||
/* If the device is a Hub, scan it for more devices. */
|
||||
if (next_dev->descdev.class == 0x09)
|
||||
grub_usb_add_hub (next_dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -476,12 +497,21 @@ grub_usb_poll_devices (void)
|
|||
/* No, it should be never changed, it should be constant. */
|
||||
for (i = 0; i < hub->nports; i++)
|
||||
{
|
||||
grub_usb_speed_t speed;
|
||||
grub_usb_speed_t speed = GRUB_USB_SPEED_NONE;
|
||||
int changed = 0;
|
||||
|
||||
speed = hub->controller->dev->detect_dev (hub->controller, i,
|
||||
&changed);
|
||||
|
||||
if (!hub->controller->dev->pending_reset)
|
||||
{
|
||||
/* Check for possible timeout */
|
||||
if (grub_get_time_ms () > hub->controller->dev->pending_reset)
|
||||
{
|
||||
/* Something went wrong, reset device was not
|
||||
* addressed properly, timeout happened */
|
||||
hub->controller->dev->pending_reset = 0;
|
||||
speed = hub->controller->dev->detect_dev (hub->controller,
|
||||
i, &changed);
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
detach_device (hub->devices[i]);
|
||||
|
@ -492,13 +522,21 @@ grub_usb_poll_devices (void)
|
|||
}
|
||||
}
|
||||
|
||||
/* We should check changes of non-root hubs too. */
|
||||
for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++)
|
||||
while (1)
|
||||
{
|
||||
grub_usb_device_t dev = grub_usb_devs[i];
|
||||
|
||||
if (dev && dev->descdev.class == 0x09)
|
||||
poll_nonroot_hub (dev);
|
||||
rescan = 0;
|
||||
|
||||
/* We should check changes of non-root hubs too. */
|
||||
for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++)
|
||||
{
|
||||
grub_usb_device_t dev = grub_usb_devs[i];
|
||||
|
||||
if (dev && dev->descdev.class == 0x09)
|
||||
poll_nonroot_hub (dev);
|
||||
}
|
||||
if (!rescan)
|
||||
break;
|
||||
grub_millisleep (50);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,41 @@
|
|||
#include <grub/misc.h>
|
||||
#include <grub/usb.h>
|
||||
#include <grub/usbtrans.h>
|
||||
#include <grub/time.h>
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_usb_execute_and_wait_transfer (grub_usb_device_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
int timeout, grub_size_t *actual)
|
||||
{
|
||||
grub_usb_err_t err;
|
||||
grub_uint64_t endtime;
|
||||
|
||||
err = dev->controller.dev->setup_transfer (&dev->controller, transfer);
|
||||
if (err)
|
||||
return err;
|
||||
/* endtime moved behind setup transfer to prevent false timeouts
|
||||
* while debugging... */
|
||||
endtime = grub_get_time_ms () + timeout;
|
||||
while (1)
|
||||
{
|
||||
err = dev->controller.dev->check_transfer (&dev->controller, transfer,
|
||||
actual);
|
||||
if (!err)
|
||||
return GRUB_USB_ERR_NONE;
|
||||
if (err != GRUB_USB_ERR_WAIT)
|
||||
return err;
|
||||
if (grub_get_time_ms () > endtime)
|
||||
{
|
||||
err = dev->controller.dev->cancel_transfer (&dev->controller,
|
||||
transfer);
|
||||
if (err)
|
||||
return err;
|
||||
return GRUB_USB_ERR_TIMEOUT;
|
||||
}
|
||||
grub_cpu_idle ();
|
||||
}
|
||||
}
|
||||
|
||||
grub_usb_err_t
|
||||
grub_usb_control_msg (grub_usb_device_t dev,
|
||||
|
@ -147,8 +182,8 @@ grub_usb_control_msg (grub_usb_device_t dev,
|
|||
|
||||
transfer->transactions[datablocks + 1].toggle = 1;
|
||||
|
||||
err = dev->controller.dev->transfer (&dev->controller, transfer,
|
||||
1000, &actual);
|
||||
err = grub_usb_execute_and_wait_transfer (dev, transfer, 1000, &actual);
|
||||
|
||||
grub_dprintf ("usb", "control: err=%d\n", err);
|
||||
|
||||
grub_free (transfer->transactions);
|
||||
|
@ -162,22 +197,20 @@ grub_usb_control_msg (grub_usb_device_t dev,
|
|||
return err;
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_usb_bulk_readwrite (grub_usb_device_t dev,
|
||||
int endpoint, grub_size_t size0, char *data_in,
|
||||
grub_transfer_type_t type, int timeout,
|
||||
grub_size_t *actual)
|
||||
static grub_usb_transfer_t
|
||||
grub_usb_bulk_setup_readwrite (grub_usb_device_t dev,
|
||||
int endpoint, grub_size_t size0, char *data_in,
|
||||
grub_transfer_type_t type)
|
||||
{
|
||||
int i;
|
||||
grub_usb_transfer_t transfer;
|
||||
int datablocks;
|
||||
unsigned int max;
|
||||
grub_usb_err_t err;
|
||||
int toggle = dev->toggle[endpoint];
|
||||
volatile char *data;
|
||||
grub_uint32_t data_addr;
|
||||
struct grub_pci_dma_chunk *data_chunk;
|
||||
grub_size_t size = size0;
|
||||
int toggle = dev->toggle[endpoint];
|
||||
|
||||
grub_dprintf ("usb", "bulk: size=0x%02lx type=%d\n", (unsigned long) size,
|
||||
type);
|
||||
|
@ -185,7 +218,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
|
|||
/* FIXME: avoid allocation any kind of buffer in a first place. */
|
||||
data_chunk = grub_memalign_dma32 (128, size);
|
||||
if (!data_chunk)
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
return NULL;
|
||||
data = grub_dma_get_virt (data_chunk);
|
||||
data_addr = grub_dma_get_phys (data_chunk);
|
||||
if (type == GRUB_USB_TRANSFER_TYPE_OUT)
|
||||
|
@ -210,18 +243,21 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
|
|||
if (! transfer)
|
||||
{
|
||||
grub_dma_free (data_chunk);
|
||||
return grub_errno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
datablocks = ((size + max - 1) / max);
|
||||
transfer->transcnt = datablocks;
|
||||
transfer->size = size - 1;
|
||||
transfer->endpoint = endpoint & 15;
|
||||
transfer->endpoint = endpoint;
|
||||
transfer->devaddr = dev->addr;
|
||||
transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK;
|
||||
transfer->dir = type;
|
||||
transfer->max = max;
|
||||
transfer->dev = dev;
|
||||
transfer->last_trans = -1; /* Reset index of last processed transaction (TD) */
|
||||
transfer->data_chunk = data_chunk;
|
||||
transfer->data = data_in;
|
||||
|
||||
/* Allocate an array of transfer data structures. */
|
||||
transfer->transactions = grub_malloc (transfer->transcnt
|
||||
|
@ -230,7 +266,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
|
|||
{
|
||||
grub_free (transfer);
|
||||
grub_dma_free (data_chunk);
|
||||
return grub_errno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set up all transfers. */
|
||||
|
@ -248,25 +284,51 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
|
|||
tr->preceding = i * max;
|
||||
size -= tr->size;
|
||||
}
|
||||
return transfer;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_usb_bulk_finish_readwrite (grub_usb_transfer_t transfer)
|
||||
{
|
||||
grub_usb_device_t dev = transfer->dev;
|
||||
int toggle = dev->toggle[transfer->endpoint];
|
||||
|
||||
err = dev->controller.dev->transfer (&dev->controller, transfer, timeout,
|
||||
actual);
|
||||
/* We must remember proper toggle value even if some transactions
|
||||
* were not processed - correct value should be inversion of last
|
||||
* processed transaction (TD). */
|
||||
if (transfer->last_trans >= 0)
|
||||
toggle = transfer->transactions[transfer->last_trans].toggle ? 0 : 1;
|
||||
else
|
||||
toggle = dev->toggle[endpoint]; /* Nothing done, take original */
|
||||
grub_dprintf ("usb", "bulk: err=%d, toggle=%d\n", err, toggle);
|
||||
dev->toggle[endpoint] = toggle;
|
||||
toggle = dev->toggle[transfer->endpoint]; /* Nothing done, take original */
|
||||
grub_dprintf ("usb", "bulk: toggle=%d\n", toggle);
|
||||
dev->toggle[transfer->endpoint] = toggle;
|
||||
|
||||
if (transfer->dir == GRUB_USB_TRANSFER_TYPE_IN)
|
||||
grub_memcpy (transfer->data, (void *)
|
||||
grub_dma_get_virt (transfer->data_chunk),
|
||||
transfer->size + 1);
|
||||
|
||||
grub_free (transfer->transactions);
|
||||
grub_free (transfer);
|
||||
grub_dma_free (data_chunk);
|
||||
grub_dma_free (transfer->data_chunk);
|
||||
}
|
||||
|
||||
if (type == GRUB_USB_TRANSFER_TYPE_IN)
|
||||
grub_memcpy (data_in, (char *) data, size0);
|
||||
static grub_usb_err_t
|
||||
grub_usb_bulk_readwrite (grub_usb_device_t dev,
|
||||
int endpoint, grub_size_t size0, char *data_in,
|
||||
grub_transfer_type_t type, int timeout,
|
||||
grub_size_t *actual)
|
||||
{
|
||||
grub_usb_err_t err;
|
||||
grub_usb_transfer_t transfer;
|
||||
|
||||
transfer = grub_usb_bulk_setup_readwrite (dev, endpoint, size0,
|
||||
data_in, type);
|
||||
if (!transfer)
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
err = grub_usb_execute_and_wait_transfer (dev, transfer, timeout, actual);
|
||||
|
||||
grub_usb_bulk_finish_readwrite (transfer);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -298,6 +360,49 @@ grub_usb_bulk_read (grub_usb_device_t dev,
|
|||
return err;
|
||||
}
|
||||
|
||||
grub_usb_err_t
|
||||
grub_usb_check_transfer (grub_usb_transfer_t transfer, grub_size_t *actual)
|
||||
{
|
||||
grub_usb_err_t err;
|
||||
grub_usb_device_t dev = transfer->dev;
|
||||
|
||||
err = dev->controller.dev->check_transfer (&dev->controller, transfer,
|
||||
actual);
|
||||
if (err == GRUB_USB_ERR_WAIT)
|
||||
return err;
|
||||
|
||||
grub_usb_bulk_finish_readwrite (transfer);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
grub_usb_transfer_t
|
||||
grub_usb_bulk_read_background (grub_usb_device_t dev,
|
||||
int endpoint, grub_size_t size, void *data)
|
||||
{
|
||||
grub_usb_err_t err;
|
||||
grub_usb_transfer_t transfer;
|
||||
|
||||
transfer = grub_usb_bulk_setup_readwrite (dev, endpoint, size,
|
||||
data, GRUB_USB_TRANSFER_TYPE_IN);
|
||||
if (!transfer)
|
||||
return NULL;
|
||||
|
||||
err = dev->controller.dev->setup_transfer (&dev->controller, transfer);
|
||||
if (err)
|
||||
return NULL;
|
||||
|
||||
return transfer;
|
||||
}
|
||||
|
||||
void
|
||||
grub_usb_cancel_transfer (grub_usb_transfer_t transfer)
|
||||
{
|
||||
grub_usb_device_t dev = transfer->dev;
|
||||
dev->controller.dev->cancel_transfer (&dev->controller, transfer);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_usb_err_t
|
||||
grub_usb_bulk_read_extended (grub_usb_device_t dev,
|
||||
int endpoint, grub_size_t size, char *data,
|
||||
|
|
|
@ -23,10 +23,8 @@
|
|||
#include <grub/disk.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/gzio.h>
|
||||
#include <grub/acpi.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/memory.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
|
@ -152,10 +150,10 @@ grub_acpi_create_ebda (void)
|
|||
auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t,
|
||||
grub_uint32_t);
|
||||
int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t size,
|
||||
grub_uint32_t type)
|
||||
grub_memory_type_t type)
|
||||
{
|
||||
grub_uint64_t end = start + size;
|
||||
if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
|
||||
if (type != GRUB_MEMORY_AVAILABLE)
|
||||
return 0;
|
||||
if (end > 0x100000)
|
||||
end = 0x100000;
|
||||
|
@ -181,7 +179,7 @@ grub_acpi_create_ebda (void)
|
|||
"couldn't find space for the new EBDA");
|
||||
|
||||
mmapregion = grub_mmap_register (PTR_TO_UINT64 (targetebda), ebda_len,
|
||||
GRUB_MACHINE_MEMORY_RESERVED);
|
||||
GRUB_MEMORY_RESERVED);
|
||||
if (! mmapregion)
|
||||
return grub_errno;
|
||||
|
||||
|
@ -325,7 +323,7 @@ setup_common_tables (void)
|
|||
|
||||
/* If it's FADT correct DSDT and FACS addresses. */
|
||||
fadt = (struct grub_acpi_fadt *) cur->addr;
|
||||
if (grub_memcmp (fadt->hdr.signature, "FACP",
|
||||
if (grub_memcmp (fadt->hdr.signature, GRUB_ACPI_FADT_SIGNATURE,
|
||||
sizeof (fadt->hdr.signature)) == 0)
|
||||
{
|
||||
fadt->dsdt_addr = PTR_TO_UINT32 (table_dsdt);
|
||||
|
@ -458,10 +456,9 @@ free_tables (void)
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_acpi (struct grub_extcmd *cmd,
|
||||
int argc, char **args)
|
||||
grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
struct grub_acpi_rsdp_v10 *rsdp;
|
||||
struct efiemu_acpi_table *cur, *t;
|
||||
grub_err_t err;
|
||||
|
@ -529,7 +526,7 @@ grub_cmd_acpi (struct grub_extcmd *cmd,
|
|||
struct grub_acpi_fadt *fadt = (struct grub_acpi_fadt *) curtable;
|
||||
|
||||
/* Set root header variables to the same values
|
||||
as FACP by default. */
|
||||
as FADT by default. */
|
||||
grub_memcpy (&root_oemid, &(fadt->hdr.oemid),
|
||||
sizeof (root_oemid));
|
||||
grub_memcpy (&root_oemtable, &(fadt->hdr.oemtable),
|
||||
|
@ -629,7 +626,7 @@ grub_cmd_acpi (struct grub_extcmd *cmd,
|
|||
grub_size_t size;
|
||||
char *buf;
|
||||
|
||||
file = grub_gzfile_open (args[i], 1);
|
||||
file = grub_file_open (args[i]);
|
||||
if (! file)
|
||||
{
|
||||
free_tables ();
|
||||
|
@ -706,7 +703,7 @@ grub_cmd_acpi (struct grub_extcmd *cmd,
|
|||
|
||||
playground = playground_ptr
|
||||
= grub_mmap_malign_and_register (1, playground_size, &mmapregion,
|
||||
GRUB_MACHINE_MEMORY_ACPI, 0);
|
||||
GRUB_MEMORY_ACPI, 0);
|
||||
|
||||
if (! playground)
|
||||
{
|
||||
|
@ -760,8 +757,7 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(acpi)
|
||||
{
|
||||
cmd = grub_register_extcmd ("acpi", grub_cmd_acpi,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd = grub_register_extcmd ("acpi", grub_cmd_acpi, 0,
|
||||
N_("[-1|-2] [--exclude=TABLE1,TABLE2|"
|
||||
"--load-only=table1,table2] FILE1"
|
||||
" [FILE2] [...]"),
|
||||
|
|
266
grub-core/commands/acpihalt.c
Normal file
266
grub-core/commands/acpihalt.c
Normal file
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 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/acpi.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/cpu/io.h>
|
||||
|
||||
static inline grub_uint32_t
|
||||
decode_length (const grub_uint8_t *ptr, int *numlen)
|
||||
{
|
||||
int num_bytes, i;
|
||||
grub_uint32_t ret;
|
||||
if (*ptr < 64)
|
||||
{
|
||||
if (numlen)
|
||||
*numlen = 1;
|
||||
return *ptr;
|
||||
}
|
||||
num_bytes = *ptr >> 6;
|
||||
if (numlen)
|
||||
*numlen = num_bytes + 1;
|
||||
ret = *ptr & 0xf;
|
||||
ptr++;
|
||||
for (i = 0; i < num_bytes; i++)
|
||||
{
|
||||
ret |= *ptr << (8 * i + 4);
|
||||
ptr++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline grub_uint32_t
|
||||
skip_name_string (const grub_uint8_t *ptr, const grub_uint8_t *end)
|
||||
{
|
||||
const grub_uint8_t *ptr0 = ptr;
|
||||
|
||||
while (ptr < end && (*ptr == '^' || *ptr == '\\'))
|
||||
ptr++;
|
||||
switch (*ptr)
|
||||
{
|
||||
case '.':
|
||||
ptr++;
|
||||
ptr += 8;
|
||||
break;
|
||||
case '/':
|
||||
ptr++;
|
||||
ptr += 1 + (*ptr) * 4;
|
||||
break;
|
||||
case 0:
|
||||
ptr++;
|
||||
break;
|
||||
default:
|
||||
ptr += 4;
|
||||
break;
|
||||
}
|
||||
return ptr - ptr0;
|
||||
}
|
||||
|
||||
static inline grub_uint32_t
|
||||
skip_data_ref_object (const grub_uint8_t *ptr, const grub_uint8_t *end)
|
||||
{
|
||||
grub_dprintf ("acpi", "data type = 0x%x\n", *ptr);
|
||||
switch (*ptr)
|
||||
{
|
||||
case GRUB_ACPI_OPCODE_PACKAGE:
|
||||
return 1 + decode_length (ptr + 1, 0);
|
||||
case GRUB_ACPI_OPCODE_ZERO:
|
||||
case GRUB_ACPI_OPCODE_ONES:
|
||||
case GRUB_ACPI_OPCODE_ONE:
|
||||
return 1;
|
||||
case GRUB_ACPI_OPCODE_BYTE_CONST:
|
||||
return 2;
|
||||
case GRUB_ACPI_OPCODE_WORD_CONST:
|
||||
return 3;
|
||||
case GRUB_ACPI_OPCODE_DWORD_CONST:
|
||||
return 5;
|
||||
default:
|
||||
if (*ptr == '^' || *ptr == '\\' || *ptr == '_'
|
||||
|| (*ptr >= 'A' && *ptr <= 'Z'))
|
||||
return skip_name_string (ptr, end);
|
||||
grub_printf ("Unknown opcode 0x%x\n", *ptr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline grub_uint32_t
|
||||
skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end)
|
||||
{
|
||||
const grub_uint8_t *ptr0 = ptr;
|
||||
int add;
|
||||
grub_dprintf ("acpi", "Extended opcode: 0x%x\n", *ptr);
|
||||
switch (*ptr)
|
||||
{
|
||||
case GRUB_ACPI_EXTOPCODE_MUTEX:
|
||||
ptr++;
|
||||
ptr += skip_name_string (ptr, end);
|
||||
ptr++;
|
||||
break;
|
||||
case GRUB_ACPI_EXTOPCODE_OPERATION_REGION:
|
||||
ptr++;
|
||||
ptr += skip_name_string (ptr, end);
|
||||
ptr++;
|
||||
ptr += add = skip_data_ref_object (ptr, end);
|
||||
if (!add)
|
||||
return 0;
|
||||
ptr += add = skip_data_ref_object (ptr, end);
|
||||
if (!add)
|
||||
return 0;
|
||||
break;
|
||||
case GRUB_ACPI_EXTOPCODE_FIELD_OP:
|
||||
ptr++;
|
||||
ptr += decode_length (ptr, 0);
|
||||
break;
|
||||
default:
|
||||
grub_printf ("Unexpected extended opcode: 0x%x\n", *ptr);
|
||||
return 0;
|
||||
}
|
||||
return ptr - ptr0;
|
||||
}
|
||||
|
||||
static int
|
||||
get_sleep_type (grub_uint8_t *table, grub_uint8_t *end)
|
||||
{
|
||||
grub_uint8_t *ptr, *prev;
|
||||
int sleep_type = -1;
|
||||
|
||||
ptr = table + sizeof (struct grub_acpi_table_header);
|
||||
while (ptr < end && prev < ptr)
|
||||
{
|
||||
int add;
|
||||
prev = ptr;
|
||||
grub_dprintf ("acpi", "Opcode 0x%x\n", *ptr);
|
||||
grub_dprintf ("acpi", "Tell %x\n", (unsigned) (ptr - table));
|
||||
switch (*ptr)
|
||||
{
|
||||
case GRUB_ACPI_OPCODE_EXTOP:
|
||||
ptr++;
|
||||
ptr += add = skip_ext_op (ptr, end);
|
||||
if (!add)
|
||||
return -1;
|
||||
break;
|
||||
case GRUB_ACPI_OPCODE_NAME:
|
||||
ptr++;
|
||||
if (memcmp (ptr, "_S5_", 4) == 0)
|
||||
{
|
||||
int ll;
|
||||
grub_uint8_t *ptr2 = ptr;
|
||||
ptr2 += 4;
|
||||
if (*ptr2 != 0x12)
|
||||
{
|
||||
grub_printf ("Unknown opcode in _S5: 0x%x\n", *ptr2);
|
||||
return -1;
|
||||
}
|
||||
ptr2++;
|
||||
decode_length (ptr2, &ll);
|
||||
ptr2 += ll;
|
||||
ptr2++;
|
||||
switch (*ptr2)
|
||||
{
|
||||
case GRUB_ACPI_OPCODE_ZERO:
|
||||
sleep_type = 0;
|
||||
break;
|
||||
case GRUB_ACPI_OPCODE_ONE:
|
||||
sleep_type = 1;
|
||||
break;
|
||||
case GRUB_ACPI_OPCODE_BYTE_CONST:
|
||||
sleep_type = ptr2[1];
|
||||
break;
|
||||
default:
|
||||
grub_printf ("Unknown data type in _S5: 0x%x\n", *ptr2);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ptr += add = skip_name_string (ptr, end);
|
||||
if (!add)
|
||||
return -1;
|
||||
ptr += add = skip_data_ref_object (ptr, end);
|
||||
if (!add)
|
||||
return -1;
|
||||
break;
|
||||
case GRUB_ACPI_OPCODE_SCOPE:
|
||||
case GRUB_ACPI_OPCODE_IF:
|
||||
case GRUB_ACPI_OPCODE_METHOD:
|
||||
{
|
||||
ptr++;
|
||||
ptr += decode_length (ptr, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
grub_dprintf ("acpi", "TYP = %d\n", sleep_type);
|
||||
return sleep_type;
|
||||
}
|
||||
|
||||
void
|
||||
grub_acpi_halt (void)
|
||||
{
|
||||
struct grub_acpi_rsdp_v20 *rsdp2;
|
||||
struct grub_acpi_rsdp_v10 *rsdp1;
|
||||
struct grub_acpi_table_header *rsdt;
|
||||
grub_uint32_t *entry_ptr;
|
||||
|
||||
rsdp2 = grub_acpi_get_rsdpv2 ();
|
||||
if (rsdp2)
|
||||
rsdp1 = &(rsdp2->rsdpv1);
|
||||
else
|
||||
rsdp1 = grub_acpi_get_rsdpv1 ();
|
||||
grub_dprintf ("acpi", "rsdp1=%p\n", rsdp1);
|
||||
if (!rsdp1)
|
||||
return;
|
||||
|
||||
rsdt = (struct grub_acpi_table_header *) (grub_addr_t) rsdp1->rsdt_addr;
|
||||
for (entry_ptr = (grub_uint32_t *) (rsdt + 1);
|
||||
entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt)
|
||||
+ rsdt->length);
|
||||
entry_ptr++)
|
||||
{
|
||||
if (grub_memcmp ((void *) (grub_addr_t) *entry_ptr, "FACP", 4) == 0)
|
||||
{
|
||||
grub_uint32_t port;
|
||||
struct grub_acpi_fadt *fadt
|
||||
= ((struct grub_acpi_fadt *) (grub_addr_t) *entry_ptr);
|
||||
struct grub_acpi_table_header *dsdt
|
||||
= (struct grub_acpi_table_header *) (grub_addr_t) fadt->dsdt_addr;
|
||||
int sleep_type = -1;
|
||||
|
||||
port = fadt->pm1a;
|
||||
|
||||
grub_dprintf ("acpi", "PM1a port=%x\n", port);
|
||||
|
||||
if (grub_memcmp (dsdt->signature, "DSDT",
|
||||
sizeof (dsdt->signature)) != 0)
|
||||
break;
|
||||
|
||||
sleep_type = get_sleep_type ((grub_uint8_t *) dsdt,
|
||||
(grub_uint8_t *) dsdt + dsdt->length);
|
||||
|
||||
if (sleep_type < 0 || sleep_type >= 8)
|
||||
break;
|
||||
|
||||
grub_dprintf ("acpi", "SLP_TYP = %d, port = 0x%x\n",
|
||||
sleep_type, port);
|
||||
|
||||
grub_outw (GRUB_ACPI_SLP_EN
|
||||
| (sleep_type << GRUB_ACPI_SLP_TYP_OFFSET), port & 0xffff);
|
||||
}
|
||||
}
|
||||
|
||||
grub_printf ("ACPI shutdown failed\n");
|
||||
}
|
|
@ -82,6 +82,7 @@ grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)),
|
|||
if (argc < 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
|
||||
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (args[0]);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include <grub/disk.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/gzio.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
|
@ -33,9 +32,9 @@ static const struct grub_arg_option options[] =
|
|||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_cat (grub_extcmd_t cmd, int argc, char **args)
|
||||
grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
int dos = 0;
|
||||
grub_file_t file;
|
||||
char buf[GRUB_DISK_SECTOR_SIZE];
|
||||
|
@ -48,7 +47,7 @@ grub_cmd_cat (grub_extcmd_t cmd, int argc, char **args)
|
|||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
|
||||
|
||||
file = grub_gzfile_open (args[0], 1);
|
||||
file = grub_file_open (args[0]);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
|
@ -77,7 +76,7 @@ grub_cmd_cat (grub_extcmd_t cmd, int argc, char **args)
|
|||
}
|
||||
|
||||
while (grub_checkkey () >= 0 &&
|
||||
(key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != GRUB_TERM_ESC)
|
||||
(key = grub_getkey ()) != GRUB_TERM_ESC)
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -92,7 +91,7 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(cat)
|
||||
{
|
||||
cmd = grub_register_extcmd ("cat", grub_cmd_cat, GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd = grub_register_extcmd ("cat", grub_cmd_cat, 0,
|
||||
N_("FILE"), N_("Show the contents of a file."),
|
||||
options);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <grub/misc.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/gzio.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
|
@ -44,8 +43,8 @@ grub_cmd_cmp (grub_command_t cmd __attribute__ ((unused)),
|
|||
grub_printf ("Compare file `%s' with `%s':\n", args[0],
|
||||
args[1]);
|
||||
|
||||
file1 = grub_gzfile_open (args[0], 1);
|
||||
file2 = grub_gzfile_open (args[1], 1);
|
||||
file1 = grub_file_open (args[0]);
|
||||
file2 = grub_file_open (args[1]);
|
||||
if (! file1 || ! file2)
|
||||
goto cleanup;
|
||||
|
||||
|
|
|
@ -27,28 +27,34 @@
|
|||
static grub_err_t
|
||||
grub_cmd_source (grub_command_t cmd, int argc, char **args)
|
||||
{
|
||||
int new_env;
|
||||
int new_env, extractor;
|
||||
|
||||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
|
||||
|
||||
new_env = (cmd->name[0] == 'c');
|
||||
extractor = (cmd->name[0] == 'e');
|
||||
new_env = (cmd->name[extractor ? sizeof ("extract_entries_") - 1 : 0] == 'c');
|
||||
|
||||
if (new_env)
|
||||
{
|
||||
grub_cls ();
|
||||
grub_env_context_open (1);
|
||||
}
|
||||
grub_cls ();
|
||||
|
||||
if (new_env && !extractor)
|
||||
grub_env_context_open ();
|
||||
if (extractor)
|
||||
grub_env_extractor_open (!new_env);
|
||||
|
||||
grub_normal_execute (args[0], 1, ! new_env);
|
||||
|
||||
if (new_env)
|
||||
if (new_env && !extractor)
|
||||
grub_env_context_close ();
|
||||
if (extractor)
|
||||
grub_env_extractor_close (!new_env);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_command_t cmd_configfile, cmd_source, cmd_dot;
|
||||
static grub_command_t cmd_extractor_source, cmd_extractor_configfile;
|
||||
|
||||
GRUB_MOD_INIT(configfile)
|
||||
{
|
||||
|
@ -60,6 +66,19 @@ GRUB_MOD_INIT(configfile)
|
|||
N_("FILE"),
|
||||
N_("Load another config file without changing context.")
|
||||
);
|
||||
|
||||
cmd_extractor_source =
|
||||
grub_register_command ("extract_entries_source", grub_cmd_source,
|
||||
N_("FILE"),
|
||||
N_("Load another config file without changing context but take only menuentries.")
|
||||
);
|
||||
|
||||
cmd_extractor_configfile =
|
||||
grub_register_command ("extract_entries_configfile", grub_cmd_source,
|
||||
N_("FILE"),
|
||||
N_("Load another config file without changing context but take only menuentries.")
|
||||
);
|
||||
|
||||
cmd_dot =
|
||||
grub_register_command (".", grub_cmd_source,
|
||||
N_("FILE"),
|
||||
|
@ -71,5 +90,7 @@ GRUB_MOD_FINI(configfile)
|
|||
{
|
||||
grub_unregister_command (cmd_configfile);
|
||||
grub_unregister_command (cmd_source);
|
||||
grub_unregister_command (cmd_extractor_configfile);
|
||||
grub_unregister_command (cmd_extractor_source);
|
||||
grub_unregister_command (cmd_dot);
|
||||
}
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
/* crc.c - command to calculate the crc32 checksum of a file */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008,2010 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/dl.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/lib/crc.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_crc (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
|
||||
{
|
||||
grub_file_t file;
|
||||
char buf[GRUB_DISK_SECTOR_SIZE];
|
||||
grub_ssize_t size;
|
||||
grub_uint32_t crc;
|
||||
|
||||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
|
||||
|
||||
file = grub_file_open (args[0]);
|
||||
if (! file)
|
||||
return 0;
|
||||
|
||||
crc = 0;
|
||||
while ((size = grub_file_read (file, buf, sizeof (buf))) > 0)
|
||||
crc = grub_getcrc32 (crc, buf, size);
|
||||
|
||||
if (grub_errno)
|
||||
goto fail;
|
||||
|
||||
grub_printf ("%08x\n", crc);
|
||||
|
||||
fail:
|
||||
grub_file_close (file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(crc)
|
||||
{
|
||||
cmd = grub_register_command ("crc", grub_cmd_crc,
|
||||
N_("FILE"),
|
||||
N_("Calculate the crc32 checksum of a file."));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(crc)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
|
@ -30,9 +30,9 @@ static const struct grub_arg_option options[] =
|
|||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_echo (grub_extcmd_t cmd, int argc, char **args)
|
||||
grub_cmd_echo (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
int newline = 1;
|
||||
int i;
|
||||
|
||||
|
@ -113,7 +113,9 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(echo)
|
||||
{
|
||||
cmd = grub_register_extcmd ("echo", grub_cmd_echo, GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd = grub_register_extcmd ("echo", grub_cmd_echo,
|
||||
GRUB_COMMAND_ACCEPT_DASH
|
||||
| GRUB_COMMAND_OPTIONS_AT_START,
|
||||
N_("[-e|-n] STRING"), N_("Display a line of text."),
|
||||
options);
|
||||
}
|
||||
|
|
143
grub-core/commands/efi/lsefimmap.c
Normal file
143
grub-core/commands/efi/lsefimmap.c
Normal file
|
@ -0,0 +1,143 @@
|
|||
/* lsefimemmap.c - Display memory map. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 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/types.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/efi/api.h>
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/command.h>
|
||||
|
||||
#define ADD_MEMORY_DESCRIPTOR(desc, size) \
|
||||
((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_lsefimmap (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
grub_efi_uintn_t map_size;
|
||||
grub_efi_memory_descriptor_t *memory_map;
|
||||
grub_efi_memory_descriptor_t *memory_map_end;
|
||||
grub_efi_memory_descriptor_t *desc;
|
||||
grub_efi_uintn_t desc_size;
|
||||
|
||||
map_size = 0;
|
||||
if (grub_efi_get_memory_map (&map_size, NULL, NULL, &desc_size, 0) < 0)
|
||||
return 0;
|
||||
|
||||
memory_map = grub_malloc (map_size);
|
||||
if (memory_map == NULL)
|
||||
return grub_errno;
|
||||
if (grub_efi_get_memory_map (&map_size, memory_map, NULL, &desc_size, 0) <= 0)
|
||||
goto fail;
|
||||
|
||||
grub_printf
|
||||
("Type Physical start - end #Pages "
|
||||
" Size Attributes\n");
|
||||
memory_map_end = ADD_MEMORY_DESCRIPTOR (memory_map, map_size);
|
||||
for (desc = memory_map;
|
||||
desc < memory_map_end;
|
||||
desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||
{
|
||||
grub_efi_uint64_t size;
|
||||
grub_efi_uint64_t attr;
|
||||
static const char types_str[][9] =
|
||||
{
|
||||
"reserved",
|
||||
"ldr-code",
|
||||
"ldr-data",
|
||||
"BS-code ",
|
||||
"BS-data ",
|
||||
"RT-code ",
|
||||
"RT-data ",
|
||||
"conv-mem",
|
||||
"unusable",
|
||||
"ACPI-rec",
|
||||
"ACPI-nvs",
|
||||
"MMIO ",
|
||||
"IO-ports",
|
||||
"PAL-code"
|
||||
};
|
||||
if (desc->type < ARRAY_SIZE (types_str))
|
||||
grub_printf ("%s ", types_str[desc->type]);
|
||||
else
|
||||
grub_printf ("Unk %02x ", desc->type);
|
||||
|
||||
grub_printf (" %016" PRIxGRUB_UINT64_T "-%016" PRIxGRUB_UINT64_T
|
||||
" %08" PRIxGRUB_UINT64_T,
|
||||
desc->physical_start,
|
||||
desc->physical_start + (desc->num_pages << 12) - 1,
|
||||
desc->num_pages);
|
||||
|
||||
size = desc->num_pages;
|
||||
size <<= (12 - 10);
|
||||
if (size < 1024)
|
||||
grub_printf (" %4" PRIuGRUB_UINT64_T "KB", size);
|
||||
else
|
||||
{
|
||||
size /= 1024;
|
||||
if (size < 1024)
|
||||
grub_printf (" %4" PRIuGRUB_UINT64_T "MB", size);
|
||||
else
|
||||
{
|
||||
size /= 1024;
|
||||
grub_printf (" %4" PRIuGRUB_UINT64_T "GB", size);
|
||||
}
|
||||
}
|
||||
|
||||
attr = desc->attribute;
|
||||
if (attr & GRUB_EFI_MEMORY_RUNTIME)
|
||||
grub_printf (" RT");
|
||||
if (attr & GRUB_EFI_MEMORY_UC)
|
||||
grub_printf (" UC");
|
||||
if (attr & GRUB_EFI_MEMORY_WC)
|
||||
grub_printf (" WC");
|
||||
if (attr & GRUB_EFI_MEMORY_WT)
|
||||
grub_printf (" WT");
|
||||
if (attr & GRUB_EFI_MEMORY_WB)
|
||||
grub_printf (" WB");
|
||||
if (attr & GRUB_EFI_MEMORY_UCE)
|
||||
grub_printf (" UCE");
|
||||
if (attr & GRUB_EFI_MEMORY_WP)
|
||||
grub_printf (" WP");
|
||||
if (attr & GRUB_EFI_MEMORY_RP)
|
||||
grub_printf (" RP");
|
||||
if (attr & GRUB_EFI_MEMORY_XP)
|
||||
grub_printf (" XP");
|
||||
|
||||
grub_printf ("\n");
|
||||
}
|
||||
|
||||
fail:
|
||||
grub_free (memory_map);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(lsefimmap)
|
||||
{
|
||||
cmd = grub_register_command ("lsefimmap", grub_cmd_lsefimmap,
|
||||
"", "Display EFI memory map.");
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(lsefimmap)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
107
grub-core/commands/efi/lsefisystab.c
Normal file
107
grub-core/commands/efi/lsefisystab.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/* lsefisystab.c - Display EFI systab. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 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/types.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/charset.h>
|
||||
#include <grub/efi/api.h>
|
||||
#include <grub/efi/efi.h>
|
||||
|
||||
struct guid_mapping
|
||||
{
|
||||
grub_efi_guid_t guid;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static const struct guid_mapping guid_mappings[] =
|
||||
{
|
||||
{ GRUB_EFI_ACPI_20_TABLE_GUID, "ACPI-2.0"},
|
||||
{ GRUB_EFI_ACPI_TABLE_GUID, "ACPI-1.0"},
|
||||
{ GRUB_EFI_SAL_TABLE_GUID, "SAL"},
|
||||
{ GRUB_EFI_SMBIOS_TABLE_GUID, "SMBIOS"},
|
||||
{ GRUB_EFI_MPS_TABLE_GUID, "MPS"},
|
||||
{ GRUB_EFI_HCDP_TABLE_GUID, "HCDP"}
|
||||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_lsefisystab (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
const grub_efi_system_table_t *st = grub_efi_system_table;
|
||||
grub_efi_configuration_table_t *t;
|
||||
unsigned int i;
|
||||
|
||||
grub_printf ("Signature: %016" PRIxGRUB_UINT64_T " revision: %08x\n",
|
||||
st->hdr.signature, st->hdr.revision);
|
||||
{
|
||||
char *vendor;
|
||||
grub_uint16_t *vendor_utf16;
|
||||
grub_printf ("Vendor: ");
|
||||
|
||||
for (vendor_utf16 = st->firmware_vendor; *vendor_utf16; vendor_utf16++);
|
||||
vendor = grub_malloc (4 * (vendor_utf16 - st->firmware_vendor) + 1);
|
||||
if (!vendor)
|
||||
return grub_errno;
|
||||
*grub_utf16_to_utf8 ((grub_uint8_t *) vendor, st->firmware_vendor,
|
||||
vendor_utf16 - st->firmware_vendor) = 0;
|
||||
grub_printf ("%s", vendor);
|
||||
grub_free (vendor);
|
||||
}
|
||||
|
||||
grub_printf (", Version=%x\n", st->firmware_revision);
|
||||
|
||||
grub_printf ("%ld tables:\n", st->num_table_entries);
|
||||
t = st->configuration_table;
|
||||
for (i = 0; i < st->num_table_entries; i++)
|
||||
{
|
||||
unsigned int j;
|
||||
|
||||
grub_printf ("%p ", t->vendor_table);
|
||||
|
||||
grub_printf ("%08x-%04x-%04x-",
|
||||
t->vendor_guid.data1, t->vendor_guid.data2,
|
||||
t->vendor_guid.data3);
|
||||
for (j = 0; j < 8; j++)
|
||||
grub_printf ("%02x", t->vendor_guid.data4[j]);
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE (guid_mappings); j++)
|
||||
if (grub_memcmp (&guid_mappings[j].guid, &t->vendor_guid,
|
||||
sizeof (grub_efi_guid_t)) == 0)
|
||||
grub_printf (" %s", guid_mappings[j].name);
|
||||
|
||||
grub_printf ("\n");
|
||||
t++;
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(lsefisystab)
|
||||
{
|
||||
cmd = grub_register_command ("lsefisystab", grub_cmd_lsefisystab,
|
||||
"", "Display EFI system tables.");
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(lsefisystab)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
162
grub-core/commands/efi/lssal.c
Normal file
162
grub-core/commands/efi/lssal.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
/* lssal.c - Display EFI SAL systab. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 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/types.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/charset.h>
|
||||
#include <grub/efi/api.h>
|
||||
#include <grub/efi/efi.h>
|
||||
|
||||
static void
|
||||
disp_sal (void *table)
|
||||
{
|
||||
struct grub_efi_sal_system_table *t = table;
|
||||
void *desc;
|
||||
grub_uint32_t len, l;
|
||||
|
||||
grub_printf ("SAL rev: %02x, signature: %x, len:%x\n",
|
||||
t->sal_rev, t->signature, t->total_table_len);
|
||||
grub_printf ("nbr entry: %d, chksum: %02x, SAL version A: %02x B: %02x\n",
|
||||
t->entry_count, t->checksum,
|
||||
t->sal_a_version, t->sal_b_version);
|
||||
grub_printf ("OEM-ID: %-32s\n", t->oem_id);
|
||||
grub_printf ("Product-ID: %-32s\n", t->product_id);
|
||||
|
||||
desc = t->entries;
|
||||
len = t->total_table_len - sizeof (struct grub_efi_sal_system_table);
|
||||
while (len > 0)
|
||||
{
|
||||
switch (*(grub_uint8_t *) desc)
|
||||
{
|
||||
case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_ENTRYPOINT_DESCRIPTOR:
|
||||
{
|
||||
struct grub_efi_sal_system_table_entrypoint_descriptor *c = desc;
|
||||
l = sizeof (*c);
|
||||
grub_printf (" Entry point: PAL=%016" PRIxGRUB_UINT64_T
|
||||
" SAL=%016" PRIxGRUB_UINT64_T " GP=%016"
|
||||
PRIxGRUB_UINT64_T "\n",
|
||||
c->pal_proc_addr, c->sal_proc_addr,
|
||||
c->global_data_ptr);
|
||||
}
|
||||
break;
|
||||
case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_MEMORY_DESCRIPTOR:
|
||||
{
|
||||
struct grub_efi_sal_system_table_memory_descriptor *c = desc;
|
||||
l = sizeof (*c);
|
||||
grub_printf (" Memory descriptor entry addr=%016" PRIxGRUB_UINT64_T
|
||||
" len=%" PRIuGRUB_UINT64_T "KB\n",
|
||||
c->addr, c->len * 4);
|
||||
grub_printf (" sal_used=%d attr=%x AR=%x attr_mask=%x "
|
||||
"type=%x usage=%x\n",
|
||||
c->sal_used, c->attr, c->ar, c->attr_mask, c->mem_type,
|
||||
c->usage);
|
||||
}
|
||||
break;
|
||||
case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PLATFORM_FEATURES:
|
||||
{
|
||||
struct grub_efi_sal_system_table_platform_features *c = desc;
|
||||
l = sizeof (*c);
|
||||
grub_printf (" Platform features: %02x", c->flags);
|
||||
if (c->flags & GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_BUSLOCK)
|
||||
grub_printf (" BusLock");
|
||||
if (c->flags & GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IRQREDIRECT)
|
||||
grub_printf (" IrqRedirect");
|
||||
if (c->flags & GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IPIREDIRECT)
|
||||
|
||||
grub_printf (" IPIRedirect");
|
||||
if (c->flags & GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_ITCDRIFT)
|
||||
|
||||
grub_printf (" ITCDrift");
|
||||
grub_printf ("\n");
|
||||
}
|
||||
break;
|
||||
case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_TRANSLATION_REGISTER_DESCRIPTOR:
|
||||
{
|
||||
struct grub_efi_sal_system_table_translation_register_descriptor *c
|
||||
= desc;
|
||||
l = sizeof (*c);
|
||||
grub_printf (" TR type=%d num=%d va=%016" PRIxGRUB_UINT64_T
|
||||
" pte=%016" PRIxGRUB_UINT64_T "\n",
|
||||
c->register_type, c->register_number,
|
||||
c->addr, c->page_size);
|
||||
}
|
||||
break;
|
||||
case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PURGE_TRANSLATION_COHERENCE:
|
||||
{
|
||||
struct grub_efi_sal_system_table_purge_translation_coherence *c
|
||||
= desc;
|
||||
l = sizeof (*c);
|
||||
grub_printf (" PTC coherence nbr=%d addr=%016" PRIxGRUB_UINT64_T "\n",
|
||||
c->ndomains, c->coherence);
|
||||
}
|
||||
break;
|
||||
case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_AP_WAKEUP:
|
||||
{
|
||||
struct grub_efi_sal_system_table_ap_wakeup *c = desc;
|
||||
l = sizeof (*c);
|
||||
grub_printf (" AP wake-up: mec=%d vect=%" PRIxGRUB_UINT64_T "\n",
|
||||
c->mechanism, c->vector);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
grub_printf (" unknown entry 0x%x\n", *(grub_uint8_t *)desc);
|
||||
return;
|
||||
}
|
||||
desc = (grub_uint8_t *)desc + l;
|
||||
len -= l;
|
||||
}
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_lssal (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
const grub_efi_system_table_t *st = grub_efi_system_table;
|
||||
grub_efi_configuration_table_t *t = st->configuration_table;
|
||||
unsigned int i;
|
||||
grub_efi_guid_t guid = GRUB_EFI_SAL_TABLE_GUID;
|
||||
|
||||
for (i = 0; i < st->num_table_entries; i++)
|
||||
{
|
||||
if (grub_memcmp (&guid, &t->vendor_guid,
|
||||
sizeof (grub_efi_guid_t)) == 0)
|
||||
{
|
||||
disp_sal (t->vendor_table);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
t++;
|
||||
}
|
||||
grub_printf ("SAL not found\n");
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(lssal)
|
||||
{
|
||||
cmd = grub_register_command ("lssal", grub_cmd_lssal, "",
|
||||
"Display SAL system table.");
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(lssal)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
|
@ -21,46 +21,55 @@
|
|||
#include <grub/list.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/script_sh.h>
|
||||
|
||||
static grub_err_t
|
||||
grub_extcmd_dispatcher (struct grub_command *cmd,
|
||||
int argc, char **args)
|
||||
grub_err_t
|
||||
grub_extcmd_dispatcher (struct grub_command *cmd, int argc, char **args,
|
||||
struct grub_script *script)
|
||||
{
|
||||
int new_argc;
|
||||
char **new_args;
|
||||
struct grub_arg_option *parser;
|
||||
struct grub_arg_list *state;
|
||||
int maxargs = 0;
|
||||
struct grub_extcmd_context context;
|
||||
grub_err_t ret;
|
||||
grub_extcmd_t ext;
|
||||
grub_extcmd_t ext = cmd->data;
|
||||
|
||||
ext = cmd->data;
|
||||
parser = (struct grub_arg_option *) ext->options;
|
||||
while (parser && (parser++)->doc)
|
||||
maxargs++;
|
||||
context.state = 0;
|
||||
context.extcmd = ext;
|
||||
context.script = script;
|
||||
|
||||
/* Set up the option state. */
|
||||
state = grub_zalloc (sizeof (struct grub_arg_list) * maxargs);
|
||||
if (! ext->options)
|
||||
{
|
||||
ret = (ext->func) (&context, argc, args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
state = grub_arg_list_alloc (ext, argc, args);
|
||||
if (grub_arg_parse (ext, argc, args, state, &new_args, &new_argc))
|
||||
{
|
||||
ext->state = state;
|
||||
ret = (ext->func) (ext, new_argc, new_args);
|
||||
context.state = state;
|
||||
ret = (ext->func) (&context, new_argc, new_args);
|
||||
grub_free (new_args);
|
||||
grub_free (state);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
ret = grub_errno;
|
||||
|
||||
grub_free (state);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
return ret;
|
||||
static grub_err_t
|
||||
grub_extcmd_dispatch (struct grub_command *cmd, int argc, char **args)
|
||||
{
|
||||
return grub_extcmd_dispatcher (cmd, argc, args, 0);
|
||||
}
|
||||
|
||||
grub_extcmd_t
|
||||
grub_register_extcmd (const char *name, grub_extcmd_func_t func,
|
||||
unsigned flags, const char *summary,
|
||||
const char *description,
|
||||
const struct grub_arg_option *parser)
|
||||
grub_register_extcmd_prio (const char *name, grub_extcmd_func_t func,
|
||||
grub_command_flags_t flags, const char *summary,
|
||||
const char *description,
|
||||
const struct grub_arg_option *parser,
|
||||
int prio)
|
||||
{
|
||||
grub_extcmd_t ext;
|
||||
grub_command_t cmd;
|
||||
|
@ -69,8 +78,8 @@ grub_register_extcmd (const char *name, grub_extcmd_func_t func,
|
|||
if (! ext)
|
||||
return 0;
|
||||
|
||||
cmd = grub_register_command_prio (name, grub_extcmd_dispatcher,
|
||||
summary, description, 1);
|
||||
cmd = grub_register_command_prio (name, grub_extcmd_dispatch,
|
||||
summary, description, prio);
|
||||
if (! cmd)
|
||||
{
|
||||
grub_free (ext);
|
||||
|
@ -88,6 +97,16 @@ grub_register_extcmd (const char *name, grub_extcmd_func_t func,
|
|||
return ext;
|
||||
}
|
||||
|
||||
grub_extcmd_t
|
||||
grub_register_extcmd (const char *name, grub_extcmd_func_t func,
|
||||
grub_command_flags_t flags, const char *summary,
|
||||
const char *description,
|
||||
const struct grub_arg_option *parser)
|
||||
{
|
||||
return grub_register_extcmd_prio (name, func, flags,
|
||||
summary, description, parser, 1);
|
||||
}
|
||||
|
||||
void
|
||||
grub_unregister_extcmd (grub_extcmd_t ext)
|
||||
{
|
||||
|
|
|
@ -32,6 +32,7 @@ static const struct grub_arg_option options[] = {
|
|||
{"prefix", 'p', 0, N_("Base directory for hash list."), N_("DIRECTORY"),
|
||||
ARG_TYPE_STRING},
|
||||
{"keep-going", 'k', 0, N_("Don't stop after first error."), 0, 0},
|
||||
{"uncompress", 'u', 0, N_("Uncompress file before checksumming."), 0, 0},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -39,7 +40,9 @@ struct { const char *name; const char *hashname; } aliases[] =
|
|||
{
|
||||
{"sha256sum", "sha256"},
|
||||
{"sha512sum", "sha512"},
|
||||
{"sha1sum", "sha1"},
|
||||
{"md5sum", "md5"},
|
||||
{"crc", "crc32"},
|
||||
};
|
||||
|
||||
static inline int
|
||||
|
@ -80,7 +83,7 @@ hash_file (grub_file_t file, const gcry_md_spec_t *hash, void *result)
|
|||
|
||||
static grub_err_t
|
||||
check_list (const gcry_md_spec_t *hash, const char *hashfilename,
|
||||
const char *prefix, int keep)
|
||||
const char *prefix, int keep, int uncompress)
|
||||
{
|
||||
grub_file_t hashlist, file;
|
||||
char *buf = NULL;
|
||||
|
@ -115,11 +118,17 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
|
|||
filename = grub_xasprintf ("%s/%s", prefix, p);
|
||||
if (!filename)
|
||||
return grub_errno;
|
||||
if (!uncompress)
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (filename);
|
||||
grub_free (filename);
|
||||
}
|
||||
else
|
||||
file = grub_file_open (p);
|
||||
{
|
||||
if (!uncompress)
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (p);
|
||||
}
|
||||
if (!file)
|
||||
{
|
||||
grub_file_close (hashlist);
|
||||
|
@ -165,19 +174,20 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_hashsum (struct grub_extcmd *cmd,
|
||||
grub_cmd_hashsum (struct grub_extcmd_context *ctxt,
|
||||
int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
const char *hashname = NULL;
|
||||
const char *prefix = NULL;
|
||||
const gcry_md_spec_t *hash;
|
||||
unsigned i;
|
||||
int keep = state[3].set;
|
||||
int uncompress = state[4].set;
|
||||
unsigned unread = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (aliases); i++)
|
||||
if (grub_strcmp (cmd->cmd->name, aliases[i].name) == 0)
|
||||
if (grub_strcmp (ctxt->extcmd->cmd->name, aliases[i].name) == 0)
|
||||
hashname = aliases[i].hashname;
|
||||
if (state[0].set)
|
||||
hashname = state[0].arg;
|
||||
|
@ -197,7 +207,7 @@ grub_cmd_hashsum (struct grub_extcmd *cmd,
|
|||
if (argc != 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
"--check is incompatible with file list");
|
||||
return check_list (hash, state[1].arg, prefix, keep);
|
||||
return check_list (hash, state[1].arg, prefix, keep, uncompress);
|
||||
}
|
||||
|
||||
for (i = 0; i < (unsigned) argc; i++)
|
||||
|
@ -206,6 +216,8 @@ grub_cmd_hashsum (struct grub_extcmd *cmd,
|
|||
grub_file_t file;
|
||||
grub_err_t err;
|
||||
unsigned j;
|
||||
if (!uncompress)
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (args[i]);
|
||||
if (!file)
|
||||
{
|
||||
|
@ -238,30 +250,37 @@ grub_cmd_hashsum (struct grub_extcmd *cmd,
|
|||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_extcmd_t cmd, cmd_md5, cmd_sha256, cmd_sha512;
|
||||
static grub_extcmd_t cmd, cmd_md5, cmd_sha1, cmd_sha256, cmd_sha512, cmd_crc;
|
||||
|
||||
GRUB_MOD_INIT(hashsum)
|
||||
{
|
||||
cmd = grub_register_extcmd ("hashsum", grub_cmd_hashsum,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd = grub_register_extcmd ("hashsum", grub_cmd_hashsum, 0,
|
||||
"hashsum -h HASH [-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]",
|
||||
"Compute or check hash checksum.",
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd_sha1 = grub_register_extcmd ("sha1sum", grub_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
"Compute or check hash checksum.",
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
cmd_sha512 = grub_register_extcmd ("sha512sum", grub_cmd_hashsum,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd_sha512 = grub_register_extcmd ("sha512sum", grub_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
N_("Compute or check hash checksum."),
|
||||
options);
|
||||
|
||||
cmd_crc = grub_register_extcmd ("crc", grub_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
N_("Compute or check hash checksum."),
|
||||
|
@ -272,6 +291,8 @@ GRUB_MOD_FINI(hashsum)
|
|||
{
|
||||
grub_unregister_extcmd (cmd);
|
||||
grub_unregister_extcmd (cmd_md5);
|
||||
grub_unregister_extcmd (cmd_sha1);
|
||||
grub_unregister_extcmd (cmd_sha256);
|
||||
grub_unregister_extcmd (cmd_sha512);
|
||||
grub_unregister_extcmd (cmd_crc);
|
||||
}
|
||||
|
|
|
@ -270,9 +270,9 @@ static int get_int_arg (const struct grub_arg_list *state)
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_hdparm (grub_extcmd_t cmd, int argc, char **args) // state????
|
||||
grub_cmd_hdparm (grub_extcmd_context_t ctxt, int argc, char **args) // state????
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
|
||||
/* Check command line. */
|
||||
if (argc != 1)
|
||||
|
@ -409,8 +409,7 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(hdparm)
|
||||
{
|
||||
cmd = grub_register_extcmd ("hdparm", grub_cmd_hdparm,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd = grub_register_extcmd ("hdparm", grub_cmd_hdparm, 0,
|
||||
N_("[OPTIONS] DISK"),
|
||||
N_("Get/set ATA disk parameters."), options);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include <grub/charset.h>
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
|
||||
grub_cmd_help (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc,
|
||||
char **args)
|
||||
{
|
||||
int cnt = 0;
|
||||
|
@ -38,8 +38,7 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
|
|||
grub_command_t cmd;
|
||||
FOR_COMMANDS(cmd)
|
||||
{
|
||||
if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) &&
|
||||
(cmd->flags & GRUB_COMMAND_FLAG_CMDLINE))
|
||||
if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE))
|
||||
{
|
||||
struct grub_term_output *term;
|
||||
const char *summary_translated = _(cmd->summary);
|
||||
|
@ -112,7 +111,8 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
|
|||
if (cnt++ > 0)
|
||||
grub_printf ("\n\n");
|
||||
|
||||
if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD)
|
||||
if ((cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) &&
|
||||
! (cmd->flags & GRUB_COMMAND_FLAG_DYNCMD))
|
||||
grub_arg_show_help ((grub_extcmd_t) cmd->data);
|
||||
else
|
||||
grub_printf ("%s %s %s\n%s\n", _("Usage:"), cmd->name, _(cmd->summary),
|
||||
|
@ -130,8 +130,7 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(help)
|
||||
{
|
||||
cmd = grub_register_extcmd ("help", grub_cmd_help,
|
||||
GRUB_COMMAND_FLAG_CMDLINE,
|
||||
cmd = grub_register_extcmd ("help", grub_cmd_help, 0,
|
||||
N_("[PATTERN ...]"),
|
||||
N_("Show a help message."), 0);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <grub/file.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/gzio.h>
|
||||
#include <grub/lib/hexdump.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
|
@ -34,9 +33,9 @@ static const struct grub_arg_option options[] = {
|
|||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_hexdump (grub_extcmd_t cmd, int argc, char **args)
|
||||
grub_cmd_hexdump (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
char buf[GRUB_DISK_SECTOR_SIZE * 4];
|
||||
grub_ssize_t size, length;
|
||||
grub_disk_addr_t skip;
|
||||
|
@ -89,7 +88,7 @@ grub_cmd_hexdump (grub_extcmd_t cmd, int argc, char **args)
|
|||
{
|
||||
grub_file_t file;
|
||||
|
||||
file = grub_gzfile_open (args[0], 1);
|
||||
file = grub_file_open (args[0]);
|
||||
if (! file)
|
||||
return 0;
|
||||
|
||||
|
@ -120,8 +119,7 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT (hexdump)
|
||||
{
|
||||
cmd = grub_register_extcmd ("hexdump", grub_cmd_hexdump,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd = grub_register_extcmd ("hexdump", grub_cmd_hexdump, 0,
|
||||
N_("[OPTIONS] FILE_OR_DEVICE"),
|
||||
N_("Dump the contents of a file or memory."),
|
||||
options);
|
||||
|
|
|
@ -22,20 +22,32 @@
|
|||
#include <grub/cmos.h>
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
parse_args (int argc, char *argv[], int *byte, int *bit)
|
||||
{
|
||||
int byte, bit;
|
||||
char *rest;
|
||||
|
||||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required.");
|
||||
|
||||
byte = grub_strtoul (argv[0], &rest, 0);
|
||||
*byte = grub_strtoul (argv[0], &rest, 0);
|
||||
if (*rest != ':')
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required.");
|
||||
|
||||
bit = grub_strtoul (rest + 1, 0, 0);
|
||||
*bit = grub_strtoul (rest + 1, 0, 0);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
int byte, bit;
|
||||
grub_err_t err;
|
||||
|
||||
err = parse_args (argc, argv, &byte, &bit);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (grub_cmos_read (byte) & (1 << bit))
|
||||
return GRUB_ERR_NONE;
|
||||
|
@ -43,7 +55,22 @@ grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)),
|
|||
return grub_error (GRUB_ERR_TEST_FAILURE, "false");
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
static grub_err_t
|
||||
grub_cmd_cmosclean (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
int byte, bit;
|
||||
grub_err_t err;
|
||||
|
||||
err = parse_args (argc, argv, &byte, &bit);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
grub_cmos_write (byte, grub_cmos_read (byte) & (~(1 << bit)));
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_command_t cmd, cmd_clean;
|
||||
|
||||
|
||||
GRUB_MOD_INIT(cmostest)
|
||||
|
@ -51,9 +78,13 @@ GRUB_MOD_INIT(cmostest)
|
|||
cmd = grub_register_command ("cmostest", grub_cmd_cmostest,
|
||||
"cmostest BYTE:BIT",
|
||||
"Test bit at BYTE:BIT in CMOS.");
|
||||
cmd_clean = grub_register_command ("cmosclean", grub_cmd_cmosclean,
|
||||
"cmosclean BYTE:BIT",
|
||||
"Clean bit at BYTE:BIT in CMOS.");
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(cmostest)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
grub_unregister_command (cmd_clean);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ static const struct grub_arg_option options[] =
|
|||
unsigned char grub_cpuid_has_longmode = 0;
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_cpuid (grub_extcmd_t cmd __attribute__ ((unused)),
|
||||
grub_cmd_cpuid (grub_extcmd_context_t ctxt __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
|
@ -88,7 +88,7 @@ GRUB_MOD_INIT(cpuid)
|
|||
done:
|
||||
#endif
|
||||
|
||||
cmd = grub_register_extcmd ("cpuid", grub_cmd_cpuid, GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd = grub_register_extcmd ("cpuid", grub_cmd_cpuid, 0,
|
||||
"[-l]", N_("Check for CPU features."), options);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,10 @@
|
|||
#include <grub/disk.h>
|
||||
#include <grub/loader.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/machine/biosnum.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/memory.h>
|
||||
#include <grub/machine/memory.h>
|
||||
|
||||
|
||||
/* Real mode IVT slot (seg:off far pointer) for interrupt 0x13. */
|
||||
|
@ -196,13 +197,13 @@ list_mappings (void)
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_drivemap (struct grub_extcmd *cmd, int argc, char **args)
|
||||
grub_cmd_drivemap (struct grub_extcmd_context *ctxt, int argc, char **args)
|
||||
{
|
||||
if (cmd->state[OPTIDX_LIST].set)
|
||||
if (ctxt->state[OPTIDX_LIST].set)
|
||||
{
|
||||
return list_mappings ();
|
||||
}
|
||||
else if (cmd->state[OPTIDX_RESET].set)
|
||||
else if (ctxt->state[OPTIDX_RESET].set)
|
||||
{
|
||||
/* Reset: just delete all mappings, freeing their memory. */
|
||||
drivemap_node_t *curnode = map_head;
|
||||
|
@ -216,7 +217,7 @@ grub_cmd_drivemap (struct grub_extcmd *cmd, int argc, char **args)
|
|||
map_head = 0;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
else if (!cmd->state[OPTIDX_SWAP].set && argc == 0)
|
||||
else if (!ctxt->state[OPTIDX_SWAP].set && argc == 0)
|
||||
{
|
||||
/* No arguments */
|
||||
return list_mappings ();
|
||||
|
@ -248,11 +249,11 @@ grub_cmd_drivemap (struct grub_extcmd *cmd, int argc, char **args)
|
|||
}
|
||||
/* Set the mapping for the disk (overwrites any existing mapping). */
|
||||
grub_dprintf ("drivemap", "%s %s (%02x) = %s (%02x)\n",
|
||||
cmd->state[OPTIDX_SWAP].set ? "Swapping" : "Mapping",
|
||||
ctxt->state[OPTIDX_SWAP].set ? "Swapping" : "Mapping",
|
||||
args[1], mapto, args[0], mapfrom);
|
||||
err = drivemap_set (mapto, mapfrom);
|
||||
/* If -s, perform the reverse mapping too (only if the first was OK). */
|
||||
if (cmd->state[OPTIDX_SWAP].set && err == GRUB_ERR_NONE)
|
||||
if (ctxt->state[OPTIDX_SWAP].set && err == GRUB_ERR_NONE)
|
||||
err = drivemap_set (mapfrom, mapto);
|
||||
return err;
|
||||
}
|
||||
|
@ -306,7 +307,7 @@ install_int13_handler (int noret __attribute__ ((unused)))
|
|||
grub_dprintf ("drivemap", "Payload is %u bytes long\n", total_size);
|
||||
handler_base = grub_mmap_malign_and_register (16, total_size,
|
||||
&drivemap_mmap,
|
||||
GRUB_MACHINE_MEMORY_RESERVED,
|
||||
GRUB_MEMORY_RESERVED,
|
||||
GRUB_MMAP_MALLOC_LOW);
|
||||
if (! handler_base)
|
||||
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't reserve "
|
||||
|
@ -401,8 +402,7 @@ GRUB_MOD_INIT (drivemap)
|
|||
{
|
||||
grub_get_root_biosnumber_saved = grub_get_root_biosnumber;
|
||||
grub_get_root_biosnumber = grub_get_root_biosnumber_drivemap;
|
||||
cmd = grub_register_extcmd ("drivemap", grub_cmd_drivemap,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd = grub_register_extcmd ("drivemap", grub_cmd_drivemap, 0,
|
||||
N_("-l | -r | [-s] grubdev osdisk."),
|
||||
N_("Manage the BIOS drive mappings."),
|
||||
options);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/machine/int.h>
|
||||
#include <grub/acpi.h>
|
||||
|
||||
static const struct grub_arg_option options[] =
|
||||
{
|
||||
|
@ -46,6 +47,8 @@ grub_halt (int no_apm)
|
|||
{
|
||||
struct grub_bios_int_registers regs;
|
||||
|
||||
grub_acpi_halt ();
|
||||
|
||||
if (no_apm)
|
||||
stop ();
|
||||
|
||||
|
@ -93,13 +96,14 @@ grub_halt (int no_apm)
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_halt (grub_extcmd_t cmd,
|
||||
grub_cmd_halt (grub_extcmd_context_t ctxt,
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
int no_apm = 0;
|
||||
|
||||
if (state[0].set)
|
||||
no_apm = 1;
|
||||
grub_halt (no_apm);
|
||||
|
@ -110,8 +114,7 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(halt)
|
||||
{
|
||||
cmd = grub_register_extcmd ("halt", grub_cmd_halt, GRUB_COMMAND_FLAG_BOTH,
|
||||
"[-n]",
|
||||
cmd = grub_register_extcmd ("halt", grub_cmd_halt, 0, "[-n]",
|
||||
N_("Halt the system, if possible using APM."),
|
||||
options);
|
||||
}
|
||||
|
|
113
grub-core/commands/i386/pc/lsapm.c
Normal file
113
grub-core/commands/i386/pc/lsapm.c
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 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/machine/int.h>
|
||||
#include <grub/machine/apm.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
int
|
||||
grub_apm_get_info (struct grub_apm_info *info)
|
||||
{
|
||||
struct grub_bios_int_registers regs;
|
||||
|
||||
/* detect APM */
|
||||
regs.eax = 0x5300;
|
||||
regs.ebx = 0;
|
||||
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||
grub_bios_interrupt (0x15, ®s);
|
||||
|
||||
if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
|
||||
return 0;
|
||||
info->version = regs.eax & 0xffff;
|
||||
info->flags = regs.ecx & 0xffff;
|
||||
|
||||
/* disconnect APM first */
|
||||
regs.eax = 0x5304;
|
||||
regs.ebx = 0;
|
||||
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||
grub_bios_interrupt (0x15, ®s);
|
||||
|
||||
/* connect APM */
|
||||
regs.eax = 0x5303;
|
||||
regs.ebx = 0;
|
||||
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||
grub_bios_interrupt (0x15, ®s);
|
||||
|
||||
if (regs.flags & GRUB_CPU_INT_FLAGS_CARRY)
|
||||
return 0;
|
||||
|
||||
info->cseg = regs.eax & 0xffff;
|
||||
info->offset = regs.ebx;
|
||||
info->cseg_16 = regs.ecx & 0xffff;
|
||||
info->dseg = regs.edx & 0xffff;
|
||||
info->cseg_len = regs.esi >> 16;
|
||||
info->cseg_16_len = regs.esi & 0xffff;
|
||||
info->dseg_len = regs.edi;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_lsapm (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)), char **args __attribute__ ((unused)))
|
||||
{
|
||||
struct grub_apm_info info;
|
||||
if (!grub_apm_get_info (&info))
|
||||
return grub_error (GRUB_ERR_IO, "no APM found");
|
||||
|
||||
grub_printf ("Vesion %u.%u\n"
|
||||
"32-bit CS = 0x%x, len = 0x%x, offset = 0x%x\n"
|
||||
"16-bit CS = 0x%x, len = 0x%x\n"
|
||||
"DS = 0x%x, len = 0x%x\n",
|
||||
info.version >> 8, info.version & 0xff,
|
||||
info.cseg, info.cseg_len, info.offset,
|
||||
info.cseg_16, info.cseg_16_len,
|
||||
info.dseg, info.dseg_len);
|
||||
grub_xputs (info.flags & GRUB_APM_FLAGS_16BITPROTECTED_SUPPORTED
|
||||
? "16-bit protected interface supported\n"
|
||||
: "16-bit protected interface unsupported\n");
|
||||
grub_xputs (info.flags & GRUB_APM_FLAGS_32BITPROTECTED_SUPPORTED
|
||||
? "32-bit protected interface supported\n"
|
||||
: "32-bit protected interface unsupported\n");
|
||||
grub_xputs (info.flags & GRUB_APM_FLAGS_CPUIDLE_SLOWS_DOWN
|
||||
? "CPU Idle slows down processor\n"
|
||||
: "CPU Idle doesn't slow down processor\n");
|
||||
grub_xputs (info.flags & GRUB_APM_FLAGS_DISABLED
|
||||
? "APM disabled\n" : "APM enabled\n");
|
||||
grub_xputs (info.flags & GRUB_APM_FLAGS_DISENGAGED
|
||||
? "APM disengaged\n" : "APM engaged\n");
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(lsapm)
|
||||
{
|
||||
cmd = grub_register_command ("lsapm", grub_cmd_lsapm, 0,
|
||||
N_("Show APM information."));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(lsapm)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
||||
|
||||
|
|
@ -284,9 +284,9 @@ grub_sendkey_preboot (int noret __attribute__ ((unused)))
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_sendkey (grub_extcmd_t cmd, int argc, char **args)
|
||||
grub_cmd_sendkey (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
|
||||
auto int find_key_code (char *key);
|
||||
auto int find_ascii_code (char *key);
|
||||
|
@ -366,8 +366,7 @@ static void *preboot_hook;
|
|||
|
||||
GRUB_MOD_INIT (sendkey)
|
||||
{
|
||||
cmd = grub_register_extcmd ("sendkey", grub_cmd_sendkey,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd = grub_register_extcmd ("sendkey", grub_cmd_sendkey, 0,
|
||||
"sendkey [KEYSTROKE1] [KEYSTROKE2] ...",
|
||||
"Emulate a keystroke", options);
|
||||
|
||||
|
|
|
@ -1,185 +0,0 @@
|
|||
/* vbeinfo.c - command to list compatible VBE video modes. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005,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/dl.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/machine/init.h>
|
||||
#include <grub/machine/vbe.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
static void *
|
||||
real2pm (grub_vbe_farptr_t ptr)
|
||||
{
|
||||
return (void *) ((((unsigned long) ptr & 0xFFFF0000) >> 12UL)
|
||||
+ ((unsigned long) ptr & 0x0000FFFF));
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_vbeinfo (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
struct grub_vbe_info_block controller_info;
|
||||
struct grub_vbe_mode_info_block mode_info_tmp;
|
||||
grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE;
|
||||
grub_uint16_t *video_mode_list;
|
||||
grub_uint16_t *p;
|
||||
grub_uint16_t *saved_video_mode_list;
|
||||
grub_size_t video_mode_list_size;
|
||||
grub_err_t err;
|
||||
char *modevar;
|
||||
|
||||
err = grub_vbe_probe (&controller_info);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
|
||||
grub_printf ("VBE info: version: %d.%d OEM software rev: %d.%d\n",
|
||||
controller_info.version >> 8,
|
||||
controller_info.version & 0xFF,
|
||||
controller_info.oem_software_rev >> 8,
|
||||
controller_info.oem_software_rev & 0xFF);
|
||||
|
||||
/* The total_memory field is in 64 KiB units. */
|
||||
grub_printf (" total memory: %d KiB\n",
|
||||
(controller_info.total_memory << 16) / 1024);
|
||||
|
||||
/* Because the information on video modes is stored in a temporary place,
|
||||
it is better to copy it to somewhere safe. */
|
||||
p = video_mode_list = real2pm (controller_info.video_mode_ptr);
|
||||
while (*p++ != 0xFFFF)
|
||||
;
|
||||
|
||||
video_mode_list_size = (grub_addr_t) p - (grub_addr_t) video_mode_list;
|
||||
saved_video_mode_list = grub_malloc (video_mode_list_size);
|
||||
if (! saved_video_mode_list)
|
||||
return grub_errno;
|
||||
|
||||
grub_memcpy (saved_video_mode_list, video_mode_list, video_mode_list_size);
|
||||
|
||||
grub_printf ("List of compatible video modes:\n");
|
||||
grub_printf ("Legend: P=Packed pixel, D=Direct color, "
|
||||
"mask/pos=R/G/B/reserved\n");
|
||||
|
||||
/* Walk through all video modes listed. */
|
||||
for (p = saved_video_mode_list; *p != 0xFFFF; p++)
|
||||
{
|
||||
const char *memory_model = 0;
|
||||
grub_uint32_t mode = (grub_uint32_t) *p;
|
||||
|
||||
err = grub_vbe_get_video_mode_info (mode, &mode_info_tmp);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_SUPPORTED) == 0)
|
||||
/* If not available, skip it. */
|
||||
continue;
|
||||
|
||||
if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_RESERVED_1) == 0)
|
||||
/* Not enough information. */
|
||||
continue;
|
||||
|
||||
if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_COLOR) == 0)
|
||||
/* Monochrome is unusable. */
|
||||
continue;
|
||||
|
||||
if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_LFB_AVAIL) == 0)
|
||||
/* We support only linear frame buffer modes. */
|
||||
continue;
|
||||
|
||||
if ((mode_info_tmp.mode_attributes & GRUB_VBE_MODEATTR_GRAPHICS) == 0)
|
||||
/* We allow only graphical modes. */
|
||||
continue;
|
||||
|
||||
switch (mode_info_tmp.memory_model)
|
||||
{
|
||||
case GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL:
|
||||
memory_model = "Packed";
|
||||
break;
|
||||
case GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR:
|
||||
memory_model = "Direct";
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (! memory_model)
|
||||
continue;
|
||||
|
||||
grub_printf ("0x%03x: %4d x %4d x %2d %s",
|
||||
mode,
|
||||
mode_info_tmp.x_resolution,
|
||||
mode_info_tmp.y_resolution,
|
||||
mode_info_tmp.bits_per_pixel,
|
||||
memory_model);
|
||||
|
||||
/* Show mask and position details for direct color modes. */
|
||||
if (mode_info_tmp.memory_model == GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR)
|
||||
grub_printf (", mask: %d/%d/%d/%d pos: %d/%d/%d/%d",
|
||||
mode_info_tmp.red_mask_size,
|
||||
mode_info_tmp.green_mask_size,
|
||||
mode_info_tmp.blue_mask_size,
|
||||
mode_info_tmp.rsvd_mask_size,
|
||||
mode_info_tmp.red_field_position,
|
||||
mode_info_tmp.green_field_position,
|
||||
mode_info_tmp.blue_field_position,
|
||||
mode_info_tmp.rsvd_field_position);
|
||||
grub_printf ("\n");
|
||||
}
|
||||
|
||||
grub_free (saved_video_mode_list);
|
||||
|
||||
/* 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;
|
||||
else
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_printf ("Configured VBE mode (vbe_mode) = 0x%03x\n", use_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(vbeinfo)
|
||||
{
|
||||
cmd =
|
||||
grub_register_command ("vbeinfo", grub_cmd_vbeinfo, 0,
|
||||
N_("List compatible VESA BIOS extension video modes."));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(vbeinfo)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
/* vbetest.c - command to test VESA BIOS Extension 2.0+ support. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005,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/>.
|
||||
*/
|
||||
|
||||
#include <grub/normal.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/machine/init.h>
|
||||
#include <grub/machine/vbe.h>
|
||||
#include <grub/video.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_vbetest (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
grub_err_t err;
|
||||
char *modevar;
|
||||
struct grub_vbe_mode_info_block mode_info;
|
||||
struct grub_vbe_info_block controller_info;
|
||||
grub_uint32_t use_mode = GRUB_VBE_DEFAULT_VIDEO_MODE;
|
||||
grub_uint32_t old_mode;
|
||||
grub_uint8_t *framebuffer = 0;
|
||||
grub_uint32_t bytes_per_scan_line = 0;
|
||||
unsigned char *ptr;
|
||||
int i;
|
||||
|
||||
grub_printf ("Probing for VESA BIOS Extension ... ");
|
||||
|
||||
/* Check if VESA BIOS exists. */
|
||||
err = grub_vbe_probe (&controller_info);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
|
||||
grub_printf ("found!\n");
|
||||
|
||||
/* Dump out controller information. */
|
||||
grub_printf ("VBE signature = %c%c%c%c\n",
|
||||
controller_info.signature[0],
|
||||
controller_info.signature[1],
|
||||
controller_info.signature[2],
|
||||
controller_info.signature[3]);
|
||||
|
||||
grub_printf ("VBE version = %d.%d\n",
|
||||
controller_info.version >> 8,
|
||||
controller_info.version & 0xFF);
|
||||
grub_printf ("OEM string ptr = %08x\n",
|
||||
controller_info.oem_string_ptr);
|
||||
grub_printf ("Total memory = %d\n",
|
||||
controller_info.total_memory);
|
||||
|
||||
err = grub_vbe_get_video_mode (&old_mode);
|
||||
grub_printf ("Get video mode err = %04x\n", err);
|
||||
|
||||
if (err == GRUB_ERR_NONE)
|
||||
grub_printf ("Old video mode = %04x\n", old_mode);
|
||||
else
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
/* 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;
|
||||
else
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
err = grub_vbe_get_video_mode_info (use_mode, &mode_info);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
|
||||
/* Dump out details about the mode being tested. */
|
||||
grub_printf ("mode: 0x%03x\n",
|
||||
use_mode);
|
||||
grub_printf ("width : %d\n",
|
||||
mode_info.x_resolution);
|
||||
grub_printf ("height: %d\n",
|
||||
mode_info.y_resolution);
|
||||
grub_printf ("memory model: %02x\n",
|
||||
mode_info.memory_model);
|
||||
grub_printf ("bytes/scanline: %d\n",
|
||||
mode_info.bytes_per_scan_line);
|
||||
grub_printf ("bytes/scanline (lin): %d\n",
|
||||
mode_info.lin_bytes_per_scan_line);
|
||||
grub_printf ("base address: %08x\n",
|
||||
mode_info.phys_base_addr);
|
||||
grub_printf ("red mask/pos: %d/%d\n",
|
||||
mode_info.red_mask_size,
|
||||
mode_info.red_field_position);
|
||||
grub_printf ("green mask/pos: %d/%d\n",
|
||||
mode_info.green_mask_size,
|
||||
mode_info.green_field_position);
|
||||
grub_printf ("blue mask/pos: %d/%d\n",
|
||||
mode_info.blue_mask_size,
|
||||
mode_info.blue_field_position);
|
||||
|
||||
grub_printf ("Press any key to continue.\n");
|
||||
|
||||
grub_getkey ();
|
||||
|
||||
/* Setup GFX mode. */
|
||||
err = grub_vbe_set_video_mode (use_mode, &mode_info);
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
|
||||
/* Determine framebuffer address and how many bytes are in scan line. */
|
||||
framebuffer = (grub_uint8_t *) mode_info.phys_base_addr;
|
||||
ptr = framebuffer;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* Draw some random data to screen. */
|
||||
for (i = 0; i < 256 * 256; i++)
|
||||
{
|
||||
ptr[i] = i & 0x0F;
|
||||
}
|
||||
|
||||
/* Draw white line to screen. */
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
ptr[mode_info.bytes_per_scan_line * 50 + i] = 0x0F;
|
||||
}
|
||||
|
||||
/* Draw another white line to screen. */
|
||||
grub_memset (ptr + bytes_per_scan_line * 51, 0x0f, bytes_per_scan_line);
|
||||
|
||||
grub_getkey ();
|
||||
|
||||
grub_video_restore ();
|
||||
|
||||
/* Restore old video mode. */
|
||||
grub_vbe_set_video_mode (old_mode, 0);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(vbetest)
|
||||
{
|
||||
cmd = grub_register_command ("vbetest", grub_cmd_vbetest,
|
||||
0, N_("Test VESA BIOS Extension 2.0+ support."));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(vbetest)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
|
@ -36,17 +36,16 @@ static const struct grub_arg_option options[] =
|
|||
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
|
||||
grub_cmd_read (grub_extcmd_context_t ctxt, int argc, char **argv)
|
||||
{
|
||||
grub_target_addr_t addr;
|
||||
grub_uint32_t value = 0;
|
||||
char buf[sizeof ("XXXXXXXX")];
|
||||
|
||||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments");
|
||||
|
||||
addr = grub_strtoul (argv[0], 0, 0);
|
||||
switch (cmd->cmd->name[sizeof ("in") - 1])
|
||||
switch (ctxt->extcmd->cmd->name[sizeof ("in") - 1])
|
||||
{
|
||||
case 'l':
|
||||
value = grub_inl (addr);
|
||||
|
@ -61,10 +60,11 @@ grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
|
|||
break;
|
||||
}
|
||||
|
||||
if (cmd->state[0].set)
|
||||
if (ctxt->state[0].set)
|
||||
{
|
||||
char buf[sizeof ("XXXXXXXX")];
|
||||
grub_snprintf (buf, sizeof (buf), "%x", value);
|
||||
grub_env_set (cmd->state[0].arg, buf);
|
||||
grub_env_set (ctxt->state[0].arg, buf);
|
||||
}
|
||||
else
|
||||
grub_printf ("0x%x\n", value);
|
||||
|
@ -117,13 +117,13 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv)
|
|||
GRUB_MOD_INIT(memrw)
|
||||
{
|
||||
cmd_read_byte =
|
||||
grub_register_extcmd ("inb", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
|
||||
grub_register_extcmd ("inb", grub_cmd_read, 0,
|
||||
N_("PORT"), N_("Read byte from PORT."), options);
|
||||
cmd_read_word =
|
||||
grub_register_extcmd ("inw", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
|
||||
grub_register_extcmd ("inw", grub_cmd_read, 0,
|
||||
N_("PORT"), N_("Read word from PORT."), options);
|
||||
cmd_read_dword =
|
||||
grub_register_extcmd ("inl", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
|
||||
grub_register_extcmd ("inl", grub_cmd_read, 0,
|
||||
N_("PORT"), N_("Read dword from PORT."), options);
|
||||
cmd_write_byte =
|
||||
grub_register_command ("outb", grub_cmd_write,
|
||||
|
|
297
grub-core/commands/keylayouts.c
Normal file
297
grub-core/commands/keylayouts.c
Normal file
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2002,2003,2005,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/term.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/keyboard_layouts.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/file.h>
|
||||
|
||||
static struct grub_keyboard_layout layout_us = {
|
||||
.keyboard_map = {
|
||||
/* Keyboard errors. Handled by driver. */
|
||||
/* 0x00 */ 0, 0, 0, 0,
|
||||
|
||||
/* 0x04 */ 'a', 'b', 'c', 'd',
|
||||
/* 0x08 */ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
|
||||
/* 0x10 */ 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
|
||||
/* 0x18 */ 'u', 'v', 'w', 'x', 'y', 'z', '1', '2',
|
||||
/* 0x20 */ '3', '4', '5', '6', '7', '8', '9', '0',
|
||||
/* 0x28 */ '\n', '\e', '\b', '\t', ' ', '-', '=', '[',
|
||||
/* According to usage table 0x31 should be mapped to '/'
|
||||
but testing with real keyboard shows that 0x32 is remapped to '/'.
|
||||
Map 0x31 to 0.
|
||||
*/
|
||||
/* 0x30 */ ']', 0, '\\', ';', '\'', '`', ',', '.',
|
||||
/* 0x39 is CapsLock. Handled by driver. */
|
||||
/* 0x38 */ '/', 0, GRUB_TERM_KEY_F1, GRUB_TERM_KEY_F2,
|
||||
/* 0x3c */ GRUB_TERM_KEY_F3, GRUB_TERM_KEY_F4,
|
||||
/* 0x3e */ GRUB_TERM_KEY_F5, GRUB_TERM_KEY_F6,
|
||||
/* 0x40 */ GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8,
|
||||
/* 0x42 */ GRUB_TERM_KEY_F9, GRUB_TERM_KEY_F10,
|
||||
/* 0x44 */ GRUB_TERM_KEY_F11, GRUB_TERM_KEY_F12,
|
||||
/* PrtScr and ScrollLock. Not handled yet. */
|
||||
/* 0x46 */ 0, 0,
|
||||
/* 0x48 is Pause. Not handled yet. */
|
||||
/* 0x48 */ 0, GRUB_TERM_KEY_INSERT,
|
||||
/* 0x4a */ GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_PPAGE,
|
||||
/* 0x4c */ GRUB_TERM_KEY_DC, GRUB_TERM_KEY_END,
|
||||
/* 0x4e */ GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_RIGHT,
|
||||
/* 0x50 */ GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_DOWN,
|
||||
/* 0x53 is NumLock. Handled by driver. */
|
||||
/* 0x52 */ GRUB_TERM_KEY_UP, 0,
|
||||
/* 0x54 */ '/', '*',
|
||||
/* 0x56 */ '-', '+',
|
||||
/* 0x58 */ '\n', GRUB_TERM_KEY_END,
|
||||
/* 0x5a */ GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_NPAGE,
|
||||
/* 0x5c */ GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_CENTER,
|
||||
/* 0x5e */ GRUB_TERM_KEY_RIGHT, GRUB_TERM_KEY_HOME,
|
||||
/* 0x60 */ GRUB_TERM_KEY_UP, GRUB_TERM_KEY_PPAGE,
|
||||
/* 0x62 */ GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC,
|
||||
/* 0x64 */ '\\'
|
||||
},
|
||||
.keyboard_map_shift = {
|
||||
/* Keyboard errors. Handled by driver. */
|
||||
/* 0x00 */ 0, 0, 0, 0,
|
||||
|
||||
/* 0x04 */ 'A', 'B', 'C', 'D',
|
||||
/* 0x08 */ 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
|
||||
/* 0x10 */ 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||
/* 0x18 */ 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@',
|
||||
/* 0x20 */ '#', '$', '%', '^', '&', '*', '(', ')',
|
||||
/* 0x28 */ '\n' | GRUB_TERM_SHIFT, '\e' | GRUB_TERM_SHIFT,
|
||||
/* 0x2a */ '\b' | GRUB_TERM_SHIFT, '\t' | GRUB_TERM_SHIFT,
|
||||
/* 0x2c */ ' ' | GRUB_TERM_SHIFT, '_', '+', '{',
|
||||
/* According to usage table 0x31 should be mapped to '/'
|
||||
but testing with real keyboard shows that 0x32 is remapped to '/'.
|
||||
Map 0x31 to 0.
|
||||
*/
|
||||
/* 0x30 */ '}', 0, '|', ':', '"', '~', '<', '>',
|
||||
/* 0x39 is CapsLock. Handled by driver. */
|
||||
/* 0x38 */ '?', 0,
|
||||
/* 0x3a */ GRUB_TERM_KEY_F1 | GRUB_TERM_SHIFT,
|
||||
/* 0x3b */ GRUB_TERM_KEY_F2 | GRUB_TERM_SHIFT,
|
||||
/* 0x3c */ GRUB_TERM_KEY_F3 | GRUB_TERM_SHIFT,
|
||||
/* 0x3d */ GRUB_TERM_KEY_F4 | GRUB_TERM_SHIFT,
|
||||
/* 0x3e */ GRUB_TERM_KEY_F5 | GRUB_TERM_SHIFT,
|
||||
/* 0x3f */ GRUB_TERM_KEY_F6 | GRUB_TERM_SHIFT,
|
||||
/* 0x40 */ GRUB_TERM_KEY_F7 | GRUB_TERM_SHIFT,
|
||||
/* 0x41 */ GRUB_TERM_KEY_F8 | GRUB_TERM_SHIFT,
|
||||
/* 0x42 */ GRUB_TERM_KEY_F9 | GRUB_TERM_SHIFT,
|
||||
/* 0x43 */ GRUB_TERM_KEY_F10 | GRUB_TERM_SHIFT,
|
||||
/* 0x44 */ GRUB_TERM_KEY_F11 | GRUB_TERM_SHIFT,
|
||||
/* 0x45 */ GRUB_TERM_KEY_F12 | GRUB_TERM_SHIFT,
|
||||
/* PrtScr and ScrollLock. Not handled yet. */
|
||||
/* 0x46 */ 0, 0,
|
||||
/* 0x48 is Pause. Not handled yet. */
|
||||
/* 0x48 */ 0, GRUB_TERM_KEY_INSERT | GRUB_TERM_SHIFT,
|
||||
/* 0x4a */ GRUB_TERM_KEY_HOME | GRUB_TERM_SHIFT,
|
||||
/* 0x4b */ GRUB_TERM_KEY_PPAGE | GRUB_TERM_SHIFT,
|
||||
/* 0x4c */ GRUB_TERM_KEY_DC | GRUB_TERM_SHIFT,
|
||||
/* 0x4d */ GRUB_TERM_KEY_END | GRUB_TERM_SHIFT,
|
||||
/* 0x4e */ GRUB_TERM_KEY_NPAGE | GRUB_TERM_SHIFT,
|
||||
/* 0x4f */ GRUB_TERM_KEY_RIGHT | GRUB_TERM_SHIFT,
|
||||
/* 0x50 */ GRUB_TERM_KEY_LEFT | GRUB_TERM_SHIFT,
|
||||
/* 0x51 */ GRUB_TERM_KEY_DOWN | GRUB_TERM_SHIFT,
|
||||
/* 0x53 is NumLock. Handled by driver. */
|
||||
/* 0x52 */ GRUB_TERM_KEY_UP | GRUB_TERM_SHIFT, 0,
|
||||
/* 0x54 */ '/', '*',
|
||||
/* 0x56 */ '-', '+',
|
||||
/* 0x58 */ '\n' | GRUB_TERM_SHIFT, '1', '2', '3', '4', '5','6', '7',
|
||||
/* 0x60 */ '8', '9', '0', '.', '|'
|
||||
}
|
||||
};
|
||||
|
||||
static struct grub_keyboard_layout *grub_current_layout = &layout_us;
|
||||
|
||||
static int
|
||||
map_key_core (int code, int status, int *alt_gr_consumed)
|
||||
{
|
||||
*alt_gr_consumed = 0;
|
||||
|
||||
if (status & GRUB_TERM_STATUS_RALT)
|
||||
{
|
||||
if (status & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT))
|
||||
{
|
||||
if (grub_current_layout->keyboard_map_shift_l3[code])
|
||||
{
|
||||
*alt_gr_consumed = 1;
|
||||
return grub_current_layout->keyboard_map_shift_l3[code];
|
||||
}
|
||||
}
|
||||
else if (grub_current_layout->keyboard_map_l3[code])
|
||||
{
|
||||
*alt_gr_consumed = 1;
|
||||
return grub_current_layout->keyboard_map_l3[code];
|
||||
}
|
||||
}
|
||||
if (status & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT))
|
||||
return grub_current_layout->keyboard_map_shift[code];
|
||||
else
|
||||
return grub_current_layout->keyboard_map[code];
|
||||
}
|
||||
|
||||
unsigned
|
||||
grub_term_map_key (grub_keyboard_key_t code, int status)
|
||||
{
|
||||
int alt_gr_consumed = 0;
|
||||
int key;
|
||||
|
||||
if (code >= 0x59 && code <= 0x63 && (status & GRUB_TERM_STATUS_NUM))
|
||||
{
|
||||
if (status & (GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT))
|
||||
status &= ~(GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT);
|
||||
else
|
||||
status |= GRUB_TERM_STATUS_RSHIFT;
|
||||
}
|
||||
|
||||
key = map_key_core (code, status, &alt_gr_consumed);
|
||||
|
||||
if (key == 0 || key == GRUB_TERM_SHIFT)
|
||||
grub_printf ("Unknown key 0x%x detected\n", code);
|
||||
|
||||
if (status & GRUB_TERM_STATUS_CAPS)
|
||||
{
|
||||
if ((key >= 'a') && (key <= 'z'))
|
||||
key += 'A' - 'a';
|
||||
else if ((key >= 'A') && (key <= 'Z'))
|
||||
key += 'a' - 'A';
|
||||
}
|
||||
|
||||
if ((status & GRUB_TERM_STATUS_LALT) ||
|
||||
((status & GRUB_TERM_STATUS_RALT) && !alt_gr_consumed))
|
||||
key |= GRUB_TERM_ALT;
|
||||
if (status & (GRUB_TERM_STATUS_LCTRL | GRUB_TERM_STATUS_RCTRL))
|
||||
key |= GRUB_TERM_CTRL;
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
char *filename;
|
||||
grub_file_t file;
|
||||
grub_uint32_t version;
|
||||
grub_uint8_t magic[GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE];
|
||||
struct grub_keyboard_layout *newmap = NULL;
|
||||
unsigned i;
|
||||
|
||||
if (argc < 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file or layout name required");
|
||||
if (argv[0][0] != '(' && argv[0][0] != '/' && argv[0][0] != '+')
|
||||
{
|
||||
const char *prefix = grub_env_get ("prefix");
|
||||
if (!prefix)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "No prefix set");
|
||||
filename = grub_xasprintf ("%s/layouts/%s.gkb", prefix, argv[0]);
|
||||
if (!filename)
|
||||
return grub_errno;
|
||||
}
|
||||
else
|
||||
filename = argv[0];
|
||||
|
||||
file = grub_file_open (filename);
|
||||
if (! file)
|
||||
goto fail;
|
||||
|
||||
if (grub_file_read (file, magic, sizeof (magic)) != sizeof (magic))
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "file is too short");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (grub_memcmp (magic, GRUB_KEYBOARD_LAYOUTS_FILEMAGIC,
|
||||
GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE) != 0)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid magic");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (grub_file_read (file, &version, sizeof (version)) != sizeof (version))
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "file is too short");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (grub_le_to_cpu32 (version) != GRUB_KEYBOARD_LAYOUTS_VERSION)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid version");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
newmap = grub_malloc (sizeof (*newmap));
|
||||
if (!newmap)
|
||||
goto fail;
|
||||
|
||||
if (grub_file_read (file, newmap, sizeof (*newmap)) != sizeof (*newmap))
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "file is too short");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (newmap->keyboard_map); i++)
|
||||
newmap->keyboard_map[i] = grub_le_to_cpu32(newmap->keyboard_map[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (newmap->keyboard_map_shift); i++)
|
||||
newmap->keyboard_map_shift[i]
|
||||
= grub_le_to_cpu32(newmap->keyboard_map_shift[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (newmap->keyboard_map_l3); i++)
|
||||
newmap->keyboard_map_l3[i]
|
||||
= grub_le_to_cpu32(newmap->keyboard_map_l3[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (newmap->keyboard_map_shift_l3); i++)
|
||||
newmap->keyboard_map_shift_l3[i]
|
||||
= grub_le_to_cpu32(newmap->keyboard_map_shift_l3[i]);
|
||||
|
||||
grub_current_layout = newmap;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
fail:
|
||||
if (filename != argv[0])
|
||||
grub_free (filename);
|
||||
grub_free (newmap);
|
||||
if (file)
|
||||
grub_file_close (file);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(keylayouts)
|
||||
{
|
||||
cmd = grub_register_command ("keymap", grub_cmd_keymap,
|
||||
0, N_("Load a keyboard layout."));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(keylayouts)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
|
@ -31,23 +31,39 @@ static const struct grub_arg_option options[] =
|
|||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
#define grub_cur_term_input grub_term_get_current_input ()
|
||||
static int
|
||||
grub_getkeystatus (void)
|
||||
{
|
||||
int status = 0;
|
||||
grub_term_input_t term;
|
||||
|
||||
if (grub_term_poll_usb)
|
||||
grub_term_poll_usb ();
|
||||
|
||||
FOR_ACTIVE_TERM_INPUTS(term)
|
||||
{
|
||||
if (term->getkeystatus)
|
||||
status |= term->getkeystatus (term);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_keystatus (grub_extcmd_t cmd,
|
||||
grub_cmd_keystatus (grub_extcmd_context_t ctxt,
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
int expect_mods = 0;
|
||||
int mods;
|
||||
|
||||
if (state[0].set)
|
||||
expect_mods |= GRUB_TERM_STATUS_SHIFT;
|
||||
expect_mods |= (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT);
|
||||
if (state[1].set)
|
||||
expect_mods |= GRUB_TERM_STATUS_CTRL;
|
||||
expect_mods |= (GRUB_TERM_STATUS_LCTRL | GRUB_TERM_STATUS_RCTRL);
|
||||
if (state[2].set)
|
||||
expect_mods |= GRUB_TERM_STATUS_ALT;
|
||||
expect_mods |= (GRUB_TERM_STATUS_LALT | GRUB_TERM_STATUS_RALT);
|
||||
|
||||
grub_dprintf ("keystatus", "expect_mods: %d\n", expect_mods);
|
||||
|
||||
|
@ -80,8 +96,7 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(keystatus)
|
||||
{
|
||||
cmd = grub_register_extcmd ("keystatus", grub_cmd_keystatus,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd = grub_register_extcmd ("keystatus", grub_cmd_keystatus, 0,
|
||||
N_("[--shift] [--ctrl] [--alt]"),
|
||||
N_("Check key modifier status."),
|
||||
options);
|
||||
|
|
806
grub-core/commands/legacycfg.c
Normal file
806
grub-core/commands/legacycfg.c
Normal file
|
@ -0,0 +1,806 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2000, 2001, 2010 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/types.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/script_sh.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/legacy_parse.h>
|
||||
#include <grub/crypto.h>
|
||||
#include <grub/auth.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
|
||||
static grub_err_t
|
||||
legacy_file (const char *filename)
|
||||
{
|
||||
grub_file_t file;
|
||||
char *entryname = NULL, *entrysrc = NULL;
|
||||
grub_menu_t menu;
|
||||
char *suffix = grub_strdup ("");
|
||||
|
||||
auto grub_err_t getline (char **line, int cont);
|
||||
grub_err_t getline (char **line,
|
||||
int cont __attribute__ ((unused)))
|
||||
{
|
||||
*line = 0;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
if (!suffix)
|
||||
return grub_errno;
|
||||
|
||||
file = grub_file_open (filename);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
menu = grub_env_get_menu ();
|
||||
if (! menu)
|
||||
{
|
||||
menu = grub_zalloc (sizeof (*menu));
|
||||
if (! menu)
|
||||
return grub_errno;
|
||||
|
||||
grub_env_set_menu (menu);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
char *buf = grub_file_getline (file);
|
||||
char *parsed = NULL;
|
||||
|
||||
if (!buf && grub_errno)
|
||||
{
|
||||
grub_file_close (file);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
if (!buf)
|
||||
break;
|
||||
|
||||
{
|
||||
char *oldname = NULL;
|
||||
char *newsuffix;
|
||||
|
||||
oldname = entryname;
|
||||
parsed = grub_legacy_parse (buf, &entryname, &newsuffix);
|
||||
buf = NULL;
|
||||
if (newsuffix)
|
||||
{
|
||||
char *t;
|
||||
|
||||
t = suffix;
|
||||
suffix = grub_realloc (suffix, grub_strlen (suffix)
|
||||
+ grub_strlen (newsuffix) + 1);
|
||||
if (!suffix)
|
||||
{
|
||||
grub_free (t);
|
||||
grub_free (entrysrc);
|
||||
grub_free (parsed);
|
||||
grub_free (newsuffix);
|
||||
grub_free (suffix);
|
||||
return grub_errno;
|
||||
}
|
||||
grub_memcpy (suffix + grub_strlen (suffix), newsuffix,
|
||||
grub_strlen (newsuffix) + 1);
|
||||
grub_free (newsuffix);
|
||||
newsuffix = NULL;
|
||||
}
|
||||
if (oldname != entryname && oldname)
|
||||
{
|
||||
const char **args = grub_malloc (sizeof (args[0]));
|
||||
if (!args)
|
||||
{
|
||||
grub_file_close (file);
|
||||
return grub_errno;
|
||||
}
|
||||
args[0] = oldname;
|
||||
grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL,
|
||||
entrysrc, 0);
|
||||
grub_free (args);
|
||||
entrysrc[0] = 0;
|
||||
grub_free (oldname);
|
||||
}
|
||||
}
|
||||
|
||||
if (parsed && !entryname)
|
||||
{
|
||||
grub_normal_parse_line (parsed, getline);
|
||||
grub_print_error ();
|
||||
grub_free (parsed);
|
||||
parsed = NULL;
|
||||
}
|
||||
else if (parsed)
|
||||
{
|
||||
if (!entrysrc)
|
||||
entrysrc = parsed;
|
||||
else
|
||||
{
|
||||
char *t;
|
||||
|
||||
t = entrysrc;
|
||||
entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc)
|
||||
+ grub_strlen (parsed) + 1);
|
||||
if (!entrysrc)
|
||||
{
|
||||
grub_free (t);
|
||||
grub_free (parsed);
|
||||
grub_free (suffix);
|
||||
return grub_errno;
|
||||
}
|
||||
grub_memcpy (entrysrc + grub_strlen (entrysrc), parsed,
|
||||
grub_strlen (parsed) + 1);
|
||||
grub_free (parsed);
|
||||
parsed = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
grub_file_close (file);
|
||||
|
||||
if (entryname)
|
||||
{
|
||||
const char **args = grub_malloc (sizeof (args[0]));
|
||||
if (!args)
|
||||
{
|
||||
grub_file_close (file);
|
||||
return grub_errno;
|
||||
}
|
||||
args[0] = entryname;
|
||||
grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, NULL, entrysrc, 0);
|
||||
grub_free (args);
|
||||
}
|
||||
|
||||
grub_normal_parse_line (suffix, getline);
|
||||
grub_print_error ();
|
||||
grub_free (suffix);
|
||||
grub_free (entrysrc);
|
||||
|
||||
if (menu && menu->size)
|
||||
grub_show_menu (menu, 1);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_legacy_source (struct grub_command *cmd,
|
||||
int argc, char **args)
|
||||
{
|
||||
int new_env, extractor;
|
||||
grub_err_t ret;
|
||||
|
||||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
|
||||
|
||||
extractor = (cmd->name[0] == 'e');
|
||||
new_env = (cmd->name[extractor ? sizeof ("extract_legacy_entries_") - 1
|
||||
: sizeof ("legacy_") - 1] == 'c');
|
||||
|
||||
if (new_env)
|
||||
grub_cls ();
|
||||
|
||||
if (new_env && !extractor)
|
||||
grub_env_context_open ();
|
||||
if (extractor)
|
||||
grub_env_extractor_open (!new_env);
|
||||
|
||||
ret = legacy_file (args[0]);
|
||||
|
||||
if (new_env && !extractor)
|
||||
grub_env_context_close ();
|
||||
if (extractor)
|
||||
grub_env_extractor_close (!new_env);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum
|
||||
{
|
||||
GUESS_IT, LINUX, MULTIBOOT, KFREEBSD, KNETBSD, KOPENBSD
|
||||
} kernel_type;
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
int i;
|
||||
int no_mem_option = 0;
|
||||
struct grub_command *cmd;
|
||||
char **cutargs;
|
||||
int cutargc;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
/* FIXME: really support this. */
|
||||
if (argc >= 1 && grub_strcmp (args[0], "--no-mem-option") == 0)
|
||||
{
|
||||
no_mem_option = 1;
|
||||
argc--;
|
||||
args++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* linux16 handles both zImages and bzImages. */
|
||||
if (argc >= 1 && (grub_strcmp (args[0], "--type=linux") == 0
|
||||
|| grub_strcmp (args[0], "--type=biglinux") == 0))
|
||||
{
|
||||
kernel_type = LINUX;
|
||||
argc--;
|
||||
args++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argc >= 1 && grub_strcmp (args[0], "--type=multiboot") == 0)
|
||||
{
|
||||
kernel_type = MULTIBOOT;
|
||||
argc--;
|
||||
args++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argc >= 1 && grub_strcmp (args[0], "--type=freebsd") == 0)
|
||||
{
|
||||
kernel_type = KFREEBSD;
|
||||
argc--;
|
||||
args++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argc >= 1 && grub_strcmp (args[0], "--type=openbsd") == 0)
|
||||
{
|
||||
kernel_type = KOPENBSD;
|
||||
argc--;
|
||||
args++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argc >= 1 && grub_strcmp (args[0], "--type=netbsd") == 0)
|
||||
{
|
||||
kernel_type = KNETBSD;
|
||||
argc--;
|
||||
args++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc < 2)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "filename required");
|
||||
|
||||
cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1));
|
||||
cutargc = argc - 1;
|
||||
grub_memcpy (cutargs + 1, args + 2, sizeof (cutargs[0]) * (argc - 2));
|
||||
cutargs[0] = args[0];
|
||||
|
||||
do
|
||||
{
|
||||
/* First try Linux. */
|
||||
if (kernel_type == GUESS_IT || kernel_type == LINUX)
|
||||
{
|
||||
cmd = grub_command_find ("linux16");
|
||||
if (cmd)
|
||||
{
|
||||
if (!(cmd->func) (cmd, cutargc, cutargs))
|
||||
{
|
||||
kernel_type = LINUX;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Then multiboot. */
|
||||
if (kernel_type == GUESS_IT || kernel_type == MULTIBOOT)
|
||||
{
|
||||
cmd = grub_command_find ("multiboot");
|
||||
if (cmd)
|
||||
{
|
||||
if (!(cmd->func) (cmd, argc, args))
|
||||
{
|
||||
kernel_type = MULTIBOOT;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
{
|
||||
int bsd_device = -1;
|
||||
int bsd_slice = -1;
|
||||
int bsd_part = -1;
|
||||
{
|
||||
grub_device_t dev;
|
||||
char *hdbiasstr;
|
||||
int hdbias = 0;
|
||||
hdbiasstr = grub_env_get ("legacy_hdbias");
|
||||
if (hdbiasstr)
|
||||
{
|
||||
hdbias = grub_strtoul (hdbiasstr, 0, 0);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
dev = grub_device_open (0);
|
||||
if (dev && dev->disk
|
||||
&& dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID
|
||||
&& dev->disk->dev->id >= 0x80 && dev->disk->dev->id <= 0x90)
|
||||
{
|
||||
struct grub_partition *part = dev->disk->partition;
|
||||
bsd_device = dev->disk->id - 0x80 - hdbias;
|
||||
if (part && (grub_strcmp (part->partmap->name, "netbsd") == 0
|
||||
|| grub_strcmp (part->partmap->name, "openbsd") == 0
|
||||
|| grub_strcmp (part->partmap->name, "bsd") == 0))
|
||||
{
|
||||
bsd_part = part->number;
|
||||
part = part->parent;
|
||||
}
|
||||
if (part && grub_strcmp (part->partmap->name, "msdos") == 0)
|
||||
bsd_slice = part->number;
|
||||
}
|
||||
}
|
||||
|
||||
/* k*BSD didn't really work well with grub-legacy. */
|
||||
if (kernel_type == GUESS_IT || kernel_type == KFREEBSD)
|
||||
{
|
||||
char buf[sizeof("adXXXXXXXXXXXXsXXXXXXXXXXXXYYY")];
|
||||
if (bsd_device != -1)
|
||||
{
|
||||
if (bsd_slice != -1 && bsd_part != -1)
|
||||
grub_snprintf(buf, sizeof(buf), "ad%ds%d%c", bsd_device,
|
||||
bsd_slice, 'a' + bsd_part);
|
||||
else if (bsd_slice != -1)
|
||||
grub_snprintf(buf, sizeof(buf), "ad%ds%d", bsd_device,
|
||||
bsd_slice);
|
||||
else
|
||||
grub_snprintf(buf, sizeof(buf), "ad%d", bsd_device);
|
||||
grub_env_set ("kFreeBSD.vfs.root.mountfrom", buf);
|
||||
}
|
||||
else
|
||||
grub_env_unset ("kFreeBSD.vfs.root.mountfrom");
|
||||
cmd = grub_command_find ("kfreebsd");
|
||||
if (cmd)
|
||||
{
|
||||
if (!(cmd->func) (cmd, cutargc, cutargs))
|
||||
{
|
||||
kernel_type = KFREEBSD;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
{
|
||||
char **bsdargs;
|
||||
int bsdargc;
|
||||
char bsddevname[sizeof ("wdXXXXXXXXXXXXY")];
|
||||
if (bsd_device == -1)
|
||||
{
|
||||
bsdargs = cutargs;
|
||||
bsdargc = cutargc;
|
||||
}
|
||||
else
|
||||
{
|
||||
bsdargc = cutargc + 2;
|
||||
bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc);
|
||||
grub_memcpy (bsdargs, args, argc * sizeof (bsdargs[0]));
|
||||
bsdargs[argc] = "-r";
|
||||
bsdargs[argc + 1] = bsddevname;
|
||||
grub_snprintf (bsddevname, sizeof (bsddevname),
|
||||
"wd%d%c", bsd_device,
|
||||
bsd_part != -1 ? bsd_part + 'a' : 'c');
|
||||
}
|
||||
if (kernel_type == GUESS_IT || kernel_type == KNETBSD)
|
||||
{
|
||||
cmd = grub_command_find ("knetbsd");
|
||||
if (cmd)
|
||||
{
|
||||
if (!(cmd->func) (cmd, bsdargc, bsdargs))
|
||||
{
|
||||
kernel_type = KNETBSD;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
if (kernel_type == GUESS_IT || kernel_type == KOPENBSD)
|
||||
{
|
||||
cmd = grub_command_find ("kopenbsd");
|
||||
if (cmd)
|
||||
{
|
||||
if (!(cmd->func) (cmd, bsdargc, bsdargs))
|
||||
{
|
||||
kernel_type = KOPENBSD;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
}
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
if (bsdargs != cutargs)
|
||||
grub_free (bsdargs);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (0);
|
||||
|
||||
return grub_error (GRUB_ERR_BAD_OS, "couldn't load file %s\n",
|
||||
args[0]);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_legacy_initrd (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
struct grub_command *cmd;
|
||||
|
||||
if (kernel_type == LINUX)
|
||||
{
|
||||
cmd = grub_command_find ("initrd16");
|
||||
if (!cmd)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "command initrd16 not found");
|
||||
|
||||
return cmd->func (cmd, argc, args);
|
||||
}
|
||||
if (kernel_type == MULTIBOOT)
|
||||
{
|
||||
cmd = grub_command_find ("module");
|
||||
if (!cmd)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "command module not found");
|
||||
|
||||
return cmd->func (cmd, argc, args);
|
||||
}
|
||||
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
"no kernel with module support is loaded in legacy way");
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
struct grub_command *cmd;
|
||||
|
||||
if (kernel_type == LINUX)
|
||||
{
|
||||
cmd = grub_command_find ("initrd16");
|
||||
if (!cmd)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "command initrd16 not found");
|
||||
|
||||
return cmd->func (cmd, argc, args);
|
||||
}
|
||||
if (kernel_type == MULTIBOOT)
|
||||
{
|
||||
char **newargs;
|
||||
grub_err_t err;
|
||||
newargs = grub_malloc ((argc + 1) * sizeof (newargs[0]));
|
||||
if (!newargs)
|
||||
return grub_errno;
|
||||
grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0]));
|
||||
newargs[0] = "--nounzip";
|
||||
cmd = grub_command_find ("module");
|
||||
if (!cmd)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "command module not found");
|
||||
|
||||
err = cmd->func (cmd, argc + 1, newargs);
|
||||
grub_free (newargs);
|
||||
return err;
|
||||
}
|
||||
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
"no kernel with module support is loaded in legacy way");
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
check_password_deny (const char *user __attribute__ ((unused)),
|
||||
const char *entered __attribute__ ((unused)),
|
||||
void *password __attribute__ ((unused)))
|
||||
{
|
||||
return GRUB_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
#define MD5_HASHLEN 16
|
||||
|
||||
struct legacy_md5_password
|
||||
{
|
||||
grub_uint8_t *salt;
|
||||
int saltlen;
|
||||
grub_uint8_t hash[MD5_HASHLEN];
|
||||
};
|
||||
|
||||
static int
|
||||
check_password_md5_real (const char *entered,
|
||||
struct legacy_md5_password *pw)
|
||||
{
|
||||
int enteredlen = grub_strlen (entered);
|
||||
unsigned char alt_result[MD5_HASHLEN];
|
||||
unsigned char *digest;
|
||||
grub_uint8_t ctx[GRUB_MD_MD5->contextsize];
|
||||
int i;
|
||||
|
||||
GRUB_MD_MD5->init (ctx);
|
||||
GRUB_MD_MD5->write (ctx, entered, enteredlen);
|
||||
GRUB_MD_MD5->write (ctx, pw->salt + 3, pw->saltlen - 3);
|
||||
GRUB_MD_MD5->write (ctx, entered, enteredlen);
|
||||
digest = GRUB_MD_MD5->read (ctx);
|
||||
GRUB_MD_MD5->final (ctx);
|
||||
memcpy (alt_result, digest, MD5_HASHLEN);
|
||||
|
||||
GRUB_MD_MD5->init (ctx);
|
||||
GRUB_MD_MD5->write (ctx, entered, enteredlen);
|
||||
GRUB_MD_MD5->write (ctx, pw->salt, pw->saltlen); /* include the $1$ header */
|
||||
for (i = enteredlen; i > 16; i -= 16)
|
||||
GRUB_MD_MD5->write (ctx, alt_result, 16);
|
||||
GRUB_MD_MD5->write (ctx, alt_result, i);
|
||||
|
||||
for (i = enteredlen; i > 0; i >>= 1)
|
||||
GRUB_MD_MD5->write (ctx, entered + ((i & 1) ? enteredlen : 0), 1);
|
||||
digest = GRUB_MD_MD5->read (ctx);
|
||||
GRUB_MD_MD5->final (ctx);
|
||||
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
memcpy (alt_result, digest, 16);
|
||||
|
||||
GRUB_MD_MD5->init (ctx);
|
||||
if ((i & 1) != 0)
|
||||
GRUB_MD_MD5->write (ctx, entered, enteredlen);
|
||||
else
|
||||
GRUB_MD_MD5->write (ctx, alt_result, 16);
|
||||
|
||||
if (i % 3 != 0)
|
||||
GRUB_MD_MD5->write (ctx, pw->salt + 3, pw->saltlen - 3);
|
||||
|
||||
if (i % 7 != 0)
|
||||
GRUB_MD_MD5->write (ctx, entered, enteredlen);
|
||||
|
||||
if ((i & 1) != 0)
|
||||
GRUB_MD_MD5->write (ctx, alt_result, 16);
|
||||
else
|
||||
GRUB_MD_MD5->write (ctx, entered, enteredlen);
|
||||
digest = GRUB_MD_MD5->read (ctx);
|
||||
GRUB_MD_MD5->final (ctx);
|
||||
}
|
||||
|
||||
return (grub_crypto_memcmp (digest, pw->hash, MD5_HASHLEN) == 0);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
check_password_md5 (const char *user,
|
||||
const char *entered,
|
||||
void *password)
|
||||
{
|
||||
if (!check_password_md5_real (entered, password))
|
||||
return GRUB_ACCESS_DENIED;
|
||||
|
||||
grub_auth_authenticate (user);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ib64t (char c)
|
||||
{
|
||||
if (c == '.')
|
||||
return 0;
|
||||
if (c == '/')
|
||||
return 1;
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0' + 2;
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return c - 'A' + 12;
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return c - 'a' + 38;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct legacy_md5_password *
|
||||
parse_legacy_md5 (int argc, char **args)
|
||||
{
|
||||
const char *salt, *saltend;
|
||||
struct legacy_md5_password *pw = NULL;
|
||||
int i;
|
||||
const char *p;
|
||||
|
||||
if (grub_memcmp (args[0], "--md5", sizeof ("--md5")) != 0)
|
||||
goto fail;
|
||||
if (argc == 1)
|
||||
goto fail;
|
||||
if (grub_strlen(args[1]) <= 3)
|
||||
goto fail;
|
||||
salt = args[1];
|
||||
saltend = grub_strchr (salt + 3, '$');
|
||||
if (!saltend)
|
||||
goto fail;
|
||||
pw = grub_malloc (sizeof (*pw));
|
||||
if (!pw)
|
||||
goto fail;
|
||||
|
||||
p = saltend + 1;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
int n;
|
||||
grub_uint32_t w = 0;
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
int ww = ib64t(*p++);
|
||||
if (ww == -1)
|
||||
goto fail;
|
||||
w |= ww << (n * 6);
|
||||
}
|
||||
pw->hash[i == 4 ? 5 : 12+i] = w & 0xff;
|
||||
pw->hash[6+i] = (w >> 8) & 0xff;
|
||||
pw->hash[i] = (w >> 16) & 0xff;
|
||||
}
|
||||
{
|
||||
int n;
|
||||
grub_uint32_t w = 0;
|
||||
for (n = 0; n < 2; n++)
|
||||
{
|
||||
int ww = ib64t(*p++);
|
||||
if (ww == -1)
|
||||
goto fail;
|
||||
w |= ww << (6 * n);
|
||||
}
|
||||
if (w >= 0x100)
|
||||
goto fail;
|
||||
pw->hash[11] = w;
|
||||
}
|
||||
|
||||
pw->saltlen = saltend - salt;
|
||||
pw->salt = (grub_uint8_t *) grub_strndup (salt, pw->saltlen);
|
||||
if (!pw->salt)
|
||||
goto fail;
|
||||
|
||||
return pw;
|
||||
|
||||
fail:
|
||||
grub_free (pw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_legacy_password (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
struct legacy_md5_password *pw = NULL;
|
||||
|
||||
if (argc == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments expected");
|
||||
if (args[0][0] != '-' || args[0][1] != '-')
|
||||
return grub_normal_set_password ("legacy", args[0]);
|
||||
|
||||
pw = parse_legacy_md5 (argc, args);
|
||||
|
||||
if (pw)
|
||||
return grub_auth_register_authentication ("legacy", check_password_md5, pw);
|
||||
else
|
||||
/* This is to imitate minor difference between grub-legacy in GRUB2.
|
||||
If 2 password commands are executed in a row and second one fails
|
||||
on GRUB2 the password of first one is used, whereas in grub-legacy
|
||||
authenthication is denied. In case of no password command was executed
|
||||
early both versions deny any access. */
|
||||
return grub_auth_register_authentication ("legacy", check_password_deny,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_legacy_check_password (struct grub_command *mycmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
struct legacy_md5_password *pw = NULL;
|
||||
char entered[GRUB_AUTH_MAX_PASSLEN];
|
||||
|
||||
if (argc == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "arguments expected");
|
||||
grub_printf ("Enter password:");
|
||||
if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
|
||||
return GRUB_ACCESS_DENIED;
|
||||
|
||||
if (args[0][0] != '-' || args[0][1] != '-')
|
||||
{
|
||||
char correct[GRUB_AUTH_MAX_PASSLEN];
|
||||
|
||||
grub_memset (correct, 0, sizeof (correct));
|
||||
grub_strncpy (correct, args[0], sizeof (correct));
|
||||
|
||||
if (grub_crypto_memcmp (entered, correct, GRUB_AUTH_MAX_PASSLEN) != 0)
|
||||
return GRUB_ACCESS_DENIED;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
pw = parse_legacy_md5 (argc, args);
|
||||
|
||||
if (!pw)
|
||||
return GRUB_ACCESS_DENIED;
|
||||
|
||||
if (!check_password_md5_real (entered, pw))
|
||||
return GRUB_ACCESS_DENIED;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_command_t cmd_source, cmd_configfile;
|
||||
static grub_command_t cmd_source_extract, cmd_configfile_extract;
|
||||
static grub_command_t cmd_kernel, cmd_initrd, cmd_initrdnounzip;
|
||||
static grub_command_t cmd_password, cmd_check_password;
|
||||
|
||||
GRUB_MOD_INIT(legacycfg)
|
||||
{
|
||||
cmd_source
|
||||
= grub_register_command ("legacy_source",
|
||||
grub_cmd_legacy_source,
|
||||
N_("FILE"),
|
||||
N_("Parse legacy config in same context"));
|
||||
cmd_configfile
|
||||
= grub_register_command ("legacy_configfile",
|
||||
grub_cmd_legacy_source,
|
||||
N_("FILE"),
|
||||
N_("Parse legacy config in new context"));
|
||||
cmd_source_extract
|
||||
= grub_register_command ("extract_legacy_entries_source",
|
||||
grub_cmd_legacy_source,
|
||||
N_("FILE"),
|
||||
N_("Parse legacy config in same context taking onl entries"));
|
||||
cmd_configfile_extract
|
||||
= grub_register_command ("extract_legacy_entries_configfile",
|
||||
grub_cmd_legacy_source,
|
||||
N_("FILE"),
|
||||
N_("Parse legacy config in new context taking onl entries"));
|
||||
|
||||
cmd_kernel = grub_register_command ("legacy_kernel",
|
||||
grub_cmd_legacy_kernel,
|
||||
N_("[--no-mem-option] [--type=TYPE] FILE [ARG ...]"),
|
||||
N_("Simulate grub-legacy kernel command"));
|
||||
|
||||
cmd_initrd = grub_register_command ("legacy_initrd",
|
||||
grub_cmd_legacy_initrd,
|
||||
N_("FILE [ARG ...]"),
|
||||
N_("Simulate grub-legacy initrd command"));
|
||||
cmd_initrdnounzip = grub_register_command ("legacy_initrd_nounzip",
|
||||
grub_cmd_legacy_initrdnounzip,
|
||||
N_("FILE [ARG ...]"),
|
||||
N_("Simulate grub-legacy modulenounzip command"));
|
||||
|
||||
cmd_password = grub_register_command ("legacy_password",
|
||||
grub_cmd_legacy_password,
|
||||
N_("[--md5] PASSWD [FILE]"),
|
||||
N_("Simulate grub-legacy password command"));
|
||||
|
||||
cmd_check_password = grub_register_command ("legacy_check_password",
|
||||
grub_cmd_legacy_check_password,
|
||||
N_("[--md5] PASSWD [FILE]"),
|
||||
N_("Simulate grub-legacy password command in menuentry mode"));
|
||||
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(legacycfg)
|
||||
{
|
||||
grub_unregister_command (cmd_source);
|
||||
grub_unregister_command (cmd_configfile);
|
||||
grub_unregister_command (cmd_source_extract);
|
||||
grub_unregister_command (cmd_configfile_extract);
|
||||
|
||||
grub_unregister_command (cmd_kernel);
|
||||
grub_unregister_command (cmd_initrd);
|
||||
grub_unregister_command (cmd_initrdnounzip);
|
||||
|
||||
grub_unregister_command (cmd_password);
|
||||
grub_unregister_command (cmd_check_password);
|
||||
}
|
|
@ -56,6 +56,7 @@ open_envblk_file (char *filename)
|
|||
grub_strcpy (filename, prefix);
|
||||
filename[len] = '/';
|
||||
grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG);
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (filename);
|
||||
grub_free (filename);
|
||||
return file;
|
||||
|
@ -67,6 +68,7 @@ open_envblk_file (char *filename)
|
|||
}
|
||||
}
|
||||
|
||||
grub_file_filter_disable_compression ();
|
||||
return grub_file_open (filename);
|
||||
}
|
||||
|
||||
|
@ -111,11 +113,11 @@ read_envblk_file (grub_file_t file)
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_load_env (grub_extcmd_t cmd,
|
||||
grub_cmd_load_env (grub_extcmd_context_t ctxt,
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
grub_file_t file;
|
||||
grub_envblk_t envblk;
|
||||
|
||||
|
@ -143,11 +145,11 @@ grub_cmd_load_env (grub_extcmd_t cmd,
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_list_env (grub_extcmd_t cmd,
|
||||
grub_cmd_list_env (grub_extcmd_context_t ctxt,
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
grub_file_t file;
|
||||
grub_envblk_t envblk;
|
||||
|
||||
|
@ -280,9 +282,9 @@ write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists,
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_save_env (grub_extcmd_t cmd, int argc, char **args)
|
||||
grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
grub_file_t file;
|
||||
grub_envblk_t envblk;
|
||||
struct blocklist *head = 0;
|
||||
|
@ -373,20 +375,15 @@ static grub_extcmd_t cmd_load, cmd_list, cmd_save;
|
|||
GRUB_MOD_INIT(loadenv)
|
||||
{
|
||||
cmd_load =
|
||||
grub_register_extcmd ("load_env", grub_cmd_load_env,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
N_("[-f FILE]"),
|
||||
grub_register_extcmd ("load_env", grub_cmd_load_env, 0, N_("[-f FILE]"),
|
||||
N_("Load variables from environment block file."),
|
||||
options);
|
||||
cmd_list =
|
||||
grub_register_extcmd ("list_env", grub_cmd_list_env,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
N_("[-f FILE]"),
|
||||
grub_register_extcmd ("list_env", grub_cmd_list_env, 0, N_("[-f FILE]"),
|
||||
N_("List variables from environment block file."),
|
||||
options);
|
||||
cmd_save =
|
||||
grub_register_extcmd ("save_env", grub_cmd_save_env,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
grub_register_extcmd ("save_env", grub_cmd_save_env, 0,
|
||||
N_("[-f FILE] variable_name [...]"),
|
||||
N_("Save variables to environment block file."),
|
||||
options);
|
||||
|
|
|
@ -120,6 +120,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
|
|||
|
||||
/* XXX: For ext2fs symlinks are detected as files while they
|
||||
should be reported as directories. */
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (pathname);
|
||||
if (! file)
|
||||
{
|
||||
|
@ -226,6 +227,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
|
|||
struct grub_dirhook_info info;
|
||||
grub_errno = 0;
|
||||
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (dirname);
|
||||
if (! file)
|
||||
goto fail;
|
||||
|
@ -263,15 +265,17 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_ls (grub_extcmd_t cmd, int argc, char **args)
|
||||
grub_cmd_ls (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
int i;
|
||||
|
||||
if (argc == 0)
|
||||
grub_ls_list_devices (state[0].set);
|
||||
else
|
||||
grub_ls_list_files (args[0], state[0].set, state[2].set,
|
||||
state[1].set);
|
||||
for (i = 0; i < argc; i++)
|
||||
grub_ls_list_files (args[i], state[0].set, state[2].set,
|
||||
state[1].set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -280,8 +284,8 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(ls)
|
||||
{
|
||||
cmd = grub_register_extcmd ("ls", grub_cmd_ls, GRUB_COMMAND_FLAG_BOTH,
|
||||
N_("[-l|-h|-a] [FILE]"),
|
||||
cmd = grub_register_extcmd ("ls", grub_cmd_ls, 0,
|
||||
N_("[-l|-h|-a] [FILE ...]"),
|
||||
N_("List devices and files."), options);
|
||||
}
|
||||
|
||||
|
|
250
grub-core/commands/lsacpi.c
Normal file
250
grub-core/commands/lsacpi.c
Normal file
|
@ -0,0 +1,250 @@
|
|||
/* acpi.c - Display acpi tables. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 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/types.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/acpi.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
static void
|
||||
print_strn (grub_uint8_t *str, grub_size_t len)
|
||||
{
|
||||
for (; *str && len; str++, len--)
|
||||
grub_printf ("%c", *str);
|
||||
for (len++; len; len--)
|
||||
grub_printf (" ");
|
||||
}
|
||||
|
||||
#define print_field(x) print_strn(x, sizeof (x))
|
||||
|
||||
static void
|
||||
disp_acpi_table (struct grub_acpi_table_header *t)
|
||||
{
|
||||
print_field (t->signature);
|
||||
grub_printf ("%4" PRIuGRUB_UINT32_T "B rev=%u OEM=", t->length, t->revision);
|
||||
print_field (t->oemid);
|
||||
print_field (t->oemtable);
|
||||
grub_printf ("OEMrev=%08" PRIxGRUB_UINT32_T " ", t->oemrev);
|
||||
print_field (t->creator_id);
|
||||
grub_printf (" %08" PRIxGRUB_UINT32_T "\n", t->creator_rev);
|
||||
}
|
||||
|
||||
static void
|
||||
disp_madt_table (struct grub_acpi_madt *t)
|
||||
{
|
||||
struct grub_acpi_madt_entry_header *d;
|
||||
grub_uint32_t len;
|
||||
|
||||
disp_acpi_table (&t->hdr);
|
||||
grub_printf ("Local APIC=%08" PRIxGRUB_UINT32_T " Flags=%08"
|
||||
PRIxGRUB_UINT32_T "\n",
|
||||
t->lapic_addr, t->flags);
|
||||
len = t->hdr.length - sizeof (struct grub_acpi_madt);
|
||||
d = t->entries;
|
||||
for (;len > 0; len -= d->len, d = (void *) ((grub_uint8_t *) d + d->len))
|
||||
{
|
||||
grub_printf (" type=%x l=%u ", d->type, d->len);
|
||||
|
||||
switch (d->type)
|
||||
{
|
||||
case GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE:
|
||||
{
|
||||
struct grub_acpi_madt_entry_interrupt_override *dt = (void *) d;
|
||||
grub_printf ("Int Override bus=%x src=%x GSI=%08x Flags=%04x\n",
|
||||
dt->bus, dt->source, dt->global_sys_interrupt,
|
||||
dt->flags);
|
||||
}
|
||||
break;
|
||||
case GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC:
|
||||
{
|
||||
struct grub_acpi_madt_entry_sapic *dt = (void *) d;
|
||||
grub_printf ("IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T
|
||||
"\n",
|
||||
dt->id, dt->global_sys_interrupt_base,
|
||||
dt->addr);
|
||||
}
|
||||
break;
|
||||
case GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC:
|
||||
{
|
||||
struct grub_acpi_madt_entry_lsapic *dt = (void *) d;
|
||||
grub_printf ("LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x",
|
||||
dt->cpu_id, dt->id, dt->eid, dt->flags);
|
||||
if (dt->flags & GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED)
|
||||
grub_printf (" Enabled\n");
|
||||
else
|
||||
grub_printf (" Disabled\n");
|
||||
if (d->len > sizeof (struct grub_acpi_madt_entry_sapic))
|
||||
grub_printf (" UID val=%08x, Str=%s\n", dt->cpu_uid,
|
||||
dt->cpu_uid_str);
|
||||
}
|
||||
break;
|
||||
case GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE:
|
||||
{
|
||||
struct grub_acpi_madt_entry_platform_int_source *dt = (void *) d;
|
||||
static const char * const platint_type[] =
|
||||
{"Nul", "PMI", "INIT", "CPEI"};
|
||||
|
||||
grub_printf ("Platform INT flags=%04x type=%02x (%s)"
|
||||
" ID=%02x EID=%02x\n",
|
||||
dt->flags, dt->inttype,
|
||||
(dt->inttype < ARRAY_SIZE (platint_type))
|
||||
? platint_type[dt->inttype] : "??", dt->cpu_id,
|
||||
dt->cpu_eid);
|
||||
grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n",
|
||||
dt->sapic_vector, dt->global_sys_int, dt->src_flags);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
grub_printf (" ??\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
disp_acpi_xsdt_table (struct grub_acpi_table_header *t)
|
||||
{
|
||||
grub_uint32_t len;
|
||||
grub_uint64_t *desc;
|
||||
|
||||
disp_acpi_table (t);
|
||||
len = t->length - sizeof (*t);
|
||||
desc = (grub_uint64_t *) (t + 1);
|
||||
for (; len > 0; desc++, len -= sizeof (*desc))
|
||||
{
|
||||
if (sizeof (grub_addr_t) == 4 && *desc >= (1ULL << 32))
|
||||
{
|
||||
grub_printf ("Unreachable table\n");
|
||||
continue;
|
||||
}
|
||||
t = (struct grub_acpi_table_header *) (grub_addr_t) *desc;
|
||||
|
||||
if (t == NULL)
|
||||
continue;
|
||||
|
||||
if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE,
|
||||
sizeof (t->signature)) == 0)
|
||||
disp_madt_table ((struct grub_acpi_madt *) t);
|
||||
else
|
||||
disp_acpi_table (t);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
disp_acpi_rsdt_table (struct grub_acpi_table_header *t)
|
||||
{
|
||||
grub_uint32_t len;
|
||||
grub_uint32_t *desc;
|
||||
|
||||
disp_acpi_table (t);
|
||||
len = t->length - sizeof (*t);
|
||||
desc = (grub_uint32_t *) (t + 1);
|
||||
for (; len > 0; desc++, len -= sizeof (*desc))
|
||||
{
|
||||
t = (struct grub_acpi_table_header *) (grub_addr_t) *desc;
|
||||
|
||||
if (t == NULL)
|
||||
continue;
|
||||
|
||||
if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE,
|
||||
sizeof (t->signature)) == 0)
|
||||
disp_madt_table ((struct grub_acpi_madt *) t);
|
||||
else
|
||||
disp_acpi_table (t);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10 *rsdp)
|
||||
{
|
||||
print_field (rsdp->signature);
|
||||
grub_printf ("chksum:%02x, OEM-ID: ", rsdp->checksum);
|
||||
print_field (rsdp->oemid);
|
||||
grub_printf ("rev=%d\n", rsdp->revision);
|
||||
grub_printf ("RSDT=%08" PRIxGRUB_UINT32_T "\n", rsdp->rsdt_addr);
|
||||
}
|
||||
|
||||
static void
|
||||
disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp)
|
||||
{
|
||||
disp_acpi_rsdpv1 (&rsdp->rsdpv1);
|
||||
grub_printf ("len=%d XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length,
|
||||
rsdp->xsdt_addr);
|
||||
}
|
||||
|
||||
static const struct grub_arg_option options[] = {
|
||||
{"v1", '1', 0, N_("Show v1 tables only."), 0, ARG_TYPE_NONE},
|
||||
{"v2", '2', 0, N_("Show v2 and v3 tablesv only."), 0, ARG_TYPE_NONE}
|
||||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_lsacpi (struct grub_extcmd_context *ctxt,
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
if (!ctxt->state[1].set)
|
||||
{
|
||||
struct grub_acpi_rsdp_v10 *rsdp1 = grub_acpi_get_rsdpv1 ();
|
||||
if (!rsdp1)
|
||||
grub_printf ("No RSDPv1\n");
|
||||
else
|
||||
{
|
||||
grub_printf ("RSDPv1 signature:");
|
||||
disp_acpi_rsdpv1 (rsdp1);
|
||||
disp_acpi_rsdt_table ((void *) (grub_addr_t) rsdp1->rsdt_addr);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ctxt->state[0].set)
|
||||
{
|
||||
struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 ();
|
||||
if (!rsdp2)
|
||||
grub_printf ("No RSDPv2\n");
|
||||
else
|
||||
{
|
||||
if (sizeof (grub_addr_t) == 4 && rsdp2->xsdt_addr >= (1ULL << 32))
|
||||
grub_printf ("Unreachable RSDPv2\n");
|
||||
else
|
||||
{
|
||||
grub_printf ("RSDPv2 signature:");
|
||||
disp_acpi_rsdpv2 (rsdp2);
|
||||
disp_acpi_xsdt_table ((void *) (grub_addr_t) rsdp2->xsdt_addr);
|
||||
grub_printf ("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_extcmd_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(lsapi)
|
||||
{
|
||||
cmd = grub_register_extcmd ("lsacpi", grub_cmd_lsacpi, 0, N_("[-1|-2]"),
|
||||
N_("Show ACPI information."), options);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(lsacpi)
|
||||
{
|
||||
grub_unregister_extcmd (cmd);
|
||||
}
|
||||
|
||||
|
|
@ -16,24 +16,39 @@
|
|||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRUB_MACHINE_EMU
|
||||
#include <grub/machine/memory.h>
|
||||
#endif
|
||||
#include <grub/dl.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/memory.h>
|
||||
|
||||
static const char *names[] =
|
||||
{
|
||||
[GRUB_MEMORY_AVAILABLE] = "available",
|
||||
[GRUB_MEMORY_RESERVED] = "reserved",
|
||||
[GRUB_MEMORY_ACPI] = "ACPI reclamaible",
|
||||
[GRUB_MEMORY_NVS] = "NVS",
|
||||
[GRUB_MEMORY_BADRAM] = "BadRAM",
|
||||
[GRUB_MEMORY_CODE] = "firmware code",
|
||||
[GRUB_MEMORY_HOLE] = "hole"
|
||||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_lsmmap (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)), char **args __attribute__ ((unused)))
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
|
||||
{
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
||||
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_memory_type_t);
|
||||
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
|
||||
grub_memory_type_t type)
|
||||
{
|
||||
grub_printf ("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n",
|
||||
(long long) addr, (long long) size, type);
|
||||
if (type < ARRAY_SIZE (names) && names[type])
|
||||
grub_printf ("base_addr = 0x%llx, length = 0x%llx, %s\n",
|
||||
(long long) addr, (long long) size, names[type]);
|
||||
else
|
||||
grub_printf ("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n",
|
||||
(long long) addr, (long long) size, type);
|
||||
return 0;
|
||||
}
|
||||
#ifndef GRUB_MACHINE_EMU
|
||||
|
|
|
@ -211,11 +211,11 @@ grub_lspci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_lspci (grub_extcmd_t cmd,
|
||||
grub_cmd_lspci (grub_extcmd_context_t ctxt,
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
iospace = cmd->state[0].set;
|
||||
iospace = ctxt->state[0].set;
|
||||
grub_pci_iterate (grub_lspci_iter);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
@ -224,8 +224,8 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(lspci)
|
||||
{
|
||||
cmd = grub_register_extcmd ("lspci", grub_cmd_lspci, GRUB_COMMAND_FLAG_BOTH,
|
||||
"[-i]", N_("List PCI devices."), options);
|
||||
cmd = grub_register_extcmd ("lspci", grub_cmd_lspci, 0, "[-i]",
|
||||
N_("List PCI devices."), options);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(lspci)
|
||||
|
|
|
@ -35,7 +35,7 @@ static const struct grub_arg_option options[] =
|
|||
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
|
||||
grub_cmd_read (grub_extcmd_context_t ctxt, int argc, char **argv)
|
||||
{
|
||||
grub_target_addr_t addr;
|
||||
grub_uint32_t value = 0;
|
||||
|
@ -45,7 +45,7 @@ grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
|
|||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid number of arguments");
|
||||
|
||||
addr = grub_strtoul (argv[0], 0, 0);
|
||||
switch (cmd->cmd->name[sizeof ("read_") - 1])
|
||||
switch (ctxt->extcmd->cmd->name[sizeof ("read_") - 1])
|
||||
{
|
||||
case 'd':
|
||||
value = *((volatile grub_uint32_t *) addr);
|
||||
|
@ -60,10 +60,10 @@ grub_cmd_read (grub_extcmd_t cmd, int argc, char **argv)
|
|||
break;
|
||||
}
|
||||
|
||||
if (cmd->state[0].set)
|
||||
if (ctxt->state[0].set)
|
||||
{
|
||||
grub_snprintf (buf, sizeof (buf), "%x", value);
|
||||
grub_env_set (cmd->state[0].arg, buf);
|
||||
grub_env_set (ctxt->state[0].arg, buf);
|
||||
}
|
||||
else
|
||||
grub_printf ("0x%x\n", value);
|
||||
|
@ -119,13 +119,13 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv)
|
|||
GRUB_MOD_INIT(memrw)
|
||||
{
|
||||
cmd_read_byte =
|
||||
grub_register_extcmd ("read_byte", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
|
||||
grub_register_extcmd ("read_byte", grub_cmd_read, 0,
|
||||
N_("ADDR"), N_("Read byte from ADDR."), options);
|
||||
cmd_read_word =
|
||||
grub_register_extcmd ("read_word", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
|
||||
grub_register_extcmd ("read_word", grub_cmd_read, 0,
|
||||
N_("ADDR"), N_("Read word from ADDR."), options);
|
||||
cmd_read_dword =
|
||||
grub_register_extcmd ("read_dword", grub_cmd_read, GRUB_COMMAND_FLAG_BOTH,
|
||||
grub_register_extcmd ("read_dword", grub_cmd_read, 0,
|
||||
N_("ADDR"), N_("Read dword from ADDR."), options);
|
||||
cmd_write_byte =
|
||||
grub_register_command ("write_byte", grub_cmd_write,
|
||||
|
|
320
grub-core/commands/menuentry.c
Normal file
320
grub-core/commands/menuentry.c
Normal file
|
@ -0,0 +1,320 @@
|
|||
/* menuentry.c - menuentry command */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 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/types.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/normal.h>
|
||||
|
||||
static const struct grub_arg_option options[] =
|
||||
{
|
||||
{"class", 1, GRUB_ARG_OPTION_REPEATABLE,
|
||||
N_("Menu entry type."), "STRING", ARG_TYPE_STRING},
|
||||
{"users", 2, 0,
|
||||
N_("Users allowed to boot this entry."), "USERNAME", ARG_TYPE_STRING},
|
||||
{"hotkey", 3, 0,
|
||||
N_("Keyboard key for this entry."), "KEY", ARG_TYPE_STRING},
|
||||
{"source", 4, 0,
|
||||
N_("Menu entry definition as a string."), "STRING", ARG_TYPE_STRING},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static struct
|
||||
{
|
||||
char *name;
|
||||
int key;
|
||||
} hotkey_aliases[] =
|
||||
{
|
||||
{"backspace", '\b'},
|
||||
{"tab", '\t'},
|
||||
{"delete", GRUB_TERM_KEY_DC},
|
||||
{"insert", GRUB_TERM_KEY_INSERT},
|
||||
{"f1", GRUB_TERM_KEY_F1},
|
||||
{"f2", GRUB_TERM_KEY_F2},
|
||||
{"f3", GRUB_TERM_KEY_F3},
|
||||
{"f4", GRUB_TERM_KEY_F4},
|
||||
{"f5", GRUB_TERM_KEY_F5},
|
||||
{"f6", GRUB_TERM_KEY_F6},
|
||||
{"f7", GRUB_TERM_KEY_F7},
|
||||
{"f8", GRUB_TERM_KEY_F8},
|
||||
{"f9", GRUB_TERM_KEY_F9},
|
||||
{"f10", GRUB_TERM_KEY_F10},
|
||||
{"f11", GRUB_TERM_KEY_F11},
|
||||
{"f12", GRUB_TERM_KEY_F12},
|
||||
};
|
||||
|
||||
/* Add a menu entry to the current menu context (as given by the environment
|
||||
variable data slot `menu'). As the configuration file is read, the script
|
||||
parser calls this when a menu entry is to be created. */
|
||||
grub_err_t
|
||||
grub_normal_add_menu_entry (int argc, const char **args, char **classes,
|
||||
const char *users, const char *hotkey,
|
||||
const char *prefix, const char *sourcecode,
|
||||
int submenu)
|
||||
{
|
||||
int menu_hotkey = 0;
|
||||
char **menu_args = NULL;
|
||||
char *menu_users = NULL;
|
||||
char *menu_title = NULL;
|
||||
char *menu_sourcecode = NULL;
|
||||
struct grub_menu_entry_class *menu_classes = NULL;
|
||||
|
||||
grub_menu_t menu;
|
||||
grub_menu_entry_t *last;
|
||||
|
||||
menu = grub_env_get_menu ();
|
||||
if (! menu)
|
||||
return grub_error (GRUB_ERR_MENU, "no menu context");
|
||||
|
||||
last = &menu->entry_list;
|
||||
|
||||
menu_sourcecode = grub_xasprintf ("%s%s", prefix ?: "", sourcecode);
|
||||
if (! menu_sourcecode)
|
||||
return grub_errno;
|
||||
|
||||
if (classes)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; classes[i]; i++); /* count # of menuentry classes */
|
||||
menu_classes = grub_zalloc (sizeof (struct grub_menu_entry_class) * i);
|
||||
if (! menu_classes)
|
||||
goto fail;
|
||||
|
||||
for (i = 0; classes[i]; i++)
|
||||
{
|
||||
menu_classes[i].name = grub_strdup (classes[i]);
|
||||
if (! menu_classes[i].name)
|
||||
goto fail;
|
||||
menu_classes[i].next = classes[i + 1] ? &menu_classes[i + 1] : NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (users)
|
||||
{
|
||||
menu_users = grub_strdup (users);
|
||||
if (! menu_users)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (hotkey)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < ARRAY_SIZE (hotkey_aliases); i++)
|
||||
if (grub_strcmp (hotkey, hotkey_aliases[i].name) == 0)
|
||||
{
|
||||
menu_hotkey = hotkey_aliases[i].key;
|
||||
break;
|
||||
}
|
||||
if (i == ARRAY_SIZE (hotkey_aliases))
|
||||
menu_hotkey = hotkey[0];
|
||||
}
|
||||
|
||||
if (! argc)
|
||||
{
|
||||
grub_error (GRUB_ERR_MENU, "menuentry is missing title");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
menu_title = grub_strdup (args[0]);
|
||||
if (! menu_title)
|
||||
goto fail;
|
||||
|
||||
/* Save argc, args to pass as parameters to block arg later. */
|
||||
menu_args = grub_malloc (sizeof (char*) * (argc + 1));
|
||||
if (! menu_args)
|
||||
goto fail;
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
menu_args[i] = grub_strdup (args[i]);
|
||||
if (! menu_args[i])
|
||||
goto fail;
|
||||
}
|
||||
menu_args[argc] = NULL;
|
||||
}
|
||||
|
||||
/* Add the menu entry at the end of the list. */
|
||||
while (*last)
|
||||
last = &(*last)->next;
|
||||
|
||||
*last = grub_zalloc (sizeof (**last));
|
||||
if (! *last)
|
||||
goto fail;
|
||||
|
||||
(*last)->title = menu_title;
|
||||
(*last)->hotkey = menu_hotkey;
|
||||
(*last)->classes = menu_classes;
|
||||
if (menu_users)
|
||||
(*last)->restricted = 1;
|
||||
(*last)->users = menu_users;
|
||||
(*last)->argc = argc;
|
||||
(*last)->args = menu_args;
|
||||
(*last)->sourcecode = menu_sourcecode;
|
||||
(*last)->submenu = submenu;
|
||||
|
||||
menu->size++;
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
fail:
|
||||
|
||||
grub_free (menu_sourcecode);
|
||||
{
|
||||
int i;
|
||||
for (i = 0; menu_classes && menu_classes[i].name; i++)
|
||||
grub_free (menu_classes[i].name);
|
||||
grub_free (menu_classes);
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; menu_args && menu_args[i]; i++)
|
||||
grub_free (menu_args[i]);
|
||||
grub_free (menu_args);
|
||||
}
|
||||
|
||||
grub_free (menu_users);
|
||||
grub_free (menu_title);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static char *
|
||||
setparams_prefix (int argc, char **args)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
char *p;
|
||||
char *result;
|
||||
grub_size_t len = 10;
|
||||
static const char *escape_characters = "\"\\";
|
||||
|
||||
auto char *strescpy (char *, const char *, const char *);
|
||||
char * strescpy (char *d, const char *s, const char *escapes)
|
||||
{
|
||||
while (*s)
|
||||
{
|
||||
if (grub_strchr (escapes, *s))
|
||||
*d++ = '\\';
|
||||
*d++ = *s++;
|
||||
}
|
||||
*d = '\0';
|
||||
return d;
|
||||
}
|
||||
|
||||
/* Count resulting string length */
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
len += 3; /* 3 = 1 space + 2 quotes */
|
||||
p = args[i];
|
||||
while (*p)
|
||||
len += grub_strchr (escape_characters, *p++) ? 2 : 1;
|
||||
}
|
||||
|
||||
result = grub_malloc (len + 2);
|
||||
if (! result)
|
||||
return 0;
|
||||
|
||||
grub_strcpy (result, "setparams");
|
||||
i = 9;
|
||||
|
||||
for (j = 0; j < argc; j++)
|
||||
{
|
||||
result[i++] = ' ';
|
||||
result[i++] = '"';
|
||||
i = strescpy (result + i, args[j], escape_characters) - result;
|
||||
result[i++] = '"';
|
||||
}
|
||||
result[i++] = '\n';
|
||||
result[i] = '\0';
|
||||
return result;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
char ch;
|
||||
char *src;
|
||||
char *prefix;
|
||||
unsigned len;
|
||||
grub_err_t r;
|
||||
|
||||
if (! argc)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing arguments");
|
||||
|
||||
if (ctxt->state[3].set && ctxt->script)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "multiple menuentry definitions");
|
||||
|
||||
if (! ctxt->state[3].set && ! ctxt->script)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menuentry definition");
|
||||
|
||||
if (! ctxt->script)
|
||||
return grub_normal_add_menu_entry (argc, (const char **) args,
|
||||
ctxt->state[0].args, ctxt->state[1].arg,
|
||||
ctxt->state[2].arg, 0,
|
||||
ctxt->state[3].arg,
|
||||
ctxt->extcmd->cmd->name[0] == 's');
|
||||
|
||||
src = args[argc - 1];
|
||||
args[argc - 1] = NULL;
|
||||
|
||||
len = grub_strlen(src);
|
||||
ch = src[len - 1];
|
||||
src[len - 1] = '\0';
|
||||
|
||||
prefix = setparams_prefix (argc - 1, args);
|
||||
if (! prefix)
|
||||
return grub_errno;
|
||||
|
||||
r = grub_normal_add_menu_entry (argc - 1, (const char **) args,
|
||||
ctxt->state[0].args, ctxt->state[1].arg,
|
||||
ctxt->state[2].arg, prefix, src + 1,
|
||||
ctxt->extcmd->cmd->name[0] == 's');
|
||||
|
||||
src[len - 1] = ch;
|
||||
args[argc - 1] = src;
|
||||
grub_free (prefix);
|
||||
return r;
|
||||
}
|
||||
|
||||
static grub_extcmd_t cmd, cmd_sub;
|
||||
|
||||
void
|
||||
grub_menu_init (void)
|
||||
{
|
||||
cmd = grub_register_extcmd ("menuentry", grub_cmd_menuentry,
|
||||
GRUB_COMMAND_FLAG_BLOCKS
|
||||
| GRUB_COMMAND_FLAG_EXTRACTOR,
|
||||
N_("BLOCK"), N_("Define a menuentry."), options);
|
||||
cmd_sub = grub_register_extcmd ("submenu", grub_cmd_menuentry,
|
||||
GRUB_COMMAND_FLAG_BLOCKS
|
||||
| GRUB_COMMAND_FLAG_EXTRACTOR,
|
||||
N_("BLOCK"), N_("Define a submenu."),
|
||||
options);
|
||||
}
|
||||
|
||||
void
|
||||
grub_menu_fini (void)
|
||||
{
|
||||
grub_unregister_extcmd (cmd);
|
||||
grub_unregister_extcmd (cmd_sub);
|
||||
}
|
|
@ -108,146 +108,6 @@ grub_rescue_cmd_info (void)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* root [DEVICE] */
|
||||
static grub_err_t
|
||||
grub_mini_cmd_root (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
grub_device_t dev;
|
||||
grub_fs_t fs;
|
||||
|
||||
if (argc > 0)
|
||||
{
|
||||
char *device_name = grub_file_get_device_name (argv[0]);
|
||||
if (! device_name)
|
||||
return grub_errno;
|
||||
|
||||
grub_env_set ("root", device_name);
|
||||
grub_free (device_name);
|
||||
}
|
||||
|
||||
dev = grub_device_open (0);
|
||||
if (! dev)
|
||||
return grub_errno;
|
||||
|
||||
fs = grub_fs_probe (dev);
|
||||
if (grub_errno == GRUB_ERR_UNKNOWN_FS)
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
grub_printf ("(%s): Filesystem is %s.\n",
|
||||
grub_env_get ("root"), fs ? fs->name : "unknown");
|
||||
|
||||
grub_device_close (dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
grub_rescue_cmd_testload (int argc, char *argv[])
|
||||
{
|
||||
grub_file_t file;
|
||||
char *buf;
|
||||
grub_ssize_t size;
|
||||
grub_ssize_t pos;
|
||||
auto void read_func (unsigned long sector, unsigned offset, unsigned len);
|
||||
|
||||
void read_func (unsigned long sector __attribute__ ((unused)),
|
||||
unsigned offset __attribute__ ((unused)),
|
||||
unsigned len __attribute__ ((unused)))
|
||||
{
|
||||
grub_putchar ('.');
|
||||
grub_refresh ();
|
||||
}
|
||||
|
||||
if (argc < 1)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
|
||||
return;
|
||||
}
|
||||
|
||||
file = grub_file_open (argv[0]);
|
||||
if (! file)
|
||||
return;
|
||||
|
||||
size = grub_file_size (file) & ~(GRUB_DISK_SECTOR_SIZE - 1);
|
||||
if (size == 0)
|
||||
{
|
||||
grub_file_close (file);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = grub_malloc (size);
|
||||
if (! buf)
|
||||
goto fail;
|
||||
|
||||
grub_printf ("Reading %s sequentially", argv[0]);
|
||||
file->read_hook = read_func;
|
||||
if (grub_file_read (file, buf, size) != size)
|
||||
goto fail;
|
||||
grub_printf (" Done.\n");
|
||||
|
||||
/* Read sequentially again. */
|
||||
grub_printf ("Reading %s sequentially again", argv[0]);
|
||||
if (grub_file_seek (file, 0) < 0)
|
||||
goto fail;
|
||||
|
||||
for (pos = 0; pos < size; pos += GRUB_DISK_SECTOR_SIZE)
|
||||
{
|
||||
char sector[GRUB_DISK_SECTOR_SIZE];
|
||||
|
||||
if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE)
|
||||
!= GRUB_DISK_SECTOR_SIZE)
|
||||
goto fail;
|
||||
|
||||
if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0)
|
||||
{
|
||||
grub_printf ("\nDiffers in %d\n", pos);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
grub_printf (" Done.\n");
|
||||
|
||||
/* Read backwards and compare. */
|
||||
grub_printf ("Reading %s backwards", argv[0]);
|
||||
pos = size;
|
||||
while (pos > 0)
|
||||
{
|
||||
char sector[GRUB_DISK_SECTOR_SIZE];
|
||||
|
||||
pos -= GRUB_DISK_SECTOR_SIZE;
|
||||
|
||||
if (grub_file_seek (file, pos) < 0)
|
||||
goto fail;
|
||||
|
||||
if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE)
|
||||
!= GRUB_DISK_SECTOR_SIZE)
|
||||
goto fail;
|
||||
|
||||
if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
grub_printf ("\nDiffers in %d\n", pos);
|
||||
|
||||
for (i = 0; i < GRUB_DISK_SECTOR_SIZE; i++)
|
||||
grub_putchar (buf[pos + i]);
|
||||
|
||||
if (i)
|
||||
grub_refresh ();
|
||||
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
grub_printf (" Done.\n");
|
||||
|
||||
fail:
|
||||
|
||||
grub_file_close (file);
|
||||
grub_free (buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* dump ADDRESS [SIZE] */
|
||||
static grub_err_t
|
||||
grub_mini_cmd_dump (struct grub_command *cmd __attribute__ ((unused)),
|
||||
|
@ -332,7 +192,7 @@ grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)),
|
|||
return 0;
|
||||
}
|
||||
|
||||
static grub_command_t cmd_cat, cmd_help, cmd_root;
|
||||
static grub_command_t cmd_cat, cmd_help;
|
||||
static grub_command_t cmd_dump, cmd_rmmod, cmd_lsmod, cmd_exit;
|
||||
|
||||
GRUB_MOD_INIT(minicmd)
|
||||
|
@ -343,9 +203,6 @@ GRUB_MOD_INIT(minicmd)
|
|||
cmd_help =
|
||||
grub_register_command ("help", grub_mini_cmd_help,
|
||||
0, N_("Show this message."));
|
||||
cmd_root =
|
||||
grub_register_command ("root", grub_mini_cmd_root,
|
||||
N_("[DEVICE]"), N_("Set the root device."));
|
||||
cmd_dump =
|
||||
grub_register_command ("dump", grub_mini_cmd_dump,
|
||||
N_("ADDR"), N_("Dump memory."));
|
||||
|
@ -364,7 +221,6 @@ GRUB_MOD_FINI(minicmd)
|
|||
{
|
||||
grub_unregister_command (cmd_cat);
|
||||
grub_unregister_command (cmd_help);
|
||||
grub_unregister_command (cmd_root);
|
||||
grub_unregister_command (cmd_dump);
|
||||
grub_unregister_command (cmd_rmmod);
|
||||
grub_unregister_command (cmd_lsmod);
|
||||
|
|
|
@ -275,7 +275,7 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
|
|||
if (! parsed[j])
|
||||
{
|
||||
for (curarg = ptool->args; curarg->name; curarg++)
|
||||
if (grub_strncmp (curarg->name, args[i],
|
||||
if (grub_strncmp (curarg->name, args[j],
|
||||
grub_strlen (curarg->name)) == 0
|
||||
&& ((curarg->type == GRUB_PARTTOOL_ARG_BOOL
|
||||
&& (args[j][grub_strlen (curarg->name)] == '+'
|
||||
|
|
|
@ -40,26 +40,22 @@ check_password (const char *user, const char *entered,
|
|||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
grub_err_t
|
||||
grub_normal_set_password (const char *user, const char *password)
|
||||
{
|
||||
grub_err_t err;
|
||||
char *pass;
|
||||
int copylen;
|
||||
|
||||
if (argc != 2)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments expected");
|
||||
|
||||
pass = grub_zalloc (GRUB_AUTH_MAX_PASSLEN);
|
||||
if (!pass)
|
||||
return grub_errno;
|
||||
copylen = grub_strlen (args[1]);
|
||||
copylen = grub_strlen (password);
|
||||
if (copylen >= GRUB_AUTH_MAX_PASSLEN)
|
||||
copylen = GRUB_AUTH_MAX_PASSLEN - 1;
|
||||
grub_memcpy (pass, args[1], copylen);
|
||||
grub_memcpy (pass, password, copylen);
|
||||
|
||||
err = grub_auth_register_authentication (args[0], check_password, pass);
|
||||
err = grub_auth_register_authentication (user, check_password, pass);
|
||||
if (err)
|
||||
{
|
||||
grub_free (pass);
|
||||
|
@ -69,6 +65,15 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
|
|||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_password (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
if (argc != 2)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments expected");
|
||||
return grub_normal_set_password (args[0], args[1]);
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(password)
|
||||
|
|
|
@ -45,9 +45,9 @@ static const struct grub_arg_option options[] =
|
|||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_probe (grub_extcmd_t cmd, int argc, char **args)
|
||||
grub_cmd_probe (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
grub_device_t dev;
|
||||
grub_fs_t fs;
|
||||
char *ptr;
|
||||
|
@ -150,8 +150,7 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT (probe)
|
||||
{
|
||||
cmd = grub_register_extcmd ("probe", grub_cmd_probe, GRUB_COMMAND_FLAG_BOTH,
|
||||
N_("[DEVICE]"),
|
||||
cmd = grub_register_extcmd ("probe", grub_cmd_probe, 0, N_("[DEVICE]"),
|
||||
N_("Retrieve device info."), options);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,37 +20,104 @@
|
|||
#include <grub/dl.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/script_sh.h>
|
||||
#include <regex.h>
|
||||
|
||||
static const struct grub_arg_option options[] =
|
||||
{
|
||||
{ "set", 's', GRUB_ARG_OPTION_REPEATABLE,
|
||||
N_("Variable names to update with matches."),
|
||||
N_("[NUMBER:]VARNAME"), ARG_TYPE_STRING },
|
||||
{ 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_regexp (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
set_matches (char **varnames, char *str, grub_size_t nmatches,
|
||||
regmatch_t *matches)
|
||||
{
|
||||
int i;
|
||||
char ch;
|
||||
char *p;
|
||||
char *q;
|
||||
grub_err_t err;
|
||||
unsigned long j;
|
||||
|
||||
auto void setvar (char *v, regmatch_t *m);
|
||||
void setvar (char *v, regmatch_t *m)
|
||||
{
|
||||
ch = str[m->rm_eo];
|
||||
str[m->rm_eo] = '\0';
|
||||
err = grub_env_set (v, str + m->rm_so);
|
||||
str[m->rm_eo] = ch;
|
||||
}
|
||||
|
||||
for (i = 0; varnames && varnames[i]; i++)
|
||||
{
|
||||
if (! (p = grub_strchr (varnames[i], ':')))
|
||||
{
|
||||
/* varname w/o index defaults to 1 */
|
||||
if (nmatches < 2 || matches[1].rm_so == -1)
|
||||
grub_env_unset (varnames[i]);
|
||||
else
|
||||
setvar (varnames[i], &matches[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
j = grub_strtoul (varnames[i], &q, 10);
|
||||
if (q != p)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
"invalid variable name format %s", varnames[i]);
|
||||
|
||||
if (nmatches <= j || matches[j].rm_so == -1)
|
||||
grub_env_unset (p + 1);
|
||||
else
|
||||
setvar (p + 1, &matches[j]);
|
||||
}
|
||||
|
||||
if (err != GRUB_ERR_NONE)
|
||||
return err;
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_regexp (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
int argn = 0;
|
||||
int matches = 0;
|
||||
regex_t regex;
|
||||
int ret;
|
||||
grub_size_t s;
|
||||
char *comperr;
|
||||
grub_err_t err;
|
||||
regmatch_t *matches = 0;
|
||||
|
||||
if (argc != 2)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "2 arguments expected");
|
||||
|
||||
ret = regcomp (®ex, args[0], RE_SYNTAX_GNU_AWK);
|
||||
ret = regcomp (®ex, args[0], REG_EXTENDED);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
ret = regexec (®ex, args[1], 0, 0, 0);
|
||||
matches = grub_zalloc (sizeof (*matches) * (regex.re_nsub + 1));
|
||||
if (! matches)
|
||||
goto fail;
|
||||
|
||||
ret = regexec (®ex, args[1], regex.re_nsub + 1, matches, 0);
|
||||
if (!ret)
|
||||
{
|
||||
err = set_matches (ctxt->state[0].args, args[1],
|
||||
regex.re_nsub + 1, matches);
|
||||
regfree (®ex);
|
||||
return GRUB_ERR_NONE;
|
||||
grub_free (matches);
|
||||
return err;
|
||||
}
|
||||
|
||||
fail:
|
||||
grub_free (matches);
|
||||
s = regerror (ret, ®ex, 0, 0);
|
||||
comperr = grub_malloc (s);
|
||||
if (!comperr)
|
||||
|
@ -65,16 +132,19 @@ grub_cmd_regexp (grub_command_t cmd __attribute__ ((unused)),
|
|||
return err;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
static grub_extcmd_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(regexp)
|
||||
{
|
||||
cmd = grub_register_command ("regexp", grub_cmd_regexp,
|
||||
N_("REGEXP STRING"),
|
||||
N_("Test if REGEXP matches STRING."));
|
||||
cmd = grub_register_extcmd ("regexp", grub_cmd_regexp, 0, N_("REGEXP STRING"),
|
||||
N_("Test if REGEXP matches STRING."), options);
|
||||
|
||||
/* Setup GRUB script wildcard translator. */
|
||||
grub_wildcard_translator = &grub_filename_translator;
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(regexp)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
grub_unregister_extcmd (cmd);
|
||||
grub_wildcard_translator = 0;
|
||||
}
|
||||
|
|
|
@ -28,9 +28,12 @@
|
|||
#include <grub/command.h>
|
||||
#include <grub/search.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
|
||||
void
|
||||
FUNC_NAME (const char *key, const char *var, int no_floppy)
|
||||
FUNC_NAME (const char *key, const char *var, int no_floppy,
|
||||
char **hints, unsigned nhints)
|
||||
{
|
||||
int count = 0;
|
||||
grub_fs_autoload_hook_t saved_autoload;
|
||||
|
@ -54,6 +57,7 @@ FUNC_NAME (const char *key, const char *var, int no_floppy)
|
|||
if (! buf)
|
||||
return 1;
|
||||
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (buf);
|
||||
if (file)
|
||||
{
|
||||
|
@ -113,22 +117,86 @@ FUNC_NAME (const char *key, const char *var, int no_floppy)
|
|||
return (found && var);
|
||||
}
|
||||
|
||||
auto int part_hook (grub_disk_t disk, const grub_partition_t partition);
|
||||
int part_hook (grub_disk_t disk, const grub_partition_t partition)
|
||||
{
|
||||
char *partition_name, *devname;
|
||||
int ret;
|
||||
|
||||
partition_name = grub_partition_get_name (partition);
|
||||
if (! partition_name)
|
||||
return 1;
|
||||
|
||||
devname = grub_xasprintf ("%s,%s", disk->name, partition_name);
|
||||
grub_free (partition_name);
|
||||
if (!devname)
|
||||
return 1;
|
||||
ret = iterate_device (devname);
|
||||
grub_free (devname);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
auto void try (void);
|
||||
void try (void)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < nhints; i++)
|
||||
{
|
||||
char *end;
|
||||
if (!hints[i][0])
|
||||
continue;
|
||||
end = hints[i] + grub_strlen (hints[i]) - 1;
|
||||
if (*end == ',')
|
||||
*end = 0;
|
||||
if (iterate_device (hints[i]))
|
||||
{
|
||||
if (!*end)
|
||||
*end = ',';
|
||||
return;
|
||||
}
|
||||
if (!*end)
|
||||
{
|
||||
grub_device_t dev;
|
||||
int ret;
|
||||
dev = grub_device_open (hints[i]);
|
||||
if (!dev)
|
||||
{
|
||||
*end = ',';
|
||||
continue;
|
||||
}
|
||||
if (!dev->disk)
|
||||
{
|
||||
grub_device_close (dev);
|
||||
*end = ',';
|
||||
continue;
|
||||
}
|
||||
ret = grub_partition_iterate (dev->disk, part_hook);
|
||||
*end = ',';
|
||||
grub_device_close (dev);
|
||||
if (ret)
|
||||
return;
|
||||
}
|
||||
}
|
||||
grub_device_iterate (iterate_device);
|
||||
}
|
||||
|
||||
/* First try without autoloading if we're setting variable. */
|
||||
if (var)
|
||||
{
|
||||
saved_autoload = grub_fs_autoload_hook;
|
||||
grub_fs_autoload_hook = 0;
|
||||
grub_device_iterate (iterate_device);
|
||||
try ();
|
||||
|
||||
/* Restore autoload hook. */
|
||||
grub_fs_autoload_hook = saved_autoload;
|
||||
|
||||
/* Retry with autoload if nothing found. */
|
||||
if (grub_errno == GRUB_ERR_NONE && count == 0)
|
||||
grub_device_iterate (iterate_device);
|
||||
try ();
|
||||
}
|
||||
else
|
||||
grub_device_iterate (iterate_device);
|
||||
try ();
|
||||
|
||||
if (grub_errno == GRUB_ERR_NONE && count == 0)
|
||||
grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key);
|
||||
|
@ -141,7 +209,8 @@ grub_cmd_do_search (grub_command_t cmd __attribute__ ((unused)), int argc,
|
|||
if (argc == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no argument specified");
|
||||
|
||||
FUNC_NAME (args[0], argc == 1 ? 0 : args[1], 0);
|
||||
FUNC_NAME (args[0], argc == 1 ? 0 : args[1], 0, (args + 2),
|
||||
argc > 2 ? argc - 2 : 0);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
@ -158,7 +227,7 @@ GRUB_MOD_INIT(search_label)
|
|||
{
|
||||
cmd =
|
||||
grub_register_command (COMMAND_NAME, grub_cmd_do_search,
|
||||
N_("NAME [VARIABLE]"),
|
||||
N_("NAME [VARIABLE] [HINTS]"),
|
||||
HELP_MESSAGE);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,9 @@ static const struct grub_arg_option options[] =
|
|||
{"set", 's', GRUB_ARG_OPTION_OPTIONAL,
|
||||
N_("Set a variable to the first device found."), "VAR", ARG_TYPE_STRING},
|
||||
{"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0},
|
||||
{"hint", 'h', GRUB_ARG_OPTION_REPEATABLE,
|
||||
N_("First try the device HINT. If HINT ends in comma, "
|
||||
"also try subpartitions"), N_("HINT"), ARG_TYPE_STRING},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -47,13 +50,19 @@ enum options
|
|||
SEARCH_FS_UUID,
|
||||
SEARCH_SET,
|
||||
SEARCH_NO_FLOPPY,
|
||||
SEARCH_HINT
|
||||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_search (grub_extcmd_t cmd, int argc, char **args)
|
||||
grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
const char *var = 0;
|
||||
int nhints = 0;
|
||||
|
||||
if (state[SEARCH_HINT].set)
|
||||
while (state[SEARCH_HINT].args[nhints])
|
||||
nhints++;
|
||||
|
||||
if (argc == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no argument specified");
|
||||
|
@ -62,11 +71,14 @@ grub_cmd_search (grub_extcmd_t cmd, int argc, char **args)
|
|||
var = state[SEARCH_SET].arg ? state[SEARCH_SET].arg : "root";
|
||||
|
||||
if (state[SEARCH_LABEL].set)
|
||||
grub_search_label (args[0], var, state[SEARCH_NO_FLOPPY].set);
|
||||
grub_search_label (args[0], var, state[SEARCH_NO_FLOPPY].set,
|
||||
state[SEARCH_HINT].args, nhints);
|
||||
else if (state[SEARCH_FS_UUID].set)
|
||||
grub_search_fs_uuid (args[0], var, state[SEARCH_NO_FLOPPY].set);
|
||||
grub_search_fs_uuid (args[0], var, state[SEARCH_NO_FLOPPY].set,
|
||||
state[SEARCH_HINT].args, nhints);
|
||||
else if (state[SEARCH_FILE].set)
|
||||
grub_search_fs_file (args[0], var, state[SEARCH_NO_FLOPPY].set);
|
||||
grub_search_fs_file (args[0], var, state[SEARCH_NO_FLOPPY].set,
|
||||
state[SEARCH_HINT].args, nhints);
|
||||
else
|
||||
return grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type");
|
||||
|
||||
|
@ -78,9 +90,9 @@ static grub_extcmd_t cmd;
|
|||
GRUB_MOD_INIT(search)
|
||||
{
|
||||
cmd =
|
||||
grub_register_extcmd ("search", grub_cmd_search,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
N_("search [-f|-l|-u|-s|-n] NAME"),
|
||||
grub_register_extcmd ("search", grub_cmd_search, GRUB_COMMAND_FLAG_EXTRACTOR,
|
||||
N_("[-f|-l|-u|-s|-n] [--hint HINT [--hint HINT] ...]"
|
||||
" NAME"),
|
||||
N_("Search devices by file, filesystem label"
|
||||
" or filesystem UUID."
|
||||
" If --set is specified, the first device found is"
|
||||
|
|
|
@ -155,7 +155,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
|
|||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv)
|
||||
grub_cmd_setpci (grub_extcmd_context_t ctxt, int argc, char **argv)
|
||||
{
|
||||
const char *ptr;
|
||||
unsigned i;
|
||||
|
@ -163,14 +163,14 @@ grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv)
|
|||
pciid_check_value = 0;
|
||||
pciid_check_mask = 0;
|
||||
|
||||
if (cmd->state[0].set)
|
||||
if (ctxt->state[0].set)
|
||||
{
|
||||
ptr = cmd->state[0].arg;
|
||||
ptr = ctxt->state[0].arg;
|
||||
pciid_check_value |= (grub_strtoul (ptr, (char **) &ptr, 16) & 0xffff);
|
||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
ptr = cmd->state[0].arg;
|
||||
ptr = ctxt->state[0].arg;
|
||||
}
|
||||
else
|
||||
pciid_check_mask |= 0xffff;
|
||||
|
@ -191,11 +191,11 @@ grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv)
|
|||
|
||||
check_bus = check_device = check_function = 0;
|
||||
|
||||
if (cmd->state[1].set)
|
||||
if (ctxt->state[1].set)
|
||||
{
|
||||
const char *optr;
|
||||
|
||||
ptr = cmd->state[1].arg;
|
||||
ptr = ctxt->state[1].arg;
|
||||
optr = ptr;
|
||||
bus = grub_strtoul (ptr, (char **) &ptr, 16);
|
||||
if (grub_errno == GRUB_ERR_BAD_NUMBER)
|
||||
|
@ -229,8 +229,8 @@ grub_cmd_setpci (grub_extcmd_t cmd, int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (cmd->state[2].set)
|
||||
varname = cmd->state[2].arg;
|
||||
if (ctxt->state[2].set)
|
||||
varname = ctxt->state[2].arg;
|
||||
else
|
||||
varname = NULL;
|
||||
|
||||
|
@ -329,7 +329,7 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(setpci)
|
||||
{
|
||||
cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd = grub_register_extcmd ("setpci", grub_cmd_setpci, 0,
|
||||
N_("[-s POSITION] [-d DEVICE] [-v VAR] "
|
||||
"[REGISTER][=VALUE[:MASK]]"),
|
||||
N_("Manipulate PCI devices."), options);
|
||||
|
|
|
@ -52,17 +52,16 @@ grub_interruptible_millisleep (grub_uint32_t ms)
|
|||
start = grub_get_time_ms ();
|
||||
|
||||
while (grub_get_time_ms () - start < ms)
|
||||
if (grub_checkkey () >= 0 &&
|
||||
GRUB_TERM_ASCII_CHAR (grub_getkey ()) == GRUB_TERM_ESC)
|
||||
if (grub_checkkey () >= 0 && grub_getkey () == GRUB_TERM_ESC)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_sleep (grub_extcmd_t cmd, int argc, char **args)
|
||||
grub_cmd_sleep (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
int n;
|
||||
|
||||
if (argc != 1)
|
||||
|
@ -101,7 +100,7 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(sleep)
|
||||
{
|
||||
cmd = grub_register_extcmd ("sleep", grub_cmd_sleep, GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd = grub_register_extcmd ("sleep", grub_cmd_sleep, 0,
|
||||
N_("NUMBER_OF_SECONDS"),
|
||||
N_("Wait for a specified number of seconds."),
|
||||
options);
|
||||
|
|
|
@ -334,6 +334,7 @@ test_parse (char **args, int *argn, int argc)
|
|||
if (grub_strcmp (args[*argn], "-s") == 0)
|
||||
{
|
||||
grub_file_t file;
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (args[*argn + 1]);
|
||||
update_val (file && (grub_file_size (file) != 0));
|
||||
if (file)
|
||||
|
@ -422,8 +423,10 @@ GRUB_MOD_INIT(test)
|
|||
{
|
||||
cmd_1 = grub_register_command ("[", grub_cmd_test,
|
||||
N_("EXPRESSION ]"), N_("Evaluate an expression."));
|
||||
cmd_1->flags |= GRUB_COMMAND_FLAG_EXTRACTOR;
|
||||
cmd_2 = grub_register_command ("test", grub_cmd_test,
|
||||
N_("EXPRESSION"), N_("Evaluate an expression."));
|
||||
cmd_2->flags |= GRUB_COMMAND_FLAG_EXTRACTOR;
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(test)
|
||||
|
|
155
grub-core/commands/testload.c
Normal file
155
grub-core/commands/testload.c
Normal file
|
@ -0,0 +1,155 @@
|
|||
/* testload.c - load the same file in multiple ways */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2003,2005,2006,2007,2009,2010 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/dl.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/loader.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_testload (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
grub_file_t file;
|
||||
char *buf;
|
||||
grub_size_t size;
|
||||
grub_off_t pos;
|
||||
auto void NESTED_FUNC_ATTR read_func (grub_disk_addr_t sector, unsigned offset, unsigned len);
|
||||
|
||||
void NESTED_FUNC_ATTR read_func (grub_disk_addr_t sector __attribute__ ((unused)),
|
||||
unsigned offset __attribute__ ((unused)),
|
||||
unsigned len __attribute__ ((unused)))
|
||||
{
|
||||
grub_xputs (".");
|
||||
grub_refresh ();
|
||||
}
|
||||
|
||||
if (argc < 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
|
||||
|
||||
file = grub_file_open (argv[0]);
|
||||
if (! file)
|
||||
return grub_errno;
|
||||
|
||||
size = grub_file_size (file) & ~(GRUB_DISK_SECTOR_SIZE - 1);
|
||||
if (size == 0)
|
||||
{
|
||||
grub_file_close (file);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
buf = grub_malloc (size);
|
||||
if (! buf)
|
||||
goto fail;
|
||||
|
||||
grub_printf ("Reading %s sequentially", argv[0]);
|
||||
file->read_hook = read_func;
|
||||
if (grub_file_read (file, buf, size) != (grub_ssize_t) size)
|
||||
goto fail;
|
||||
grub_printf (" Done.\n");
|
||||
|
||||
/* Read sequentially again. */
|
||||
grub_printf ("Reading %s sequentially again", argv[0]);
|
||||
grub_file_seek (file, 0);
|
||||
|
||||
for (pos = 0; pos < size; pos += GRUB_DISK_SECTOR_SIZE)
|
||||
{
|
||||
char sector[GRUB_DISK_SECTOR_SIZE];
|
||||
|
||||
if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE)
|
||||
!= GRUB_DISK_SECTOR_SIZE)
|
||||
goto fail;
|
||||
|
||||
if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0)
|
||||
{
|
||||
grub_printf ("\nDiffers in %lld\n", (unsigned long long) pos);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
grub_printf (" Done.\n");
|
||||
|
||||
/* Read backwards and compare. */
|
||||
grub_printf ("Reading %s backwards", argv[0]);
|
||||
pos = size;
|
||||
while (pos > 0)
|
||||
{
|
||||
char sector[GRUB_DISK_SECTOR_SIZE];
|
||||
|
||||
pos -= GRUB_DISK_SECTOR_SIZE;
|
||||
|
||||
grub_file_seek (file, pos);
|
||||
|
||||
if (grub_file_read (file, sector, GRUB_DISK_SECTOR_SIZE)
|
||||
!= GRUB_DISK_SECTOR_SIZE)
|
||||
goto fail;
|
||||
|
||||
if (grub_memcmp (sector, buf + pos, GRUB_DISK_SECTOR_SIZE) != 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
grub_printf ("\nDiffers in %lld\n", (unsigned long long) pos);
|
||||
|
||||
for (i = 0; i < GRUB_DISK_SECTOR_SIZE; i++)
|
||||
{
|
||||
grub_printf ("%02x ", buf[pos + i]);
|
||||
if ((i & 15) == 15)
|
||||
grub_printf ("\n");
|
||||
}
|
||||
|
||||
if (i)
|
||||
grub_refresh ();
|
||||
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
grub_printf (" Done.\n");
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
fail:
|
||||
|
||||
grub_file_close (file);
|
||||
grub_free (buf);
|
||||
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_IO, "bad read");
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(testload)
|
||||
{
|
||||
cmd =
|
||||
grub_register_command ("testload", grub_cmd_testload,
|
||||
N_("FILE"),
|
||||
N_("Load the same file in multiple ways."));
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(testload)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
184
grub-core/commands/videoinfo.c
Normal file
184
grub-core/commands/videoinfo.c
Normal file
|
@ -0,0 +1,184 @@
|
|||
/* videoinfo.c - command to list video modes. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2005,2007,2008,2009,2010 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/video.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
static unsigned height, width, depth;
|
||||
|
||||
static int
|
||||
hook (const struct grub_video_mode_info *info)
|
||||
{
|
||||
if (height && width && (info->width != width || info->height != height))
|
||||
return 0;
|
||||
|
||||
if (depth && info->bpp != depth)
|
||||
return 0;
|
||||
|
||||
if (info->mode_number == GRUB_VIDEO_MODE_NUMBER_INVALID)
|
||||
grub_printf (" ");
|
||||
else
|
||||
grub_printf (" 0x%03x ", info->mode_number);
|
||||
grub_printf ("%4d x %4d x %2d ", info->width, info->height, info->bpp);
|
||||
|
||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT)
|
||||
grub_printf ("Text-only ");
|
||||
/* Show mask and position details for direct color modes. */
|
||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_RGB)
|
||||
grub_printf ("Direct, mask: %d/%d/%d/%d pos: %d/%d/%d/%d",
|
||||
info->red_mask_size,
|
||||
info->green_mask_size,
|
||||
info->blue_mask_size,
|
||||
info->reserved_mask_size,
|
||||
info->red_field_pos,
|
||||
info->green_field_pos,
|
||||
info->blue_field_pos,
|
||||
info->reserved_field_pos);
|
||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
|
||||
grub_printf ("Packed ");
|
||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_YUV)
|
||||
grub_printf ("YUV ");
|
||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PLANAR)
|
||||
grub_printf ("Planar ");
|
||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_HERCULES)
|
||||
grub_printf ("Hercules ");
|
||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_CGA)
|
||||
grub_printf ("CGA ");
|
||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_NONCHAIN4)
|
||||
grub_printf ("Non-chain 4 ");
|
||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP)
|
||||
grub_printf ("Monochrome ");
|
||||
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_UNKNOWN)
|
||||
grub_printf ("Unknown ");
|
||||
|
||||
grub_printf ("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_videoinfo (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
grub_video_adapter_t adapter;
|
||||
grub_video_driver_id_t id;
|
||||
|
||||
height = width = depth = 0;
|
||||
if (argc)
|
||||
{
|
||||
char *ptr;
|
||||
ptr = args[0];
|
||||
width = grub_strtoul (ptr, &ptr, 0);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
if (*ptr != 'x')
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid mode specification");
|
||||
ptr++;
|
||||
height = grub_strtoul (ptr, &ptr, 0);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
if (*ptr == 'x')
|
||||
{
|
||||
ptr++;
|
||||
depth = grub_strtoul (ptr, &ptr, 0);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
if (grub_strcmp (cmd->name, "vbeinfo") == 0)
|
||||
grub_dl_load ("vbe");
|
||||
#endif
|
||||
|
||||
id = grub_video_get_driver_id ();
|
||||
|
||||
grub_printf ("List of supported video modes:\n");
|
||||
grub_printf ("Legend: P=Packed pixel, D=Direct color, "
|
||||
"mask/pos=R/G/B/reserved\n");
|
||||
|
||||
FOR_VIDEO_ADAPTERS (adapter)
|
||||
{
|
||||
grub_printf ("Adapter '%s':\n", adapter->name);
|
||||
|
||||
if (!adapter->iterate)
|
||||
{
|
||||
grub_printf (" No info available\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (adapter->id != id)
|
||||
{
|
||||
if (adapter->init ())
|
||||
{
|
||||
grub_printf (" Failed\n");
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (adapter->print_adapter_specific_info)
|
||||
adapter->print_adapter_specific_info ();
|
||||
|
||||
adapter->iterate (hook);
|
||||
|
||||
if (adapter->id != id)
|
||||
{
|
||||
if (adapter->fini ())
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
static grub_command_t cmd_vbe;
|
||||
#endif
|
||||
|
||||
GRUB_MOD_INIT(videoinfo)
|
||||
{
|
||||
cmd = grub_register_command ("videoinfo", grub_cmd_videoinfo, "[WxH[xD]]",
|
||||
N_("List available video modes. If "
|
||||
"resolution is given show only modes"
|
||||
" matching it."));
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
cmd_vbe = grub_register_command ("vbeinfo", grub_cmd_videoinfo, "[WxH[xD]]",
|
||||
N_("List available video modes. If "
|
||||
"resolution is given show only modes"
|
||||
" matching it."));
|
||||
#endif
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(videoinfo)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
grub_unregister_command (cmd_vbe);
|
||||
#endif
|
||||
}
|
||||
|
|
@ -26,11 +26,11 @@
|
|||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/gfxmenu_view.h>
|
||||
#include <grub/env.h>
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
int argc, char **args)
|
||||
{
|
||||
grub_err_t err;
|
||||
grub_video_color_t color;
|
||||
|
@ -41,8 +41,20 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
|
|||
int i;
|
||||
struct grub_video_render_target *text_layer;
|
||||
grub_video_color_t palette[16];
|
||||
const char *mode = NULL;
|
||||
|
||||
err = grub_video_set_mode ("auto", GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
if (grub_strcmp (cmd->name, "vbetest") == 0)
|
||||
grub_dl_load ("vbe");
|
||||
#endif
|
||||
|
||||
mode = grub_env_get ("gfxmode");
|
||||
if (argc)
|
||||
mode = args[0];
|
||||
if (!mode)
|
||||
mode = "auto";
|
||||
|
||||
err = grub_video_set_mode (mode, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -180,14 +192,25 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
|
|||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
static grub_command_t cmd_vbe;
|
||||
#endif
|
||||
|
||||
GRUB_MOD_INIT(videotest)
|
||||
{
|
||||
cmd = grub_register_command ("videotest", grub_cmd_videotest,
|
||||
"[WxH]",
|
||||
N_("Test video subsystem in mode WxH."));
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
cmd_vbe = grub_register_command ("vbetest", grub_cmd_videotest,
|
||||
0, N_("Test video subsystem."));
|
||||
#endif
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(videotest)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
#ifdef GRUB_MACHINE_PCBIOS
|
||||
grub_unregister_command (cmd_vbe);
|
||||
#endif
|
||||
}
|
||||
|
|
498
grub-core/commands/wildcard.c
Normal file
498
grub-core/commands/wildcard.c
Normal file
|
@ -0,0 +1,498 @@
|
|||
/* wildcard.c - Wildcard character expansion for GRUB script. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 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/mm.h>
|
||||
#include <grub/fs.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/device.h>
|
||||
#include <grub/script_sh.h>
|
||||
|
||||
#include <regex.h>
|
||||
|
||||
static inline int isregexop (char ch);
|
||||
static char ** merge (char **lhs, char **rhs);
|
||||
static char *make_dir (const char *prefix, const char *start, const char *end);
|
||||
static int make_regex (const char *regex_start, const char *regex_end,
|
||||
regex_t *regexp);
|
||||
static void split_path (const char *path, const char **suffix_end, const char **regex_end);
|
||||
static char ** match_devices (const regex_t *regexp, int noparts);
|
||||
static char ** match_files (const char *prefix, const char *suffix_start,
|
||||
const char *suffix_end, const regex_t *regexp);
|
||||
|
||||
static char* wildcard_escape (const char *s);
|
||||
static char* wildcard_unescape (const char *s);
|
||||
static grub_err_t wildcard_expand (const char *s, char ***strs);
|
||||
|
||||
struct grub_script_wildcard_translator grub_filename_translator = {
|
||||
.expand = wildcard_expand,
|
||||
.escape = wildcard_escape,
|
||||
.unescape = wildcard_unescape
|
||||
};
|
||||
|
||||
static char **
|
||||
merge (char **dest, char **ps)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
char **p;
|
||||
|
||||
if (! dest)
|
||||
return ps;
|
||||
|
||||
if (! ps)
|
||||
return dest;
|
||||
|
||||
for (i = 0; dest[i]; i++)
|
||||
;
|
||||
for (j = 0; ps[j]; j++)
|
||||
;
|
||||
|
||||
p = grub_realloc (dest, sizeof (char*) * (i + j + 1));
|
||||
if (! p)
|
||||
{
|
||||
grub_free (dest);
|
||||
grub_free (ps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dest = p;
|
||||
for (j = 0; ps[j]; j++)
|
||||
dest[i++] = ps[j];
|
||||
dest[i] = 0;
|
||||
|
||||
grub_free (ps);
|
||||
return dest;
|
||||
}
|
||||
|
||||
static inline int
|
||||
isregexop (char ch)
|
||||
{
|
||||
return grub_strchr ("*.\\", ch) ? 1 : 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
make_dir (const char *prefix, const char *start, const char *end)
|
||||
{
|
||||
char ch;
|
||||
unsigned i;
|
||||
unsigned n;
|
||||
char *result;
|
||||
|
||||
i = grub_strlen (prefix);
|
||||
n = i + end - start;
|
||||
|
||||
result = grub_malloc (n + 1);
|
||||
if (! result)
|
||||
return 0;
|
||||
|
||||
grub_strcpy (result, prefix);
|
||||
while (start < end && (ch = *start++))
|
||||
if (ch == '\\' && isregexop (*start))
|
||||
result[i++] = *start++;
|
||||
else
|
||||
result[i++] = ch;
|
||||
|
||||
result[i] = '\0';
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
make_regex (const char *start, const char *end, regex_t *regexp)
|
||||
{
|
||||
char ch;
|
||||
int i = 0;
|
||||
unsigned len = end - start;
|
||||
char *buffer = grub_malloc (len * 2 + 2 + 1); /* worst case size. */
|
||||
|
||||
if (! buffer)
|
||||
return 1;
|
||||
|
||||
buffer[i++] = '^';
|
||||
while (start < end)
|
||||
{
|
||||
/* XXX Only * expansion for now. */
|
||||
switch ((ch = *start++))
|
||||
{
|
||||
case '\\':
|
||||
buffer[i++] = ch;
|
||||
if (*start != '\0')
|
||||
buffer[i++] = *start++;
|
||||
break;
|
||||
|
||||
case '.':
|
||||
case '(':
|
||||
case ')':
|
||||
buffer[i++] = '\\';
|
||||
buffer[i++] = ch;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
buffer[i++] = '.';
|
||||
buffer[i++] = '*';
|
||||
break;
|
||||
|
||||
default:
|
||||
buffer[i++] = ch;
|
||||
}
|
||||
}
|
||||
buffer[i++] = '$';
|
||||
buffer[i] = '\0';
|
||||
grub_dprintf ("expand", "Regexp is %s\n", buffer);
|
||||
|
||||
if (regcomp (regexp, buffer, RE_SYNTAX_GNU_AWK))
|
||||
{
|
||||
grub_free (buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
grub_free (buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Split `str' into two parts: (1) dirname that is regexop free (2)
|
||||
dirname that has a regexop. */
|
||||
static void
|
||||
split_path (const char *str, const char **noregexop, const char **regexop)
|
||||
{
|
||||
char ch = 0;
|
||||
int regex = 0;
|
||||
|
||||
const char *end;
|
||||
const char *split; /* points till the end of dirnaname that doesn't
|
||||
need expansion. */
|
||||
|
||||
split = end = str;
|
||||
while ((ch = *end))
|
||||
{
|
||||
if (ch == '\\' && end[1])
|
||||
end++;
|
||||
|
||||
else if (isregexop (ch))
|
||||
regex = 1;
|
||||
|
||||
else if (ch == '/' && ! regex)
|
||||
split = end + 1; /* forward to next regexop-free dirname */
|
||||
|
||||
else if (ch == '/' && regex)
|
||||
break; /* stop at the first dirname with a regexop */
|
||||
|
||||
end++;
|
||||
}
|
||||
|
||||
*regexop = end;
|
||||
if (! regex)
|
||||
*noregexop = end;
|
||||
else
|
||||
*noregexop = split;
|
||||
}
|
||||
|
||||
static char **
|
||||
match_devices (const regex_t *regexp, int noparts)
|
||||
{
|
||||
int i;
|
||||
int ndev;
|
||||
char **devs;
|
||||
|
||||
auto int match (const char *name);
|
||||
int match (const char *name)
|
||||
{
|
||||
char **t;
|
||||
char *buffer;
|
||||
|
||||
/* skip partitions if asked to. */
|
||||
if (noparts && grub_strchr(name, ','))
|
||||
return 0;
|
||||
|
||||
buffer = grub_xasprintf ("(%s)", name);
|
||||
if (! buffer)
|
||||
return 1;
|
||||
|
||||
grub_dprintf ("expand", "matching: %s\n", buffer);
|
||||
if (regexec (regexp, buffer, 0, 0, 0))
|
||||
{
|
||||
grub_dprintf ("expand", "not matched\n");
|
||||
grub_free (buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
t = grub_realloc (devs, sizeof (char*) * (ndev + 2));
|
||||
if (! t)
|
||||
return 1;
|
||||
|
||||
devs = t;
|
||||
devs[ndev++] = buffer;
|
||||
devs[ndev] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ndev = 0;
|
||||
devs = 0;
|
||||
|
||||
if (grub_device_iterate (match))
|
||||
goto fail;
|
||||
|
||||
return devs;
|
||||
|
||||
fail:
|
||||
|
||||
for (i = 0; devs && devs[i]; i++)
|
||||
grub_free (devs[i]);
|
||||
|
||||
if (devs)
|
||||
grub_free (devs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char **
|
||||
match_files (const char *prefix, const char *suffix, const char *end,
|
||||
const regex_t *regexp)
|
||||
{
|
||||
int i;
|
||||
int error;
|
||||
char **files;
|
||||
unsigned nfile;
|
||||
char *dir;
|
||||
const char *path;
|
||||
char *device_name;
|
||||
grub_fs_t fs;
|
||||
grub_device_t dev;
|
||||
|
||||
auto int match (const char *name, const struct grub_dirhook_info *info);
|
||||
int match (const char *name, const struct grub_dirhook_info *info)
|
||||
{
|
||||
char **t;
|
||||
char *buffer;
|
||||
|
||||
/* skip . and .. names */
|
||||
if (grub_strcmp(".", name) == 0 || grub_strcmp("..", name) == 0)
|
||||
return 0;
|
||||
|
||||
grub_dprintf ("expand", "matching: %s in %s\n", name, dir);
|
||||
if (regexec (regexp, name, 0, 0, 0))
|
||||
return 0;
|
||||
|
||||
buffer = grub_xasprintf ("%s%s", dir, name);
|
||||
if (! buffer)
|
||||
return 1;
|
||||
|
||||
t = grub_realloc (files, sizeof (char*) * (nfile + 2));
|
||||
if (! t)
|
||||
{
|
||||
grub_free (buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
files = t;
|
||||
files[nfile++] = buffer;
|
||||
files[nfile] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
nfile = 0;
|
||||
files = 0;
|
||||
dev = 0;
|
||||
device_name = 0;
|
||||
grub_error_push ();
|
||||
|
||||
dir = make_dir (prefix, suffix, end);
|
||||
if (! dir)
|
||||
goto fail;
|
||||
|
||||
device_name = grub_file_get_device_name (dir);
|
||||
dev = grub_device_open (device_name);
|
||||
if (! dev)
|
||||
goto fail;
|
||||
|
||||
fs = grub_fs_probe (dev);
|
||||
if (! fs)
|
||||
goto fail;
|
||||
|
||||
path = grub_strchr (dir, ')');
|
||||
if (! path)
|
||||
goto fail;
|
||||
path++;
|
||||
|
||||
if (fs->dir (dev, path, match))
|
||||
goto fail;
|
||||
|
||||
grub_free (dir);
|
||||
grub_device_close (dev);
|
||||
grub_free (device_name);
|
||||
grub_error_pop ();
|
||||
return files;
|
||||
|
||||
fail:
|
||||
|
||||
if (dir)
|
||||
grub_free (dir);
|
||||
|
||||
for (i = 0; files && files[i]; i++)
|
||||
grub_free (files[i]);
|
||||
|
||||
if (files)
|
||||
grub_free (files);
|
||||
|
||||
if (dev)
|
||||
grub_device_close (dev);
|
||||
|
||||
if (device_name)
|
||||
grub_free (device_name);
|
||||
|
||||
grub_error_pop ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char*
|
||||
wildcard_escape (const char *s)
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
char ch;
|
||||
char *p;
|
||||
|
||||
len = grub_strlen (s);
|
||||
p = grub_malloc (len * 2 + 1);
|
||||
if (! p)
|
||||
return NULL;
|
||||
|
||||
i = 0;
|
||||
while ((ch = *s++))
|
||||
{
|
||||
if (isregexop (ch))
|
||||
p[i++] = '\\';
|
||||
p[i++] = ch;
|
||||
}
|
||||
p[i] = '\0';
|
||||
return p;
|
||||
}
|
||||
|
||||
static char*
|
||||
wildcard_unescape (const char *s)
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
char ch;
|
||||
char *p;
|
||||
|
||||
len = grub_strlen (s);
|
||||
p = grub_malloc (len + 1);
|
||||
if (! p)
|
||||
return NULL;
|
||||
|
||||
i = 0;
|
||||
while ((ch = *s++))
|
||||
{
|
||||
if (ch == '\\' && isregexop (*s))
|
||||
p[i++] = *s++;
|
||||
else
|
||||
p[i++] = ch;
|
||||
}
|
||||
p[i] = '\0';
|
||||
return p;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
wildcard_expand (const char *s, char ***strs)
|
||||
{
|
||||
const char *start;
|
||||
const char *regexop;
|
||||
const char *noregexop;
|
||||
char **paths = 0;
|
||||
|
||||
unsigned i;
|
||||
regex_t regexp;
|
||||
|
||||
start = s;
|
||||
while (*start)
|
||||
{
|
||||
split_path (start, &noregexop, ®exop);
|
||||
if (noregexop >= regexop) /* no more wildcards */
|
||||
break;
|
||||
|
||||
if (make_regex (noregexop, regexop, ®exp))
|
||||
goto fail;
|
||||
|
||||
if (paths == 0)
|
||||
{
|
||||
if (start == noregexop) /* device part has regexop */
|
||||
paths = match_devices (®exp, *start != '(');
|
||||
|
||||
else if (*start == '(') /* device part explicit wo regexop */
|
||||
paths = match_files ("", start, noregexop, ®exp);
|
||||
|
||||
else if (*start == '/') /* no device part */
|
||||
{
|
||||
char **r;
|
||||
unsigned n;
|
||||
char *root;
|
||||
char *prefix;
|
||||
|
||||
root = grub_env_get ("root");
|
||||
if (! root)
|
||||
goto fail;
|
||||
|
||||
prefix = grub_xasprintf ("(%s)", root);
|
||||
if (! prefix)
|
||||
goto fail;
|
||||
|
||||
paths = match_files (prefix, start, noregexop, ®exp);
|
||||
grub_free (prefix);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char **r = 0;
|
||||
|
||||
for (i = 0; paths[i]; i++)
|
||||
{
|
||||
char **p;
|
||||
|
||||
p = match_files (paths[i], start, noregexop, ®exp);
|
||||
if (! p)
|
||||
continue;
|
||||
|
||||
r = merge (r, p);
|
||||
if (! r)
|
||||
goto fail;
|
||||
}
|
||||
paths = r;
|
||||
}
|
||||
|
||||
regfree (®exp);
|
||||
if (! paths)
|
||||
goto done;
|
||||
|
||||
start = regexop;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
*strs = paths;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
||||
for (i = 0; paths && paths[i]; i++)
|
||||
grub_free (paths[i]);
|
||||
grub_free (paths);
|
||||
regfree (®exp);
|
||||
return grub_errno;
|
||||
}
|
|
@ -723,7 +723,6 @@ grub_ata_open (const char *name, grub_disk_t disk)
|
|||
|
||||
disk->id = (unsigned long) dev;
|
||||
|
||||
disk->has_partitions = 1;
|
||||
disk->data = dev;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -514,16 +514,12 @@ grub_efidisk_open (const char *name, struct grub_disk *disk)
|
|||
switch (name[0])
|
||||
{
|
||||
case 'f':
|
||||
disk->has_partitions = 0;
|
||||
d = get_device (fd_devices, num);
|
||||
break;
|
||||
case 'c':
|
||||
/* FIXME: a CDROM should have partitions, but not implemented yet. */
|
||||
disk->has_partitions = 0;
|
||||
d = get_device (cd_devices, num);
|
||||
break;
|
||||
case 'h':
|
||||
disk->has_partitions = 1;
|
||||
d = get_device (hd_devices, num);
|
||||
break;
|
||||
default:
|
||||
|
@ -731,7 +727,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
|||
{
|
||||
/* This is a hard disk partition. */
|
||||
grub_disk_t parent = 0;
|
||||
char *partition_name = 0;
|
||||
grub_partition_t tpart = NULL;
|
||||
char *device_name;
|
||||
grub_efi_device_path_t *dup_dp, *dup_ldp;
|
||||
grub_efi_hard_drive_device_path_t hd;
|
||||
|
@ -770,7 +766,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
|||
if (grub_partition_get_start (part) == hd.partition_start
|
||||
&& grub_partition_get_len (part) == hd.partition_size)
|
||||
{
|
||||
partition_name = grub_partition_get_name (part);
|
||||
tpart = part;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -799,14 +795,17 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
|||
grub_memcpy (&hd, ldp, sizeof (hd));
|
||||
grub_partition_iterate (parent, find_partition);
|
||||
|
||||
if (! partition_name)
|
||||
if (! tpart)
|
||||
{
|
||||
grub_disk_close (parent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_name = grub_xasprintf ("%s,%s", parent->name, partition_name);
|
||||
grub_free (partition_name);
|
||||
{
|
||||
char *partition_name = grub_partition_get_name (tpart);
|
||||
device_name = grub_xasprintf ("%s,%s", parent->name, partition_name);
|
||||
grub_free (partition_name);
|
||||
}
|
||||
grub_disk_close (parent);
|
||||
|
||||
return device_name;
|
||||
|
|
|
@ -43,7 +43,6 @@ grub_host_open (const char *name, grub_disk_t disk)
|
|||
disk->total_sectors = 0;
|
||||
disk->id = (unsigned long) "host";
|
||||
|
||||
disk->has_partitions = 0;
|
||||
disk->data = 0;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
*/
|
||||
|
||||
#include <grub/machine/biosdisk.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/machine/kernel.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/machine/int.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/dl.h>
|
||||
|
@ -248,6 +248,9 @@ grub_biosdisk_get_drive (const char *name)
|
|||
{
|
||||
unsigned long drive;
|
||||
|
||||
if (name[0] == 'c' && name[1] == 'd' && name[2] == 0 && cd_drive)
|
||||
return cd_drive;
|
||||
|
||||
if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd')
|
||||
goto fail;
|
||||
|
||||
|
@ -270,6 +273,9 @@ grub_biosdisk_call_hook (int (*hook) (const char *name), int drive)
|
|||
{
|
||||
char name[10];
|
||||
|
||||
if (cd_drive && drive == cd_drive)
|
||||
return hook ("cd");
|
||||
|
||||
grub_snprintf (name, sizeof (name),
|
||||
(drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
|
||||
return hook (name);
|
||||
|
@ -321,7 +327,6 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
|||
if (drive < 0)
|
||||
return grub_errno;
|
||||
|
||||
disk->has_partitions = 1;
|
||||
disk->id = drive;
|
||||
|
||||
data = (struct grub_biosdisk_data *) grub_zalloc (sizeof (*data));
|
||||
|
|
|
@ -113,7 +113,6 @@ grub_nand_open (const char *name, grub_disk_t disk)
|
|||
|
||||
disk->id = dev_ihandle;
|
||||
|
||||
disk->has_partitions = 0;
|
||||
disk->data = data;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -23,9 +23,15 @@
|
|||
#include <grub/ieee1275/ieee1275.h>
|
||||
#include <grub/ieee1275/ofdisk.h>
|
||||
|
||||
static char *last_devpath;
|
||||
static grub_ieee1275_ihandle_t last_ihandle;
|
||||
|
||||
struct ofdisk_hash_ent
|
||||
{
|
||||
char *devpath;
|
||||
/* Pointer to shortest available name on nodes representing canonical names,
|
||||
otherwise NULL. */
|
||||
const char *shortest;
|
||||
struct ofdisk_hash_ent *next;
|
||||
};
|
||||
|
||||
|
@ -59,60 +65,125 @@ static struct ofdisk_hash_ent *
|
|||
ofdisk_hash_add (char *devpath)
|
||||
{
|
||||
struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)];
|
||||
struct ofdisk_hash_ent *p = grub_malloc(sizeof (*p));
|
||||
struct ofdisk_hash_ent *p, *pcan;
|
||||
char *curcan;
|
||||
|
||||
if (p)
|
||||
p = grub_malloc(sizeof (*p));
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
p->devpath = devpath;
|
||||
p->next = *head;
|
||||
p->shortest = 0;
|
||||
*head = p;
|
||||
|
||||
curcan = grub_ieee1275_canonicalise_devname (devpath);
|
||||
if (!curcan)
|
||||
{
|
||||
p->devpath = devpath;
|
||||
p->next = *head;
|
||||
*head = p;
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return p;
|
||||
}
|
||||
|
||||
pcan = ofdisk_hash_find (curcan);
|
||||
if (!pcan)
|
||||
pcan = ofdisk_hash_add (curcan);
|
||||
else
|
||||
grub_free (curcan);
|
||||
|
||||
if (!pcan)
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
else
|
||||
{
|
||||
if (!pcan->shortest
|
||||
|| grub_strlen (pcan->shortest) > grub_strlen (devpath))
|
||||
pcan->shortest = devpath;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static int
|
||||
grub_ofdisk_iterate (int (*hook) (const char *name))
|
||||
static void
|
||||
scan (void)
|
||||
{
|
||||
auto int dev_iterate (struct grub_ieee1275_devalias *alias);
|
||||
|
||||
int dev_iterate (struct grub_ieee1275_devalias *alias)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ofdisk_hash_ent *op;
|
||||
|
||||
grub_dprintf ("disk", "device name = %s type = %s\n", alias->name,
|
||||
alias->type);
|
||||
|
||||
if (grub_strcmp (alias->type, "block") != 0)
|
||||
return 0;
|
||||
|
||||
grub_dprintf ("disk", "disk name = %s\n", alias->name);
|
||||
|
||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY))
|
||||
op = ofdisk_hash_find (alias->path);
|
||||
if (!op)
|
||||
{
|
||||
grub_ieee1275_phandle_t dev;
|
||||
char tmp[8];
|
||||
|
||||
if (grub_ieee1275_finddevice (alias->path, &dev))
|
||||
char *name = grub_strdup (alias->name);
|
||||
if (!name)
|
||||
{
|
||||
grub_dprintf ("disk", "finddevice (%s) failed\n", alias->path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (grub_ieee1275_get_property (dev, "iconname", tmp,
|
||||
sizeof tmp, 0))
|
||||
{
|
||||
grub_dprintf ("disk", "get iconname failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (grub_strcmp (tmp, "sdmmc"))
|
||||
{
|
||||
grub_dprintf ("disk", "device is not an SD card\n");
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return 0;
|
||||
}
|
||||
op = ofdisk_hash_add (name);
|
||||
}
|
||||
|
||||
if (! grub_strcmp (alias->type, "block") &&
|
||||
grub_strncmp (alias->name, "cdrom", 5))
|
||||
ret = hook (alias->name);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return grub_devalias_iterate (dev_iterate);
|
||||
grub_devalias_iterate (dev_iterate);
|
||||
grub_ieee1275_devices_iterate (dev_iterate);
|
||||
}
|
||||
|
||||
static int
|
||||
grub_ofdisk_iterate (int (*hook) (const char *name))
|
||||
{
|
||||
unsigned i;
|
||||
scan ();
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (ofdisk_hash); i++)
|
||||
{
|
||||
static struct ofdisk_hash_ent *ent;
|
||||
for (ent = ofdisk_hash[i]; ent; ent = ent->next)
|
||||
{
|
||||
if (!ent->shortest)
|
||||
continue;
|
||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY))
|
||||
{
|
||||
grub_ieee1275_phandle_t dev;
|
||||
char tmp[8];
|
||||
|
||||
if (grub_ieee1275_finddevice (ent->devpath, &dev))
|
||||
{
|
||||
grub_dprintf ("disk", "finddevice (%s) failed\n",
|
||||
ent->devpath);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_ieee1275_get_property (dev, "iconname", tmp,
|
||||
sizeof tmp, 0))
|
||||
{
|
||||
grub_dprintf ("disk", "get iconname failed\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (tmp, "sdmmc") != 0)
|
||||
{
|
||||
grub_dprintf ("disk", "device is not an SD card\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (grub_strncmp (ent->shortest, "cdrom", 5) == 0)
|
||||
continue;
|
||||
|
||||
if (hook (ent->shortest))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
|
@ -137,11 +208,6 @@ compute_dev_path (const char *name)
|
|||
*p++ = c;
|
||||
}
|
||||
|
||||
if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
|
||||
{
|
||||
*p++ = ':';
|
||||
*p++ = '0';
|
||||
}
|
||||
*p++ = '\0';
|
||||
|
||||
return devpath;
|
||||
|
@ -151,8 +217,6 @@ static grub_err_t
|
|||
grub_ofdisk_open (const char *name, grub_disk_t disk)
|
||||
{
|
||||
grub_ieee1275_phandle_t dev;
|
||||
grub_ieee1275_ihandle_t dev_ihandle = 0;
|
||||
struct ofdisk_hash_ent *op;
|
||||
char *devpath;
|
||||
/* XXX: This should be large enough for any possible case. */
|
||||
char prop[64];
|
||||
|
@ -162,69 +226,50 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
|
|||
if (! devpath)
|
||||
return grub_errno;
|
||||
|
||||
op = ofdisk_hash_find (devpath);
|
||||
if (!op)
|
||||
op = ofdisk_hash_add (devpath);
|
||||
grub_dprintf ("disk", "Opening `%s'.\n", devpath);
|
||||
|
||||
grub_free (devpath);
|
||||
if (!op)
|
||||
return grub_errno;
|
||||
|
||||
grub_dprintf ("disk", "Opening `%s'.\n", op->devpath);
|
||||
|
||||
if (grub_ieee1275_finddevice (op->devpath, &dev))
|
||||
{
|
||||
grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read device properties");
|
||||
goto fail;
|
||||
}
|
||||
if (grub_ieee1275_finddevice (devpath, &dev))
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read device properties");
|
||||
|
||||
if (grub_ieee1275_get_property (dev, "device_type", prop, sizeof (prop),
|
||||
&actual))
|
||||
{
|
||||
grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read the device type");
|
||||
goto fail;
|
||||
}
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read the device type");
|
||||
|
||||
if (grub_strcmp (prop, "block"))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_DEVICE, "not a block device");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
grub_ieee1275_open (op->devpath, &dev_ihandle);
|
||||
if (! dev_ihandle)
|
||||
{
|
||||
grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
grub_dprintf ("disk", "Opened `%s' as handle %p.\n", op->devpath,
|
||||
(void *) (unsigned long) dev_ihandle);
|
||||
return grub_error (GRUB_ERR_BAD_DEVICE, "not a block device");
|
||||
|
||||
/* XXX: There is no property to read the number of blocks. There
|
||||
should be a property `#blocks', but it is not there. Perhaps it
|
||||
is possible to use seek for this. */
|
||||
disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
|
||||
|
||||
disk->id = (unsigned long) op;
|
||||
{
|
||||
struct ofdisk_hash_ent *op;
|
||||
op = ofdisk_hash_find (devpath);
|
||||
if (!op)
|
||||
op = ofdisk_hash_add (devpath);
|
||||
else
|
||||
grub_free (devpath);
|
||||
if (!op)
|
||||
return grub_errno;
|
||||
disk->id = (unsigned long) op;
|
||||
disk->data = op->devpath;
|
||||
}
|
||||
|
||||
/* XXX: Read this, somehow. */
|
||||
disk->has_partitions = 1;
|
||||
disk->data = (void *) (unsigned long) dev_ihandle;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (dev_ihandle)
|
||||
grub_ieee1275_close (dev_ihandle);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_ofdisk_close (grub_disk_t disk)
|
||||
{
|
||||
grub_dprintf ("disk", "Closing handle %p.\n",
|
||||
(void *) disk->data);
|
||||
grub_ieee1275_close ((grub_ieee1275_ihandle_t) (unsigned long) disk->data);
|
||||
if (disk->data == last_devpath)
|
||||
{
|
||||
if (last_ihandle)
|
||||
grub_ieee1275_close (last_ihandle);
|
||||
last_ihandle = 0;
|
||||
last_devpath = NULL;
|
||||
}
|
||||
disk->data = 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
|
@ -234,16 +279,40 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
|||
grub_ssize_t status, actual;
|
||||
unsigned long long pos;
|
||||
|
||||
if (disk->data != last_devpath)
|
||||
{
|
||||
if (last_ihandle)
|
||||
grub_ieee1275_close (last_ihandle);
|
||||
last_ihandle = 0;
|
||||
last_devpath = NULL;
|
||||
|
||||
if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
|
||||
{
|
||||
char name2[grub_strlen (disk->data) + 3];
|
||||
char *p;
|
||||
|
||||
grub_strcpy (name2, disk->data);
|
||||
p = name2 + grub_strlen (name2);
|
||||
*p++ = ':';
|
||||
*p++ = '0';
|
||||
*p = 0;
|
||||
grub_ieee1275_open (name2, &last_ihandle);
|
||||
}
|
||||
else
|
||||
grub_ieee1275_open (disk->data, &last_ihandle);
|
||||
if (! last_ihandle)
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
|
||||
last_devpath = disk->data;
|
||||
}
|
||||
|
||||
pos = sector * 512UL;
|
||||
|
||||
grub_ieee1275_seek ((grub_ieee1275_ihandle_t) (unsigned long) disk->data,
|
||||
pos, &status);
|
||||
grub_ieee1275_seek (last_ihandle, pos, &status);
|
||||
if (status < 0)
|
||||
return grub_error (GRUB_ERR_READ_ERROR,
|
||||
"seek error, can't seek block %llu",
|
||||
(long long) sector);
|
||||
grub_ieee1275_read ((grub_ieee1275_ihandle_t) (unsigned long) disk->data,
|
||||
buf, size * 512UL, &actual);
|
||||
grub_ieee1275_read (last_ihandle, buf, size * 512UL, &actual);
|
||||
if (actual != (grub_ssize_t) (size * 512UL))
|
||||
return grub_error (GRUB_ERR_READ_ERROR, "read error on block: %llu",
|
||||
(long long) sector);
|
||||
|
@ -281,5 +350,10 @@ grub_ofdisk_init (void)
|
|||
void
|
||||
grub_ofdisk_fini (void)
|
||||
{
|
||||
if (last_ihandle)
|
||||
grub_ieee1275_close (last_ihandle);
|
||||
last_ihandle = 0;
|
||||
last_devpath = NULL;
|
||||
|
||||
grub_disk_dev_unregister (&grub_ofdisk_dev);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ struct grub_loopback
|
|||
{
|
||||
char *devname;
|
||||
grub_file_t file;
|
||||
int has_partitions;
|
||||
struct grub_loopback *next;
|
||||
};
|
||||
|
||||
|
@ -38,7 +37,6 @@ static struct grub_loopback *loopback_list;
|
|||
static const struct grub_arg_option options[] =
|
||||
{
|
||||
{"delete", 'd', 0, N_("Delete the loopback device entry."), 0, 0},
|
||||
{"partitions", 'p', 0, N_("Simulate a hard drive with partitions."), 0, 0},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -71,9 +69,9 @@ delete_loopback (const char *name)
|
|||
|
||||
/* The command to add and remove loopback devices. */
|
||||
static grub_err_t
|
||||
grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args)
|
||||
grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = state = cmd->state;
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
grub_file_t file;
|
||||
struct grub_loopback *newdev;
|
||||
grub_err_t ret;
|
||||
|
@ -106,9 +104,6 @@ grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args)
|
|||
grub_file_close (newdev->file);
|
||||
newdev->file = file;
|
||||
|
||||
/* Set has_partitions when `--partitions' was used. */
|
||||
newdev->has_partitions = state[1].set;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -126,9 +121,6 @@ grub_cmd_loopback (grub_extcmd_t cmd, int argc, char **args)
|
|||
|
||||
newdev->file = file;
|
||||
|
||||
/* Set has_partitions when `--partitions' was used. */
|
||||
newdev->has_partitions = state[1].set;
|
||||
|
||||
/* Add the new entry to the list. */
|
||||
newdev->next = loopback_list;
|
||||
loopback_list = newdev;
|
||||
|
@ -167,11 +159,13 @@ grub_loopback_open (const char *name, grub_disk_t disk)
|
|||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
|
||||
|
||||
/* Use the filesize for the disk size, round up to a complete sector. */
|
||||
disk->total_sectors = ((dev->file->size + GRUB_DISK_SECTOR_SIZE - 1)
|
||||
/ GRUB_DISK_SECTOR_SIZE);
|
||||
if (dev->file->size != GRUB_FILE_SIZE_UNKNOWN)
|
||||
disk->total_sectors = ((dev->file->size + GRUB_DISK_SECTOR_SIZE - 1)
|
||||
/ GRUB_DISK_SECTOR_SIZE);
|
||||
else
|
||||
disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
|
||||
disk->id = (unsigned long) dev;
|
||||
|
||||
disk->has_partitions = dev->has_partitions;
|
||||
disk->data = dev->file;
|
||||
|
||||
return 0;
|
||||
|
@ -227,8 +221,7 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(loopback)
|
||||
{
|
||||
cmd = grub_register_extcmd ("loopback", grub_cmd_loopback,
|
||||
GRUB_COMMAND_FLAG_BOTH,
|
||||
cmd = grub_register_extcmd ("loopback", grub_cmd_loopback, 0,
|
||||
N_("[-d|-p] DEVICENAME FILE."),
|
||||
N_("Make a device of a file."), options);
|
||||
grub_disk_dev_register (&grub_loopback_dev);
|
||||
|
|
|
@ -150,7 +150,6 @@ grub_lvm_open (const char *name, grub_disk_t disk)
|
|||
if (! lv)
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown LVM device %s", name);
|
||||
|
||||
disk->has_partitions = 0;
|
||||
disk->id = lv->number;
|
||||
disk->data = lv;
|
||||
disk->total_sectors = lv->size;
|
||||
|
@ -274,9 +273,17 @@ grub_lvm_scan_device (const char *name)
|
|||
struct grub_lvm_vg *vg;
|
||||
struct grub_lvm_pv *pv;
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("scanning %s for LVM", name);
|
||||
#endif
|
||||
|
||||
disk = grub_disk_open (name);
|
||||
if (!disk)
|
||||
return 0;
|
||||
{
|
||||
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Search for label. */
|
||||
for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
|
||||
|
@ -294,7 +301,12 @@ grub_lvm_scan_device (const char *name)
|
|||
|
||||
/* Return if we didn't find a label. */
|
||||
if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
|
||||
goto fail;
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("no LVM signature found\n");
|
||||
#endif
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
|
||||
|
||||
|
@ -318,6 +330,9 @@ grub_lvm_scan_device (const char *name)
|
|||
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"we don't support multiple LVM data areas");
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("we don't support multiple LVM data areas\n");
|
||||
#endif
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -344,6 +359,9 @@ grub_lvm_scan_device (const char *name)
|
|||
{
|
||||
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"unknown LVM metadata header");
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("unknown LVM metadata header\n");
|
||||
#endif
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
|
@ -364,7 +382,12 @@ grub_lvm_scan_device (const char *name)
|
|||
q++;
|
||||
|
||||
if (q == metadatabuf + mda_size)
|
||||
goto fail2;
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("error parsing metadata\n");
|
||||
#endif
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
vgname_len = q - p;
|
||||
vgname = grub_malloc (vgname_len + 1);
|
||||
|
@ -376,7 +399,12 @@ grub_lvm_scan_device (const char *name)
|
|||
|
||||
p = grub_strstr (q, "id = \"");
|
||||
if (p == NULL)
|
||||
goto fail3;
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("couldn't find ID\n");
|
||||
#endif
|
||||
goto fail3;
|
||||
}
|
||||
p += sizeof ("id = \"") - 1;
|
||||
grub_memcpy (vg_id, p, GRUB_LVM_ID_STRLEN);
|
||||
vg_id[GRUB_LVM_ID_STRLEN] = '\0';
|
||||
|
@ -399,7 +427,12 @@ grub_lvm_scan_device (const char *name)
|
|||
|
||||
vg->extent_size = grub_lvm_getvalue (&p, "extent_size = ");
|
||||
if (p == NULL)
|
||||
goto fail4;
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("unknown extent size\n");
|
||||
#endif
|
||||
goto fail4;
|
||||
}
|
||||
|
||||
vg->lvs = NULL;
|
||||
vg->pvs = NULL;
|
||||
|
@ -439,11 +472,21 @@ grub_lvm_scan_device (const char *name)
|
|||
|
||||
pv->start = grub_lvm_getvalue (&p, "pe_start = ");
|
||||
if (p == NULL)
|
||||
goto pvs_fail;
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("unknown pe_start\n");
|
||||
#endif
|
||||
goto pvs_fail;
|
||||
}
|
||||
|
||||
p = grub_strchr (p, '}');
|
||||
if (p == NULL)
|
||||
goto pvs_fail;
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("error parsing pe_start\n");
|
||||
#endif
|
||||
goto pvs_fail;
|
||||
}
|
||||
p++;
|
||||
|
||||
pv->disk = NULL;
|
||||
|
@ -500,7 +543,12 @@ grub_lvm_scan_device (const char *name)
|
|||
|
||||
lv->segment_count = grub_lvm_getvalue (&p, "segment_count = ");
|
||||
if (p == NULL)
|
||||
goto lvs_fail;
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("unknown segment_count\n");
|
||||
#endif
|
||||
goto lvs_fail;
|
||||
}
|
||||
lv->segments = grub_malloc (sizeof (*seg) * lv->segment_count);
|
||||
seg = lv->segments;
|
||||
|
||||
|
@ -510,14 +558,29 @@ grub_lvm_scan_device (const char *name)
|
|||
|
||||
p = grub_strstr (p, "segment");
|
||||
if (p == NULL)
|
||||
goto lvs_segment_fail;
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("unknown segment\n");
|
||||
#endif
|
||||
goto lvs_segment_fail;
|
||||
}
|
||||
|
||||
seg->start_extent = grub_lvm_getvalue (&p, "start_extent = ");
|
||||
if (p == NULL)
|
||||
goto lvs_segment_fail;
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("unknown start_extent\n");
|
||||
#endif
|
||||
goto lvs_segment_fail;
|
||||
}
|
||||
seg->extent_count = grub_lvm_getvalue (&p, "extent_count = ");
|
||||
if (p == NULL)
|
||||
goto lvs_segment_fail;
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("unknown extent_count\n");
|
||||
#endif
|
||||
goto lvs_segment_fail;
|
||||
}
|
||||
|
||||
if (grub_lvm_checkvalue (&p, "type = ", "snapshot"))
|
||||
{
|
||||
|
@ -528,7 +591,12 @@ grub_lvm_scan_device (const char *name)
|
|||
|
||||
seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = ");
|
||||
if (p == NULL)
|
||||
goto lvs_segment_fail;
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("unknown stripe_count\n");
|
||||
#endif
|
||||
goto lvs_segment_fail;
|
||||
}
|
||||
|
||||
lv->size += seg->extent_count * vg->extent_size;
|
||||
|
||||
|
@ -541,7 +609,12 @@ grub_lvm_scan_device (const char *name)
|
|||
|
||||
p = grub_strstr (p, "stripes = [");
|
||||
if (p == NULL)
|
||||
goto lvs_segment_fail2;
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("unknown stripes\n");
|
||||
#endif
|
||||
goto lvs_segment_fail2;
|
||||
}
|
||||
p += sizeof("stripes = [") - 1;
|
||||
|
||||
for (j = 0; j < seg->stripe_count; j++)
|
||||
|
@ -655,6 +728,8 @@ grub_lvm_scan_device (const char *name)
|
|||
grub_free (metadatabuf);
|
||||
fail:
|
||||
grub_disk_close (disk);
|
||||
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
231
grub-core/disk/mdraid1x_linux.c
Normal file
231
grub-core/disk/mdraid1x_linux.c
Normal file
|
@ -0,0 +1,231 @@
|
|||
/* mdraid_linux.c - module to handle Linux Software RAID. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008,2009,2010 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/dl.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/raid.h>
|
||||
|
||||
/* Linux RAID on disk structures and constants,
|
||||
copied from include/linux/raid/md_p.h. */
|
||||
|
||||
#define SB_MAGIC 0xa92b4efc
|
||||
|
||||
/*
|
||||
* The version-1 superblock :
|
||||
* All numeric fields are little-endian.
|
||||
*
|
||||
* Total size: 256 bytes plus 2 per device.
|
||||
* 1K allows 384 devices.
|
||||
*/
|
||||
|
||||
struct grub_raid_super_1x
|
||||
{
|
||||
/* Constant array information - 128 bytes. */
|
||||
grub_uint32_t magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian. */
|
||||
grub_uint32_t major_version; /* 1. */
|
||||
grub_uint32_t feature_map; /* Bit 0 set if 'bitmap_offset' is meaningful. */
|
||||
grub_uint32_t pad0; /* Always set to 0 when writing. */
|
||||
|
||||
grub_uint8_t set_uuid[16]; /* User-space generated. */
|
||||
char set_name[32]; /* Set and interpreted by user-space. */
|
||||
|
||||
grub_uint64_t ctime; /* Lo 40 bits are seconds, top 24 are microseconds or 0. */
|
||||
grub_uint32_t level; /* -4 (multipath), -1 (linear), 0,1,4,5. */
|
||||
grub_uint32_t layout; /* only for raid5 and raid10 currently. */
|
||||
grub_uint64_t size; /* Used size of component devices, in 512byte sectors. */
|
||||
|
||||
grub_uint32_t chunksize; /* In 512byte sectors. */
|
||||
grub_uint32_t raid_disks;
|
||||
grub_uint32_t bitmap_offset; /* Sectors after start of superblock that bitmap starts
|
||||
* NOTE: signed, so bitmap can be before superblock
|
||||
* only meaningful of feature_map[0] is set.
|
||||
*/
|
||||
|
||||
/* These are only valid with feature bit '4'. */
|
||||
grub_uint32_t new_level; /* New level we are reshaping to. */
|
||||
grub_uint64_t reshape_position; /* Next address in array-space for reshape. */
|
||||
grub_uint32_t delta_disks; /* Change in number of raid_disks. */
|
||||
grub_uint32_t new_layout; /* New layout. */
|
||||
grub_uint32_t new_chunk; /* New chunk size (512byte sectors). */
|
||||
grub_uint8_t pad1[128 - 124]; /* Set to 0 when written. */
|
||||
|
||||
/* Constant this-device information - 64 bytes. */
|
||||
grub_uint64_t data_offset; /* Sector start of data, often 0. */
|
||||
grub_uint64_t data_size; /* Sectors in this device that can be used for data. */
|
||||
grub_uint64_t super_offset; /* Sector start of this superblock. */
|
||||
grub_uint64_t recovery_offset; /* Sectors before this offset (from data_offset) have been recovered. */
|
||||
grub_uint32_t dev_number; /* Permanent identifier of this device - not role in raid. */
|
||||
grub_uint32_t cnt_corrected_read; /* Number of read errors that were corrected by re-writing. */
|
||||
grub_uint8_t device_uuid[16]; /* User-space setable, ignored by kernel. */
|
||||
grub_uint8_t devflags; /* Per-device flags. Only one defined... */
|
||||
grub_uint8_t pad2[64 - 57]; /* Set to 0 when writing. */
|
||||
|
||||
/* Array state information - 64 bytes. */
|
||||
grub_uint64_t utime; /* 40 bits second, 24 btes microseconds. */
|
||||
grub_uint64_t events; /* Incremented when superblock updated. */
|
||||
grub_uint64_t resync_offset; /* Data before this offset (from data_offset) known to be in sync. */
|
||||
grub_uint32_t sb_csum; /* Checksum upto devs[max_dev]. */
|
||||
grub_uint32_t max_dev; /* Size of devs[] array to consider. */
|
||||
grub_uint8_t pad3[64 - 32]; /* Set to 0 when writing. */
|
||||
|
||||
/* Device state information. Indexed by dev_number.
|
||||
* 2 bytes per device.
|
||||
* Note there are no per-device state flags. State information is rolled
|
||||
* into the 'roles' value. If a device is spare or faulty, then it doesn't
|
||||
* have a meaningful role.
|
||||
*/
|
||||
grub_uint16_t dev_roles[0]; /* Role in array, or 0xffff for a spare, or 0xfffe for faulty. */
|
||||
};
|
||||
/* Could be __attribute__ ((packed)), but since all members in this struct
|
||||
are already appropriately aligned, we can omit this and avoid suboptimal
|
||||
assembly in some cases. */
|
||||
|
||||
#define WriteMostly1 1 /* Mask for writemostly flag in above devflags. */
|
||||
|
||||
static grub_err_t
|
||||
grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array,
|
||||
grub_disk_addr_t *start_sector)
|
||||
{
|
||||
grub_disk_addr_t sector;
|
||||
grub_uint64_t size;
|
||||
struct grub_raid_super_1x sb;
|
||||
grub_uint8_t minor_version;
|
||||
|
||||
/* The sector where the mdraid 0.90 superblock is stored, if available. */
|
||||
size = grub_disk_get_size (disk);
|
||||
|
||||
/* Check for an 1.x superblock.
|
||||
* It's always aligned to a 4K boundary
|
||||
* and depending on the minor version it can be:
|
||||
* 0: At least 8K, but less than 12K, from end of device
|
||||
* 1: At start of device
|
||||
* 2: 4K from start of device.
|
||||
*/
|
||||
|
||||
for (minor_version = 0; minor_version < 3; ++minor_version)
|
||||
{
|
||||
switch (minor_version)
|
||||
{
|
||||
case 0:
|
||||
sector = (size - 8 * 2) & ~(4 * 2 - 1);
|
||||
break;
|
||||
case 1:
|
||||
sector = 0;
|
||||
break;
|
||||
case 2:
|
||||
sector = 4 * 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (grub_disk_read (disk, sector, 0, sizeof (struct grub_raid_super_1x),
|
||||
&sb))
|
||||
return grub_errno;
|
||||
|
||||
if (sb.magic != SB_MAGIC)
|
||||
continue;
|
||||
|
||||
{
|
||||
grub_uint64_t sb_size;
|
||||
struct grub_raid_super_1x *real_sb;
|
||||
|
||||
if (sb.major_version != 1)
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"Unsupported RAID version: %d",
|
||||
sb.major_version);
|
||||
|
||||
/* Multipath. */
|
||||
if ((int) sb.level == -4)
|
||||
sb.level = 1;
|
||||
|
||||
if (sb.level != 0 && sb.level != 1 && sb.level != 4 &&
|
||||
sb.level != 5 && sb.level != 6 && sb.level != 10)
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"Unsupported RAID level: %d", sb.level);
|
||||
|
||||
/* 1.x superblocks don't have a fixed size on disk. So we have to
|
||||
read it again now that we now the max device count. */
|
||||
sb_size = sizeof (struct grub_raid_super_1x)
|
||||
+ 2 * grub_le_to_cpu32 (sb.max_dev);
|
||||
real_sb = grub_malloc (sb_size);
|
||||
if (! real_sb)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_disk_read (disk, sector, 0, sb_size, real_sb))
|
||||
{
|
||||
grub_free (real_sb);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
array->name = grub_strdup (real_sb->set_name);
|
||||
if (! array->name)
|
||||
{
|
||||
grub_free (real_sb);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
array->number = 0;
|
||||
array->level = grub_le_to_cpu32 (real_sb->level);
|
||||
array->layout = grub_le_to_cpu32 (real_sb->layout);
|
||||
array->total_devs = grub_le_to_cpu32 (real_sb->raid_disks);
|
||||
array->disk_size = grub_le_to_cpu64 (real_sb->size);
|
||||
array->chunk_size = grub_le_to_cpu32 (real_sb->chunksize);
|
||||
if (grub_le_to_cpu32 (real_sb->dev_number) <
|
||||
grub_le_to_cpu32 (real_sb->max_dev))
|
||||
array->index = grub_le_to_cpu16
|
||||
(real_sb->dev_roles[grub_le_to_cpu32 (real_sb->dev_number)]);
|
||||
else
|
||||
array->index = 0xffff; /* disk will be later not used! */
|
||||
array->uuid_len = 16;
|
||||
array->uuid = grub_malloc (16);
|
||||
if (!array->uuid)
|
||||
{
|
||||
grub_free (real_sb);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
grub_memcpy (array->uuid, real_sb->set_uuid, 16);
|
||||
|
||||
*start_sector = real_sb->data_offset;
|
||||
|
||||
grub_free (real_sb);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE, "not 1.x raid");
|
||||
}
|
||||
|
||||
static struct grub_raid grub_mdraid_dev = {
|
||||
.name = "mdraid1x",
|
||||
.detect = grub_mdraid_detect,
|
||||
.next = 0
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT (mdraid1x)
|
||||
{
|
||||
grub_raid_register (&grub_mdraid_dev);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (mdraid1x)
|
||||
{
|
||||
grub_raid_unregister (&grub_mdraid_dev);
|
||||
}
|
|
@ -159,266 +159,78 @@ struct grub_raid_super_09
|
|||
struct grub_raid_disk_09 this_disk;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* The version-1 superblock :
|
||||
* All numeric fields are little-endian.
|
||||
*
|
||||
* Total size: 256 bytes plus 2 per device.
|
||||
* 1K allows 384 devices.
|
||||
*/
|
||||
|
||||
struct grub_raid_super_1x
|
||||
{
|
||||
/* Constant array information - 128 bytes. */
|
||||
grub_uint32_t magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian. */
|
||||
grub_uint32_t major_version; /* 1. */
|
||||
grub_uint32_t feature_map; /* Bit 0 set if 'bitmap_offset' is meaningful. */
|
||||
grub_uint32_t pad0; /* Always set to 0 when writing. */
|
||||
|
||||
grub_uint8_t set_uuid[16]; /* User-space generated. */
|
||||
char set_name[32]; /* Set and interpreted by user-space. */
|
||||
|
||||
grub_uint64_t ctime; /* Lo 40 bits are seconds, top 24 are microseconds or 0. */
|
||||
grub_uint32_t level; /* -4 (multipath), -1 (linear), 0,1,4,5. */
|
||||
grub_uint32_t layout; /* only for raid5 and raid10 currently. */
|
||||
grub_uint64_t size; /* Used size of component devices, in 512byte sectors. */
|
||||
|
||||
grub_uint32_t chunksize; /* In 512byte sectors. */
|
||||
grub_uint32_t raid_disks;
|
||||
grub_uint32_t bitmap_offset; /* Sectors after start of superblock that bitmap starts
|
||||
* NOTE: signed, so bitmap can be before superblock
|
||||
* only meaningful of feature_map[0] is set.
|
||||
*/
|
||||
|
||||
/* These are only valid with feature bit '4'. */
|
||||
grub_uint32_t new_level; /* New level we are reshaping to. */
|
||||
grub_uint64_t reshape_position; /* Next address in array-space for reshape. */
|
||||
grub_uint32_t delta_disks; /* Change in number of raid_disks. */
|
||||
grub_uint32_t new_layout; /* New layout. */
|
||||
grub_uint32_t new_chunk; /* New chunk size (512byte sectors). */
|
||||
grub_uint8_t pad1[128 - 124]; /* Set to 0 when written. */
|
||||
|
||||
/* Constant this-device information - 64 bytes. */
|
||||
grub_uint64_t data_offset; /* Sector start of data, often 0. */
|
||||
grub_uint64_t data_size; /* Sectors in this device that can be used for data. */
|
||||
grub_uint64_t super_offset; /* Sector start of this superblock. */
|
||||
grub_uint64_t recovery_offset; /* Sectors before this offset (from data_offset) have been recovered. */
|
||||
grub_uint32_t dev_number; /* Permanent identifier of this device - not role in raid. */
|
||||
grub_uint32_t cnt_corrected_read; /* Number of read errors that were corrected by re-writing. */
|
||||
grub_uint8_t device_uuid[16]; /* User-space setable, ignored by kernel. */
|
||||
grub_uint8_t devflags; /* Per-device flags. Only one defined... */
|
||||
grub_uint8_t pad2[64 - 57]; /* Set to 0 when writing. */
|
||||
|
||||
/* Array state information - 64 bytes. */
|
||||
grub_uint64_t utime; /* 40 bits second, 24 btes microseconds. */
|
||||
grub_uint64_t events; /* Incremented when superblock updated. */
|
||||
grub_uint64_t resync_offset; /* Data before this offset (from data_offset) known to be in sync. */
|
||||
grub_uint32_t sb_csum; /* Checksum upto devs[max_dev]. */
|
||||
grub_uint32_t max_dev; /* Size of devs[] array to consider. */
|
||||
grub_uint8_t pad3[64 - 32]; /* Set to 0 when writing. */
|
||||
|
||||
/* Device state information. Indexed by dev_number.
|
||||
* 2 bytes per device.
|
||||
* Note there are no per-device state flags. State information is rolled
|
||||
* into the 'roles' value. If a device is spare or faulty, then it doesn't
|
||||
* have a meaningful role.
|
||||
*/
|
||||
grub_uint16_t dev_roles[0]; /* Role in array, or 0xffff for a spare, or 0xfffe for faulty. */
|
||||
};
|
||||
/* Could be __attribute__ ((packed)), but since all members in this struct
|
||||
are already appropriately aligned, we can omit this and avoid suboptimal
|
||||
assembly in some cases. */
|
||||
|
||||
#define WriteMostly1 1 /* Mask for writemostly flag in above devflags. */
|
||||
|
||||
static grub_err_t
|
||||
grub_mdraid_detect_09 (grub_disk_addr_t sector,
|
||||
struct grub_raid_super_09 *sb,
|
||||
struct grub_raid_array *array,
|
||||
grub_disk_addr_t *start_sector)
|
||||
{
|
||||
grub_uint32_t *uuid;
|
||||
|
||||
if (sb->major_version != 0 || sb->minor_version != 90)
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"unsupported RAID version: %d.%d",
|
||||
sb->major_version, sb->minor_version);
|
||||
|
||||
/* FIXME: Check the checksum. */
|
||||
|
||||
/* Multipath. */
|
||||
if ((int) sb->level == -4)
|
||||
sb->level = 1;
|
||||
|
||||
if (sb->level != 0 && sb->level != 1 && sb->level != 4 &&
|
||||
sb->level != 5 && sb->level != 6 && sb->level != 10)
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"unsupported RAID level: %d", sb->level);
|
||||
|
||||
array->name = NULL;
|
||||
array->number = sb->md_minor;
|
||||
array->level = sb->level;
|
||||
array->layout = sb->layout;
|
||||
array->total_devs = sb->raid_disks;
|
||||
array->disk_size = (sb->size) ? sb->size * 2 : sector;
|
||||
array->chunk_size = sb->chunk_size >> 9;
|
||||
array->index = sb->this_disk.number;
|
||||
array->uuid_len = 16;
|
||||
array->uuid = grub_malloc (16);
|
||||
if (!array->uuid)
|
||||
return grub_errno;
|
||||
|
||||
uuid = (grub_uint32_t *) array->uuid;
|
||||
uuid[0] = sb->set_uuid0;
|
||||
uuid[1] = sb->set_uuid1;
|
||||
uuid[2] = sb->set_uuid2;
|
||||
uuid[3] = sb->set_uuid3;
|
||||
|
||||
*start_sector = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_mdraid_detect_1x (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
struct grub_raid_super_1x *sb,
|
||||
struct grub_raid_array *array,
|
||||
grub_disk_addr_t *start_sector)
|
||||
{
|
||||
grub_uint64_t sb_size;
|
||||
struct grub_raid_super_1x *real_sb;
|
||||
|
||||
if (sb->major_version != 1)
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"Unsupported RAID version: %d",
|
||||
sb->major_version);
|
||||
|
||||
/* Multipath. */
|
||||
if ((int) sb->level == -4)
|
||||
sb->level = 1;
|
||||
|
||||
if (sb->level != 0 && sb->level != 1 && sb->level != 4 &&
|
||||
sb->level != 5 && sb->level != 6 && sb->level != 10)
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"Unsupported RAID level: %d", sb->level);
|
||||
|
||||
/* 1.x superblocks don't have a fixed size on disk. So we have to
|
||||
read it again now that we now the max device count. */
|
||||
sb_size = sizeof (struct grub_raid_super_1x) + 2 * grub_le_to_cpu32 (sb->max_dev);
|
||||
real_sb = grub_malloc (sb_size);
|
||||
if (! real_sb)
|
||||
return grub_errno;
|
||||
|
||||
if (grub_disk_read (disk, sector, 0, sb_size, real_sb))
|
||||
{
|
||||
grub_free (real_sb);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
array->name = grub_strdup (real_sb->set_name);
|
||||
if (! array->name)
|
||||
{
|
||||
grub_free (real_sb);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
array->number = 0;
|
||||
array->level = grub_le_to_cpu32 (real_sb->level);
|
||||
array->layout = grub_le_to_cpu32 (real_sb->layout);
|
||||
array->total_devs = grub_le_to_cpu32 (real_sb->raid_disks);
|
||||
array->disk_size = grub_le_to_cpu64 (real_sb->size);
|
||||
array->chunk_size = grub_le_to_cpu32 (real_sb->chunksize);
|
||||
if (grub_le_to_cpu32 (real_sb->dev_number) <
|
||||
grub_le_to_cpu32 (real_sb->max_dev))
|
||||
array->index = grub_le_to_cpu16
|
||||
(real_sb->dev_roles[grub_le_to_cpu32 (real_sb->dev_number)]);
|
||||
else
|
||||
array->index = 0xffff; /* disk will be later not used! */
|
||||
array->uuid_len = 16;
|
||||
array->uuid = grub_malloc (16);
|
||||
if (!array->uuid)
|
||||
{
|
||||
grub_free (real_sb);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
grub_memcpy (array->uuid, real_sb->set_uuid, 16);
|
||||
|
||||
*start_sector = real_sb->data_offset;
|
||||
|
||||
grub_free (real_sb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array,
|
||||
grub_disk_addr_t *start_sector)
|
||||
{
|
||||
grub_disk_addr_t sector;
|
||||
grub_uint64_t size;
|
||||
struct grub_raid_super_09 sb_09;
|
||||
struct grub_raid_super_1x sb_1x;
|
||||
grub_uint8_t minor_version;
|
||||
struct grub_raid_super_09 sb;
|
||||
grub_uint32_t *uuid;
|
||||
|
||||
/* The sector where the mdraid 0.90 superblock is stored, if available. */
|
||||
size = grub_disk_get_size (disk);
|
||||
sector = NEW_SIZE_SECTORS (size);
|
||||
|
||||
if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb_09))
|
||||
if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb))
|
||||
return grub_errno;
|
||||
|
||||
/* Look whether there is a mdraid 0.90 superblock. */
|
||||
if (sb_09.md_magic == SB_MAGIC)
|
||||
return grub_mdraid_detect_09 (sector, &sb_09, array, start_sector);
|
||||
if (sb.md_magic != SB_MAGIC)
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE, "not 0.9x raid");
|
||||
|
||||
/* Check for an 1.x superblock.
|
||||
* It's always aligned to a 4K boundary
|
||||
* and depending on the minor version it can be:
|
||||
* 0: At least 8K, but less than 12K, from end of device
|
||||
* 1: At start of device
|
||||
* 2: 4K from start of device.
|
||||
*/
|
||||
if (sb.major_version != 0 || sb.minor_version != 90)
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"unsupported RAID version: %d.%d",
|
||||
sb.major_version, sb.minor_version);
|
||||
|
||||
for (minor_version = 0; minor_version < 3; ++minor_version)
|
||||
{
|
||||
switch (minor_version)
|
||||
{
|
||||
case 0:
|
||||
sector = (size - 8 * 2) & ~(4 * 2 - 1);
|
||||
break;
|
||||
case 1:
|
||||
sector = 0;
|
||||
break;
|
||||
case 2:
|
||||
sector = 4 * 2;
|
||||
break;
|
||||
}
|
||||
/* FIXME: Check the checksum. */
|
||||
|
||||
if (grub_disk_read (disk, sector, 0, sizeof (struct grub_raid_super_1x),
|
||||
&sb_1x))
|
||||
return grub_errno;
|
||||
/* Multipath. */
|
||||
if ((int) sb.level == -4)
|
||||
sb.level = 1;
|
||||
|
||||
if (sb_1x.magic == SB_MAGIC)
|
||||
return grub_mdraid_detect_1x (disk, sector, &sb_1x, array,
|
||||
start_sector);
|
||||
}
|
||||
if (sb.level != 0 && sb.level != 1 && sb.level != 4 &&
|
||||
sb.level != 5 && sb.level != 6 && sb.level != 10)
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"unsupported RAID level: %d", sb.level);
|
||||
|
||||
/* Neither 0.90 nor 1.x. */
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid");
|
||||
array->name = NULL;
|
||||
array->number = sb.md_minor;
|
||||
array->level = sb.level;
|
||||
array->layout = sb.layout;
|
||||
array->total_devs = sb.raid_disks;
|
||||
array->disk_size = (sb.size) ? sb.size * 2 : sector;
|
||||
array->chunk_size = sb.chunk_size >> 9;
|
||||
array->index = sb.this_disk.number;
|
||||
array->uuid_len = 16;
|
||||
array->uuid = grub_malloc (16);
|
||||
if (!array->uuid)
|
||||
return grub_errno;
|
||||
|
||||
uuid = (grub_uint32_t *) array->uuid;
|
||||
uuid[0] = sb.set_uuid0;
|
||||
uuid[1] = sb.set_uuid1;
|
||||
uuid[2] = sb.set_uuid2;
|
||||
uuid[3] = sb.set_uuid3;
|
||||
|
||||
*start_sector = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct grub_raid grub_mdraid_dev = {
|
||||
.name = "mdraid",
|
||||
.name = "mdraid09",
|
||||
.detect = grub_mdraid_detect,
|
||||
.next = 0
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT (mdraid)
|
||||
GRUB_MOD_INIT (mdraid09)
|
||||
{
|
||||
grub_raid_register (&grub_mdraid_dev);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI (mdraid)
|
||||
GRUB_MOD_FINI (mdraid09)
|
||||
{
|
||||
grub_raid_unregister (&grub_mdraid_dev);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@ grub_memdisk_open (const char *name, grub_disk_t disk)
|
|||
|
||||
disk->total_sectors = memdisk_size / GRUB_DISK_SECTOR_SIZE;
|
||||
disk->id = (unsigned long) "mdsk";
|
||||
disk->has_partitions = 0;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
|
|
@ -126,7 +126,6 @@ grub_raid_open (const char *name, grub_disk_t disk)
|
|||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown RAID device %s",
|
||||
name);
|
||||
|
||||
disk->has_partitions = 1;
|
||||
disk->id = array->number;
|
||||
disk->data = array;
|
||||
|
||||
|
|
|
@ -431,12 +431,6 @@ grub_scsi_open (const char *name, grub_disk_t disk)
|
|||
"unknown SCSI device");
|
||||
}
|
||||
|
||||
if (scsi->devtype == grub_scsi_devtype_cdrom)
|
||||
disk->has_partitions = 0;
|
||||
else
|
||||
disk->has_partitions = 1;
|
||||
|
||||
|
||||
/* According to USB MS tests specification, issue Test Unit Ready
|
||||
* until OK */
|
||||
maxtime = grub_get_time_ms () + 5000; /* It is safer value */
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
#include <grub/normal.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/efiemu/efiemu.h>
|
||||
#include <grub/memory.h>
|
||||
|
||||
struct grub_efiemu_memrequest
|
||||
{
|
||||
|
@ -269,10 +269,11 @@ static grub_err_t
|
|||
grub_efiemu_mmap_init (void)
|
||||
{
|
||||
auto int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t, grub_uint64_t,
|
||||
grub_uint32_t);
|
||||
grub_memory_type_t);
|
||||
int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t addr __attribute__ ((unused)),
|
||||
grub_uint64_t size __attribute__ ((unused)),
|
||||
grub_uint32_t type __attribute__ ((unused)))
|
||||
grub_memory_type_t type
|
||||
__attribute__ ((unused)))
|
||||
{
|
||||
mmap_reserved_size++;
|
||||
return 0;
|
||||
|
@ -382,32 +383,29 @@ grub_efiemu_mm_init (void)
|
|||
static grub_err_t
|
||||
grub_efiemu_mmap_fill (void)
|
||||
{
|
||||
auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
||||
auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
|
||||
grub_memory_type_t);
|
||||
int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr,
|
||||
grub_uint64_t size,
|
||||
grub_uint32_t type)
|
||||
grub_memory_type_t type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GRUB_MACHINE_MEMORY_AVAILABLE:
|
||||
case GRUB_MEMORY_AVAILABLE:
|
||||
return grub_efiemu_add_to_mmap (addr, size,
|
||||
GRUB_EFI_CONVENTIONAL_MEMORY);
|
||||
|
||||
#ifdef GRUB_MACHINE_MEMORY_ACPI
|
||||
case GRUB_MACHINE_MEMORY_ACPI:
|
||||
case GRUB_MEMORY_ACPI:
|
||||
return grub_efiemu_add_to_mmap (addr, size,
|
||||
GRUB_EFI_ACPI_RECLAIM_MEMORY);
|
||||
#endif
|
||||
|
||||
#ifdef GRUB_MACHINE_MEMORY_NVS
|
||||
case GRUB_MACHINE_MEMORY_NVS:
|
||||
case GRUB_MEMORY_NVS:
|
||||
return grub_efiemu_add_to_mmap (addr, size,
|
||||
GRUB_EFI_ACPI_MEMORY_NVS);
|
||||
#endif
|
||||
|
||||
default:
|
||||
grub_printf ("Unknown memory type %d. Marking as unusable\n", type);
|
||||
case GRUB_MACHINE_MEMORY_RESERVED:
|
||||
grub_printf ("Unknown memory type %d. Assuming unusable\n", type);
|
||||
case GRUB_MEMORY_RESERVED:
|
||||
return grub_efiemu_add_to_mmap (addr, size,
|
||||
GRUB_EFI_UNUSABLE_MEMORY);
|
||||
}
|
||||
|
@ -421,9 +419,7 @@ grub_efiemu_mmap_fill (void)
|
|||
}
|
||||
|
||||
grub_err_t
|
||||
grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
||||
grub_uint64_t,
|
||||
grub_uint32_t))
|
||||
grub_efiemu_mmap_iterate (grub_memory_hook_t hook)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
|
@ -432,18 +428,22 @@ grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
|||
{
|
||||
case GRUB_EFI_RUNTIME_SERVICES_CODE:
|
||||
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
|
||||
GRUB_EFIEMU_MEMORY_CODE);
|
||||
GRUB_MEMORY_CODE);
|
||||
break;
|
||||
|
||||
case GRUB_EFI_UNUSABLE_MEMORY:
|
||||
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
|
||||
GRUB_MEMORY_BADRAM);
|
||||
break;
|
||||
|
||||
case GRUB_EFI_RESERVED_MEMORY_TYPE:
|
||||
case GRUB_EFI_RUNTIME_SERVICES_DATA:
|
||||
case GRUB_EFI_UNUSABLE_MEMORY:
|
||||
case GRUB_EFI_MEMORY_MAPPED_IO:
|
||||
case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
|
||||
case GRUB_EFI_PAL_CODE:
|
||||
case GRUB_EFI_MAX_MEMORY_TYPE:
|
||||
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
|
||||
GRUB_EFIEMU_MEMORY_RESERVED);
|
||||
GRUB_MEMORY_RESERVED);
|
||||
break;
|
||||
|
||||
case GRUB_EFI_LOADER_CODE:
|
||||
|
@ -452,17 +452,17 @@ grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
|
|||
case GRUB_EFI_BOOT_SERVICES_DATA:
|
||||
case GRUB_EFI_CONVENTIONAL_MEMORY:
|
||||
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
|
||||
GRUB_EFIEMU_MEMORY_AVAILABLE);
|
||||
GRUB_MEMORY_AVAILABLE);
|
||||
break;
|
||||
|
||||
case GRUB_EFI_ACPI_RECLAIM_MEMORY:
|
||||
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
|
||||
GRUB_EFIEMU_MEMORY_ACPI);
|
||||
GRUB_MEMORY_ACPI);
|
||||
break;
|
||||
|
||||
case GRUB_EFI_ACPI_MEMORY_NVS:
|
||||
hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
|
||||
GRUB_EFIEMU_MEMORY_NVS);
|
||||
GRUB_MEMORY_NVS);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
#include <grub/err.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/efiemu/efiemu.h>
|
||||
#include <grub/lib/crc.h>
|
||||
#include <grub/crypto.h>
|
||||
|
||||
grub_err_t
|
||||
SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks,
|
||||
|
@ -123,6 +123,7 @@ SUFFIX (grub_efiemu_crc) (void)
|
|||
int handle;
|
||||
grub_off_t off;
|
||||
struct SUFFIX (grub_efiemu_runtime_services) *runtime_services;
|
||||
grub_uint8_t crc32_context[GRUB_MD_CRC32->contextsize];
|
||||
|
||||
/* compute CRC32 of runtime_services */
|
||||
err = grub_efiemu_resolve_symbol ("efiemu_runtime_services",
|
||||
|
@ -132,19 +133,25 @@ SUFFIX (grub_efiemu_crc) (void)
|
|||
|
||||
runtime_services = (struct SUFFIX (grub_efiemu_runtime_services) *)
|
||||
((grub_uint8_t *) grub_efiemu_mm_obtain_request (handle) + off);
|
||||
runtime_services->hdr.crc32 = 0;
|
||||
runtime_services->hdr.crc32 = grub_getcrc32
|
||||
(0, runtime_services, runtime_services->hdr.header_size);
|
||||
|
||||
GRUB_MD_CRC32->init(crc32_context);
|
||||
GRUB_MD_CRC32->write(crc32_context, runtime_services, runtime_services->hdr.header_size);
|
||||
GRUB_MD_CRC32->final(crc32_context);
|
||||
|
||||
runtime_services->hdr.crc32 =
|
||||
grub_be_to_cpu32(*(grub_uint32_t*)GRUB_MD_CRC32->read(crc32_context));
|
||||
|
||||
err = grub_efiemu_resolve_symbol ("efiemu_system_table", &handle, &off);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* compute CRC32 of system table */
|
||||
SUFFIX (grub_efiemu_system_table)->hdr.crc32 = 0;
|
||||
SUFFIX (grub_efiemu_system_table)->hdr.crc32
|
||||
= grub_getcrc32 (0, SUFFIX (grub_efiemu_system_table),
|
||||
SUFFIX (grub_efiemu_system_table)->hdr.header_size);
|
||||
GRUB_MD_CRC32->init(crc32_context);
|
||||
GRUB_MD_CRC32->write(crc32_context, SUFFIX (grub_efiemu_system_table),
|
||||
SUFFIX (grub_efiemu_system_table)->hdr.header_size);
|
||||
GRUB_MD_CRC32->final(crc32_context);
|
||||
SUFFIX (grub_efiemu_system_table)->hdr.crc32 =
|
||||
grub_be_to_cpu32(*(grub_uint32_t*)GRUB_MD_CRC32->read(crc32_context));
|
||||
|
||||
grub_dprintf ("efiemu","system_table = %p, runtime_services = %p\n",
|
||||
SUFFIX (grub_efiemu_system_table), runtime_services);
|
||||
|
|
132
grub-core/fs/btrfs.c
Normal file
132
grub-core/fs/btrfs.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
/* btrfs.c - B-tree file system. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 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/err.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/types.h>
|
||||
|
||||
#define BTRFS_SIGNATURE "_BHRfS_M"
|
||||
|
||||
struct btrfs_superblock
|
||||
{
|
||||
grub_uint8_t dummy1[32];
|
||||
grub_uint16_t uuid[8];
|
||||
grub_uint8_t dummy2[16];
|
||||
grub_uint8_t signature[sizeof (BTRFS_SIGNATURE) - 1];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct grub_btrfs_data
|
||||
{
|
||||
struct btrfs_superblock sblock;
|
||||
};
|
||||
|
||||
static struct grub_btrfs_data *
|
||||
grub_btrfs_mount (grub_disk_t disk)
|
||||
{
|
||||
struct grub_btrfs_data *data = grub_malloc (sizeof (*data));
|
||||
if (! data)
|
||||
return NULL;
|
||||
|
||||
if (grub_disk_read (disk, 128, 0, sizeof (data->sblock),
|
||||
&data->sblock) != GRUB_ERR_NONE)
|
||||
goto fail;
|
||||
|
||||
if (grub_strncmp ((char *) data->sblock.signature, BTRFS_SIGNATURE, sizeof (BTRFS_SIGNATURE) - 1))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
fail:
|
||||
grub_free (data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_btrfs_open (struct grub_file *file __attribute__ ((unused)),
|
||||
const char *name __attribute__ ((unused)))
|
||||
{
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "only detection is supported for Btrfs");
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_btrfs_dir (grub_device_t device,
|
||||
const char *path __attribute__ ((unused)),
|
||||
int (*hook) (const char *filename,
|
||||
const struct grub_dirhook_info *info)
|
||||
__attribute__ ((unused)))
|
||||
{
|
||||
struct grub_btrfs_data *data = grub_btrfs_mount (device->disk);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
|
||||
grub_free (data);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_btrfs_uuid (grub_device_t device, char **uuid)
|
||||
{
|
||||
struct grub_btrfs_data *data;
|
||||
|
||||
*uuid = NULL;
|
||||
|
||||
data = grub_btrfs_mount (device->disk);
|
||||
if (! data)
|
||||
return grub_errno;
|
||||
|
||||
*uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
|
||||
grub_be_to_cpu16 (data->sblock.uuid[0]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[1]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[2]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[3]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[4]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[5]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[6]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[7]));
|
||||
|
||||
grub_free (data);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static struct grub_fs grub_btrfs_fs =
|
||||
{
|
||||
.name = "btrfs",
|
||||
.dir = grub_btrfs_dir,
|
||||
.open = grub_btrfs_open,
|
||||
.uuid = grub_btrfs_uuid,
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(btrfs)
|
||||
{
|
||||
grub_fs_register (&grub_btrfs_fs);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(btrfs)
|
||||
{
|
||||
grub_fs_unregister (&grub_btrfs_fs);
|
||||
}
|
|
@ -728,22 +728,27 @@ grub_ext2_open (struct grub_file *file, const char *name)
|
|||
{
|
||||
struct grub_ext2_data *data;
|
||||
struct grub_fshelp_node *fdiro = 0;
|
||||
grub_err_t err;
|
||||
|
||||
grub_dl_ref (my_mod);
|
||||
|
||||
data = grub_ext2_mount (file->device->disk);
|
||||
if (! data)
|
||||
goto fail;
|
||||
{
|
||||
err = grub_errno;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_ext2_iterate_dir,
|
||||
grub_ext2_read_symlink, GRUB_FSHELP_REG);
|
||||
if (grub_errno)
|
||||
err = grub_fshelp_find_file (name, &data->diropen, &fdiro,
|
||||
grub_ext2_iterate_dir,
|
||||
grub_ext2_read_symlink, GRUB_FSHELP_REG);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
if (! fdiro->inode_read)
|
||||
{
|
||||
grub_ext2_read_inode (data, fdiro->ino, &fdiro->inode);
|
||||
if (grub_errno)
|
||||
err = grub_ext2_read_inode (data, fdiro->ino, &fdiro->inode);
|
||||
if (err)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -763,7 +768,7 @@ grub_ext2_open (struct grub_file *file, const char *name)
|
|||
|
||||
grub_dl_unref (my_mod);
|
||||
|
||||
return grub_errno;
|
||||
return err;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
|
|
|
@ -25,10 +25,13 @@
|
|||
#include <grub/dl.h>
|
||||
#include <grub/types.h>
|
||||
|
||||
#ifdef MODE_MINIX2
|
||||
#define GRUB_MINIX_MAGIC 0x2468
|
||||
#define GRUB_MINIX_MAGIC_30 0x2478
|
||||
#else
|
||||
#define GRUB_MINIX_MAGIC 0x137F
|
||||
#define GRUB_MINIX2_MAGIC 0x2468
|
||||
#define GRUB_MINIX_MAGIC_30 0x138F
|
||||
#define GRUB_MINIX2_MAGIC_30 0x2478
|
||||
#endif
|
||||
#define GRUB_MINIX_BSIZE 1024U
|
||||
#define GRUB_MINIX_LOG2_BSIZE 1
|
||||
#define GRUB_MINIX_ROOT_INODE 1
|
||||
|
@ -38,20 +41,25 @@
|
|||
#define GRUB_MINIX_IFDIR 0040000U
|
||||
#define GRUB_MINIX_IFLNK 0120000U
|
||||
|
||||
#define GRUB_MINIX_INODE(data,field) (data->version == 1 ? \
|
||||
data->inode. field : data->inode2. field)
|
||||
#define GRUB_MINIX_INODE_ENDIAN(data,field,bits1,bits2) (data->version == 1 ? \
|
||||
grub_le_to_cpu##bits1 (data->inode.field) : \
|
||||
grub_le_to_cpu##bits2 (data->inode2.field))
|
||||
#define GRUB_MINIX_INODE_SIZE(data) GRUB_MINIX_INODE_ENDIAN (data,size,16,32)
|
||||
#define GRUB_MINIX_INODE_MODE(data) GRUB_MINIX_INODE_ENDIAN (data,mode,16,16)
|
||||
#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) GRUB_MINIX_INODE_ENDIAN \
|
||||
(data,dir_zones[blk],16,32)
|
||||
#define GRUB_MINIX_INODE_INDIR_ZONE(data) \
|
||||
GRUB_MINIX_INODE_ENDIAN (data,indir_zone,16,32)
|
||||
#define GRUB_MINIX_INODE_DINDIR_ZONE(data) \
|
||||
GRUB_MINIX_INODE_ENDIAN (data,double_indir_zone,16,32)
|
||||
#define GRUB_MINIX_INODE_BLKSZ(data) (data->version == 1 ? 2 : 4)
|
||||
#ifdef MODE_MINIX2
|
||||
typedef grub_uint32_t grub_minix_uintn_t;
|
||||
#define grub_minix_le_to_cpu_n grub_le_to_cpu32
|
||||
#else
|
||||
typedef grub_uint16_t grub_minix_uintn_t;
|
||||
#define grub_minix_le_to_cpu_n grub_le_to_cpu16
|
||||
#endif
|
||||
|
||||
#define GRUB_MINIX_INODE_BLKSZ(data) sizeof (grub_minix_uintn_t)
|
||||
|
||||
#define GRUB_MINIX_INODE_SIZE(data) (grub_minix_le_to_cpu_n (data->inode.size))
|
||||
#define GRUB_MINIX_INODE_MODE(data) (grub_le_to_cpu16 (data->inode.mode))
|
||||
#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) (grub_minix_le_to_cpu_n \
|
||||
(data->inode.dir_zones[blk]))
|
||||
#define GRUB_MINIX_INODE_INDIR_ZONE(data) (grub_minix_le_to_cpu_n \
|
||||
(data->inode.indir_zone))
|
||||
#define GRUB_MINIX_INODE_DINDIR_ZONE(data) (grub_minix_le_to_cpu_n \
|
||||
(data->inode.double_indir_zone))
|
||||
|
||||
#define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \
|
||||
+ grub_le_to_cpu16 (sblock->log2_zone_size))
|
||||
#define GRUB_MINIX_ZONESZ (GRUB_MINIX_BSIZE \
|
||||
|
@ -69,6 +77,7 @@ struct grub_minix_sblock
|
|||
grub_uint16_t magic;
|
||||
};
|
||||
|
||||
#ifndef MODE_MINIX2
|
||||
struct grub_minix_inode
|
||||
{
|
||||
grub_uint16_t mode;
|
||||
|
@ -82,7 +91,9 @@ struct grub_minix_inode
|
|||
grub_uint16_t double_indir_zone;
|
||||
};
|
||||
|
||||
struct grub_minix2_inode
|
||||
#else
|
||||
|
||||
struct grub_minix_inode
|
||||
{
|
||||
grub_uint16_t mode;
|
||||
grub_uint16_t nlinks;
|
||||
|
@ -99,16 +110,16 @@ struct grub_minix2_inode
|
|||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* Information about a "mounted" minix filesystem. */
|
||||
struct grub_minix_data
|
||||
{
|
||||
struct grub_minix_sblock sblock;
|
||||
struct grub_minix_inode inode;
|
||||
struct grub_minix2_inode inode2;
|
||||
int ino;
|
||||
int linknest;
|
||||
grub_disk_t disk;
|
||||
int version;
|
||||
int filename_size;
|
||||
};
|
||||
|
||||
|
@ -128,24 +139,12 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
|
|||
/* Read the block pointer in ZONE, on the offset NUM. */
|
||||
int grub_get_indir (int zone, int num)
|
||||
{
|
||||
if (data->version == 1)
|
||||
{
|
||||
grub_uint16_t indir16;
|
||||
grub_disk_read (data->disk,
|
||||
zone << GRUB_MINIX_LOG2_ZONESZ,
|
||||
sizeof (grub_uint16_t) * num,
|
||||
sizeof (grub_uint16_t), (char *) &indir16);
|
||||
return grub_le_to_cpu16 (indir16);
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_uint32_t indir32;
|
||||
grub_disk_read (data->disk,
|
||||
zone << GRUB_MINIX_LOG2_ZONESZ,
|
||||
sizeof (grub_uint32_t) * num,
|
||||
sizeof (grub_uint32_t), (char *) &indir32);
|
||||
return grub_le_to_cpu32 (indir32);
|
||||
}
|
||||
grub_minix_uintn_t indirn;
|
||||
grub_disk_read (data->disk,
|
||||
zone << GRUB_MINIX_LOG2_ZONESZ,
|
||||
sizeof (grub_minix_uintn_t) * num,
|
||||
sizeof (grub_minix_uintn_t), (char *) &indirn);
|
||||
return grub_minix_le_to_cpu_n (indirn);
|
||||
}
|
||||
|
||||
/* Direct block. */
|
||||
|
@ -259,27 +258,13 @@ grub_minix_read_inode (struct grub_minix_data *data, int ino)
|
|||
+ grub_le_to_cpu16 (sblock->zone_bmap_size))
|
||||
<< GRUB_MINIX_LOG2_BSIZE);
|
||||
|
||||
if (data->version == 1)
|
||||
{
|
||||
block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
|
||||
int offs = (ino % (GRUB_DISK_SECTOR_SIZE
|
||||
/ sizeof (struct grub_minix_inode))
|
||||
* sizeof (struct grub_minix_inode));
|
||||
|
||||
grub_disk_read (data->disk, block, offs,
|
||||
sizeof (struct grub_minix_inode), &data->inode);
|
||||
}
|
||||
else
|
||||
{
|
||||
block += ino / (GRUB_DISK_SECTOR_SIZE
|
||||
/ sizeof (struct grub_minix2_inode));
|
||||
int offs = (ino
|
||||
% (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix2_inode))
|
||||
* sizeof (struct grub_minix2_inode));
|
||||
|
||||
grub_disk_read (data->disk, block, offs,
|
||||
sizeof (struct grub_minix2_inode),&data->inode2);
|
||||
}
|
||||
block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
|
||||
int offs = (ino % (GRUB_DISK_SECTOR_SIZE
|
||||
/ sizeof (struct grub_minix_inode))
|
||||
* sizeof (struct grub_minix_inode));
|
||||
|
||||
grub_disk_read (data->disk, block, offs,
|
||||
sizeof (struct grub_minix_inode), &data->inode);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
@ -424,25 +409,9 @@ grub_minix_mount (grub_disk_t disk)
|
|||
goto fail;
|
||||
|
||||
if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC)
|
||||
{
|
||||
data->version = 1;
|
||||
data->filename_size = 14;
|
||||
}
|
||||
else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC)
|
||||
{
|
||||
data->version = 2;
|
||||
data->filename_size = 14;
|
||||
}
|
||||
data->filename_size = 14;
|
||||
else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC_30)
|
||||
{
|
||||
data->version = 1;
|
||||
data->filename_size = 30;
|
||||
}
|
||||
else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC_30)
|
||||
{
|
||||
data->version = 2;
|
||||
data->filename_size = 30;
|
||||
}
|
||||
data->filename_size = 30;
|
||||
else
|
||||
goto fail;
|
||||
|
||||
|
@ -453,7 +422,11 @@ grub_minix_mount (grub_disk_t disk)
|
|||
|
||||
fail:
|
||||
grub_free (data);
|
||||
#ifdef MODE_MINIX2
|
||||
grub_error (GRUB_ERR_BAD_FS, "not a minix2 filesystem");
|
||||
#else
|
||||
grub_error (GRUB_ERR_BAD_FS, "not a minix filesystem");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -583,32 +556,36 @@ grub_minix_close (grub_file_t file)
|
|||
}
|
||||
|
||||
|
||||
static grub_err_t
|
||||
grub_minix_label (grub_device_t device __attribute ((unused)),
|
||||
char **label __attribute ((unused)))
|
||||
{
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
static struct grub_fs grub_minix_fs =
|
||||
{
|
||||
#ifdef MODE_MINIX2
|
||||
.name = "minix2",
|
||||
#else
|
||||
.name = "minix",
|
||||
#endif
|
||||
.dir = grub_minix_dir,
|
||||
.open = grub_minix_open,
|
||||
.read = grub_minix_read,
|
||||
.close = grub_minix_close,
|
||||
.label = grub_minix_label,
|
||||
.next = 0
|
||||
};
|
||||
|
||||
#ifdef MODE_MINIX2
|
||||
GRUB_MOD_INIT(minix2)
|
||||
#else
|
||||
GRUB_MOD_INIT(minix)
|
||||
#endif
|
||||
{
|
||||
grub_fs_register (&grub_minix_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
|
||||
#ifdef MODE_MINIX2
|
||||
GRUB_MOD_FINI(minix2)
|
||||
#else
|
||||
GRUB_MOD_FINI(minix)
|
||||
#endif
|
||||
{
|
||||
grub_fs_unregister (&grub_minix_fs);
|
||||
}
|
||||
|
|
2
grub-core/fs/minix2.c
Normal file
2
grub-core/fs/minix2.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define MODE_MINIX2 1
|
||||
#include "minix.c"
|
|
@ -1,22 +0,0 @@
|
|||
#! /bin/sh
|
||||
#
|
||||
# Copyright (C) 2005,2009 Free Software Foundation, Inc.
|
||||
#
|
||||
# This gensymlist.sh is free software; the author
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
# Read source code from stdin and detect command names.
|
||||
|
||||
module=$1
|
||||
|
||||
grep -v "^#" | sed -n \
|
||||
-e "/grub_register_command *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $module/;p;}" \
|
||||
-e "/grub_register_extcmd *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $module/;p;}" \
|
||||
-e "/grub_register_command_p1 *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $module/;p;}"
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue