merge mainline into gingold3
This commit is contained in:
commit
774b7ca021
320 changed files with 18661 additions and 6490 deletions
22
.bzrignore
22
.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
|
||||
|
@ -91,7 +101,13 @@ texinfo.tex
|
|||
grub-core/lib/libgcrypt-grub
|
||||
**/.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
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
2008-01-28 Tristan Gingold <gingold@free.fr>
|
||||
2010-01-18 Robert Millan <rmh.grub@aybabtu.com>
|
||||
2010-08-31 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* commands/lsacpi.c: New file.
|
||||
* grub-core/Makefile.core.def (lsacpi): New module.
|
||||
* include/grub/acpi.h (GRUB_ACPI_FADT_SIGNATURE): New definition.
|
||||
(GRUB_ACPI_MADT_SIGNATURE): Likewise.
|
||||
(grub_acpi_madt_entry_header): New struct.
|
||||
(grub_acpi_madt): Likewise.
|
||||
(grub_acpi_madt_entry_interrupt_override): Likewise.
|
||||
(grub_acpi_madt_entry_sapic): Likewise.
|
||||
(grub_acpi_madt_entry_lsapic): Likewise.
|
||||
(grub_acpi_madt_entry_platform_int_source): Likewise.
|
||||
* include/grub/types.h (PRIxGRUB_UINT32_T): New definition.
|
||||
(PRIuGRUB_UINT32_T): Likewise.
|
||||
(PRIxGRUB_UINT64_T): Likewise.
|
|
@ -1,18 +0,0 @@
|
|||
2008-01-28 Tristan Gingold <gingold@free.fr>
|
||||
2010-01-18 Robert Millan <rmh.grub@aybabtu.com>
|
||||
2010-08-31 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/commands/efi/lsefisystab.c: New file.
|
||||
* grub-core/commands/efi/lssal.c: Likewise.
|
||||
* grub-core/Makefile.core.def (lsacpi): New module.
|
||||
(lsefisystab): Likewise.
|
||||
* include/grub/efi/api.h (GRUB_EFI_SAL_TABLE_GUID): New definition.
|
||||
(GRUB_EFI_HCDP_TABLE_GUID): Likewise.
|
||||
(grub_efi_sal_system_table): New struct.
|
||||
(grub_efi_sal_system_table_entrypoint_descriptor): Likewise.
|
||||
(grub_efi_sal_system_table_memory_descriptor): Likewise.
|
||||
(grub_efi_sal_system_table_platform_features): Likewise.
|
||||
(grub_efi_sal_system_table_translation_register_descriptor): Likewise.
|
||||
(grub_efi_sal_system_table_purge_translation_coherence): Likewise.
|
||||
(grub_efi_sal_system_table_ap_wakeup): Likewise.
|
||||
* include/grub/types.h (PRIuGRUB_UINT64_T): New definition.
|
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:
|
||||
|
||||
|
|
22
Makefile.am
22
Makefile.am
|
@ -1,7 +1,7 @@
|
|||
AUTOMAKE_OPTIONS = subdir-objects
|
||||
|
||||
DEPDIR = .deps-util
|
||||
SUBDIRS = . grub-core po docs
|
||||
SUBDIRS = . grub-core po docs util/bash-completion.d
|
||||
|
||||
include $(top_srcdir)/conf/Makefile.common
|
||||
include $(top_srcdir)/conf/Makefile.extra-dist
|
||||
|
@ -44,9 +44,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 +76,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
|
||||
|
|
|
@ -23,7 +23,6 @@ library = {
|
|||
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;
|
||||
|
||||
|
@ -31,7 +30,6 @@ library = {
|
|||
common = grub-core/commands/extcmd.c;
|
||||
common = grub-core/commands/ls.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;
|
||||
|
@ -43,6 +41,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;
|
||||
|
@ -52,6 +51,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;
|
||||
|
@ -72,11 +72,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;
|
||||
|
@ -88,6 +88,7 @@ library = {
|
|||
common = grub-core/partmap/gpt.c;
|
||||
common = grub-core/partmap/msdos.c;
|
||||
common = grub-core/partmap/sun.c;
|
||||
common = grub-core/partmap/sunpc.c;
|
||||
common = grub-core/script/function.c;
|
||||
common = grub-core/script/lexer.c;
|
||||
common = grub-core/script/main.c;
|
||||
|
@ -178,11 +179,15 @@ program = {
|
|||
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;
|
||||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||
condition = COND_GRUB_FSTEST;
|
||||
cflags = '$(CFLAGS_GCRY)';
|
||||
cppflags = '$(CPPFLAGS_GCRY)';
|
||||
};
|
||||
|
||||
program = {
|
||||
|
@ -229,14 +234,11 @@ 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)';
|
||||
|
@ -256,6 +258,16 @@ program = {
|
|||
enable = sparc64_ieee1275;
|
||||
};
|
||||
|
||||
program = {
|
||||
name = grub-mklayout;
|
||||
mansection = 1;
|
||||
|
||||
common = util/grub-mklayout.c;
|
||||
|
||||
ldadd = libgrub.a;
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER)';
|
||||
};
|
||||
|
||||
data = {
|
||||
common = util/grub.d/README;
|
||||
installdir = grubconf;
|
||||
|
@ -345,20 +357,18 @@ 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;
|
||||
};
|
||||
|
||||
script = {
|
||||
mansection = 8;
|
||||
installdir = sbin;
|
||||
name = grub-mknetdir;
|
||||
|
||||
common = util/grub-mknetdir.in;
|
||||
};
|
||||
|
||||
script = {
|
||||
name = grub-mkconfig;
|
||||
common = util/grub-mkconfig.in;
|
||||
|
@ -392,6 +402,11 @@ script = {
|
|||
installdir = noinst;
|
||||
};
|
||||
|
||||
script = {
|
||||
name = grub-kbdcomp;
|
||||
common = util/grub-kbdcomp.in;
|
||||
};
|
||||
|
||||
script = {
|
||||
name = grub-shell;
|
||||
common = tests/util/grub-shell.in;
|
||||
|
@ -500,6 +515,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;
|
||||
|
@ -512,3 +575,14 @@ 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)';
|
||||
};
|
||||
|
|
89
NEWS
89
NEWS
|
@ -1,9 +1,98 @@
|
|||
New in 1.99:
|
||||
|
||||
* New relocator. Allows for more kernel support and more
|
||||
straightforward loader writing.
|
||||
|
||||
* Handle USB pendrives exposed as floppies.
|
||||
|
||||
* New Automake-based build system.
|
||||
|
||||
* Add `sendkey' command (i386-pc only).
|
||||
|
||||
* ZFS support in `grub-install' and `grub-mkconfig'. Note: complete
|
||||
functionality requires external ZFS implementation (available from
|
||||
grub-extras).
|
||||
|
||||
* Support 1.x versions of mdadm metadata.
|
||||
|
||||
* Fix corruption when reading Reiserfs directory entries.
|
||||
|
||||
* Bidirectional text and diacritics support.
|
||||
|
||||
* Skip LVM snapshots.
|
||||
|
||||
* MIPS Yeeloong firmware port.
|
||||
|
||||
* Change grub-mkdevicemap to emit /dev/disk/by-id/ names where possible
|
||||
on GNU/Linux.
|
||||
|
||||
* Add `grub-mkconfig' support for Xen with Linux.
|
||||
|
||||
* Add `grub-mkconfig' support for initrd images on Fedora 13.
|
||||
|
||||
* Support >3GiB and <16MiB RAM in i386-qemu.
|
||||
|
||||
* Add support for Cirrus 5446 and Bochs video cards.
|
||||
|
||||
* Load more appropriate video drivers automatically in `grub-mkconfig'.
|
||||
|
||||
* USB improvements, including hotplugging/hotunplugging, hub support,
|
||||
and USB serial support.
|
||||
|
||||
* AMD Geode CS5536 support.
|
||||
|
||||
* Extensive updates to the Texinfo documentation.
|
||||
|
||||
* Add `grub-probe' support for the btrfs filesystem, permitting / to
|
||||
reside on btrfs as long as /boot is on a filesystem natively supported
|
||||
by GRUB.
|
||||
|
||||
* Handle symbolic links under /dev/mapper on GNU/Linux.
|
||||
|
||||
* Handle installation across multiple partition table types.
|
||||
|
||||
* Add `cmostest' command (i386/x86_64 only).
|
||||
|
||||
* Add support for DM-RAID disk devices on GNU/Linux.
|
||||
|
||||
* Remove `grub-mkisofs'. `grub-mkrescue' now uses GNU xorriso to build
|
||||
CD images.
|
||||
|
||||
* `grub-mkrescue' support for EFI, coreboot, and QEMU platforms.
|
||||
|
||||
* Unify `grub-mkimage' source code across platforms.
|
||||
|
||||
* Fix VGA (as opposed to VBE) video driver, formerly a terminal driver.
|
||||
|
||||
* Add menu hotkey support.
|
||||
|
||||
* Add support for the nilfs2 filesystem.
|
||||
|
||||
* `grub-probe' and `grub-mkconfig' support for NetBSD.
|
||||
|
||||
* Support setting a background image in `grub-mkconfig'.
|
||||
|
||||
* Support multiple terminals in `grub-mkconfig'.
|
||||
|
||||
* Regexp support.
|
||||
|
||||
* MIPS multiboot2 support.
|
||||
|
||||
* Multiboot2 tag support.
|
||||
|
||||
* sunpc partition table support.
|
||||
|
||||
* Add a number of new language features to GRUB script: `for', `while',
|
||||
`until', `elif', function parameters, `break', `continue', and
|
||||
`shift'.
|
||||
|
||||
* Support nested partition tables. GRUB now prefers to name partitions
|
||||
in the form `(hd0,msdos1,bsd1)' rather than `(hd0,1,a)'.
|
||||
|
||||
* Speed up consecutive hostdisk operations on the same device.
|
||||
|
||||
* Compile parts of `grub-emu' as modules.
|
||||
|
||||
New in 1.98 - 2010-03-06:
|
||||
|
||||
* Multiboot on EFI support.
|
||||
|
|
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*
|
||||
|
|
|
@ -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
|
||||
|
||||
|
@ -83,20 +88,26 @@ 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,14 @@ 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')
|
||||
|
|
38
config.h.in
Normal file
38
config.h.in
Normal file
|
@ -0,0 +1,38 @@
|
|||
#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@"
|
||||
/* 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
|
123
configure.ac
123
configure.ac
|
@ -44,7 +44,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 +164,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 +176,19 @@ 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)
|
||||
|
||||
grubdirname=`echo "$PACKAGE" | sed "$program_transform_name"`
|
||||
AC_SUBST(grubdirname)
|
||||
|
||||
#
|
||||
# Checks for build programs.
|
||||
#
|
||||
|
@ -264,8 +277,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.
|
||||
|
@ -410,10 +431,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 +589,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 +688,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 +773,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 +786,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 +820,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 +851,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 +888,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 +902,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
|
||||
|
@ -918,7 +929,9 @@ AC_CONFIG_FILES([Makefile])
|
|||
AC_CONFIG_FILES([grub-core/Makefile])
|
||||
AC_CONFIG_FILES([po/Makefile])
|
||||
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 +955,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 +970,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
|
||||
|
|
432
docs/grub.texi
432
docs/grub.texi
|
@ -46,6 +46,8 @@ Invariant Sections.
|
|||
@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}.
|
||||
@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
|
||||
|
@ -77,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
|
||||
|
@ -964,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
|
||||
|
||||
|
||||
|
@ -1126,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,
|
||||
|
@ -1226,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
|
||||
|
||||
|
@ -1239,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
|
||||
|
||||
|
@ -1304,6 +1311,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
|
||||
|
@ -1372,9 +1418,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
|
||||
|
@ -2006,8 +2415,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
|
||||
|
||||
|
||||
|
@ -2498,7 +2906,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():
|
||||
|
|
|
@ -74,9 +74,10 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
|
|||
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/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
|
||||
|
@ -92,24 +93,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
|
||||
|
@ -122,8 +119,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
|
||||
|
@ -132,19 +129,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
|
||||
|
@ -178,13 +173,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
|
||||
|
@ -204,61 +205,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 = {
|
||||
|
@ -394,6 +405,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)';
|
||||
|
@ -458,6 +470,7 @@ module = {
|
|||
name = boot;
|
||||
common = commands/boot.c;
|
||||
i386_pc = lib/i386/pc/biosnum.c;
|
||||
enable = videomodules;
|
||||
};
|
||||
|
||||
module = {
|
||||
|
@ -481,12 +494,6 @@ module = {
|
|||
enable = x86;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = crc;
|
||||
common = commands/crc.c;
|
||||
common = lib/crc.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = date;
|
||||
common = commands/date.c;
|
||||
|
@ -526,6 +533,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;
|
||||
|
@ -706,15 +717,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 = {
|
||||
|
@ -868,6 +872,11 @@ module = {
|
|||
common = fs/befs_be.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = btrfs;
|
||||
common = fs/btrfs.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = cpio;
|
||||
common = fs/cpio.c;
|
||||
|
@ -913,6 +922,11 @@ module = {
|
|||
common = fs/minix.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = minix2;
|
||||
common = fs/minix2.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = nilfs2;
|
||||
common = fs/nilfs2.c;
|
||||
|
@ -1044,6 +1058,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;
|
||||
|
@ -1119,6 +1136,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;
|
||||
|
@ -1195,6 +1213,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;
|
||||
|
@ -1411,3 +1431,43 @@ module = {
|
|||
name = datehook;
|
||||
common = hook/datehook.c;
|
||||
};
|
||||
|
||||
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. */
|
||||
|
@ -704,20 +701,22 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
break;
|
||||
|
||||
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;
|
||||
transfer->controller_data = cdata;
|
||||
|
||||
/* 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;
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
if ((intstatus & 0x10) != 0)
|
||||
{ /* Unrecoverable error - only reset can help...! */
|
||||
err_unrec = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Detected a HALT. */
|
||||
if (err_halt || (grub_le_to_cpu32 (ed_virt->td_head) & 1))
|
||||
static void
|
||||
pre_finish_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer)
|
||||
{
|
||||
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);
|
||||
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,63 +888,70 @@ 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 */
|
||||
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 */
|
||||
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 */
|
||||
|
||||
/* 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 */
|
||||
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 )
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys);
|
||||
/* Set index of last processed TD */
|
||||
if (tderr_virt)
|
||||
{
|
||||
|
@ -1031,7 +963,7 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
|
||||
/* Evaluation of error code */
|
||||
grub_dprintf ("ohci", "OHCI tderr_phys=0x%02x, errcode=0x%02x\n",
|
||||
tderr_phys, errcode);
|
||||
cdata->tderr_phys, errcode);
|
||||
switch (errcode)
|
||||
{
|
||||
case 0:
|
||||
|
@ -1090,6 +1022,7 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
- (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:
|
||||
|
@ -1117,13 +1050,53 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
break;
|
||||
}
|
||||
|
||||
finish_transfer (dev, transfer);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
else if (err_unrec)
|
||||
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 */
|
||||
err = GRUB_USB_ERR_UNRECOVERABLE;
|
||||
grub_dprintf("ohci", "Unrecoverable error!");
|
||||
|
||||
/* Do OHCI reset in case of unrecoverable error - maybe we will need
|
||||
|
@ -1151,12 +1124,58 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
(2 << 6)
|
||||
| GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE
|
||||
| GRUB_OHCI_REG_CONTROL_BULK_ENABLE );
|
||||
finish_transfer (dev, transfer);
|
||||
|
||||
return GRUB_USB_ERR_UNRECOVERABLE;
|
||||
}
|
||||
|
||||
else if (err_timeout)
|
||||
static grub_usb_err_t
|
||||
grub_ohci_check_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
grub_size_t *actual)
|
||||
{
|
||||
/* In case of timeout do not detect error from TD */
|
||||
err = GRUB_ERR_TIMEOUT;
|
||||
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);
|
||||
}
|
||||
|
||||
return GRUB_USB_ERR_WAIT;
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -1166,50 +1185,24 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
/* 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);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
finish_transfer (dev, transfer);
|
||||
|
||||
/* 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 */
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
grub_dprintf ("ohci", "OHCI finished, freeing, err=0x%02x, errcode=0x%02x\n",
|
||||
err, errcode);
|
||||
grub_ohci_free_tds (o, td_head_virt);
|
||||
|
||||
return err;
|
||||
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 */
|
||||
/* 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);
|
||||
grub_millisleep (50); /* For root hub should be nominaly 50ms */
|
||||
|
||||
/* End the reset signaling. */
|
||||
/* 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_millisleep (10);
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
|
||||
}
|
||||
|
||||
/* Enable the port and wait for it. */
|
||||
/* 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));
|
||||
|
||||
|
@ -1280,7 +1290,15 @@ 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);
|
||||
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
|
||||
|
|
|
@ -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)
|
||||
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 (;;)
|
||||
{
|
||||
grub_uhci_td_t errtd;
|
||||
transfer->controller_data = cdata;
|
||||
|
||||
errtd = (grub_uhci_td_t) (grub_addr_t) (qh->elinkptr & ~0x0f);
|
||||
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 (qh->elinkptr & 1)
|
||||
break;
|
||||
if (cdata->qh->elinkptr & 1)
|
||||
{
|
||||
grub_dprintf ("uhci", "transaction complete\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 GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
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;
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fall through, no errors occurred, so the QH might be
|
||||
updated. */
|
||||
grub_dprintf ("uhci", "transaction fallthrough\n");
|
||||
|
||||
if (grub_get_time_ms () > endtime)
|
||||
return GRUB_USB_ERR_WAIT;
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_uhci_cancel_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer)
|
||||
{
|
||||
err = GRUB_USB_ERR_STALL;
|
||||
grub_dprintf ("uhci", "transaction timed out\n");
|
||||
goto fail;
|
||||
}
|
||||
grub_cpu_idle ();
|
||||
}
|
||||
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 complete\n");
|
||||
|
||||
fail:
|
||||
|
||||
if (err != GRUB_USB_ERR_NONE)
|
||||
grub_dprintf ("uhci", "transaction failed\n");
|
||||
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_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;
|
||||
}
|
||||
/* 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,12 +264,15 @@ grub_usb_root_hub (grub_usb_controller_t controller)
|
|||
for (i = 0; i < hub->nports; i++)
|
||||
{
|
||||
grub_usb_speed_t speed;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -361,14 +311,37 @@ poll_nonroot_hub (grub_usb_device_t dev)
|
|||
{
|
||||
grub_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))
|
||||
if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)
|
||||
{
|
||||
grub_usb_speed_t speed;
|
||||
|
||||
/* Determine the device speed. */
|
||||
if (status & GRUB_USB_HUB_STATUS_LOWSPEED)
|
||||
speed = GRUB_USB_SPEED_LOW;
|
||||
else
|
||||
/* 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++)
|
||||
{
|
||||
if (status & GRUB_USB_HUB_STATUS_HIGHSPEED)
|
||||
speed = GRUB_USB_SPEED_HIGH;
|
||||
else
|
||||
speed = GRUB_USB_SPEED_FULL;
|
||||
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;
|
||||
|
||||
/* A device is actually connected to this port.
|
||||
* Now do reset of port. */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
/* 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);
|
||||
/* If the Hub does not cooperate for this port, just skip
|
||||
the port. */
|
||||
if (err)
|
||||
continue;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for reset procedure done */
|
||||
timeout = grub_get_time_ms () + 1000;
|
||||
do
|
||||
if (status & GRUB_USB_HUB_STATUS_C_PORT_RESET)
|
||||
{
|
||||
/* Get the port status. */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_GET_STATUS,
|
||||
0, i, sizeof (status), (char *) &status);
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_PORT_RESET, i, 0, 0);
|
||||
|
||||
if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)
|
||||
{
|
||||
grub_usb_speed_t speed;
|
||||
grub_usb_device_t next_dev;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
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,6 +522,10 @@ grub_usb_poll_devices (void)
|
|||
}
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
rescan = 0;
|
||||
|
||||
/* We should check changes of non-root hubs too. */
|
||||
for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++)
|
||||
{
|
||||
|
@ -500,6 +534,10 @@ grub_usb_poll_devices (void)
|
|||
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,
|
||||
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 timeout,
|
||||
grub_size_t *actual)
|
||||
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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 (grub_arg_parse (ext, argc, args, state, &new_args, &new_argc))
|
||||
if (! ext->options)
|
||||
{
|
||||
ext->state = state;
|
||||
ret = (ext->func) (ext, new_argc, new_args);
|
||||
grub_free (new_args);
|
||||
}
|
||||
else
|
||||
ret = grub_errno;
|
||||
|
||||
grub_free (state);
|
||||
|
||||
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))
|
||||
{
|
||||
context.state = state;
|
||||
ret = (ext->func) (&context, new_argc, new_args);
|
||||
grub_free (new_args);
|
||||
grub_free (state);
|
||||
return ret;
|
||||
}
|
||||
|
||||
grub_free (state);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
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,
|
||||
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)
|
||||
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}
|
||||
};
|
||||
|
||||
|
@ -40,6 +41,7 @@ struct { const char *name; const char *hashname; } aliases[] =
|
|||
{"sha256sum", "sha256"},
|
||||
{"sha512sum", "sha512"},
|
||||
{"md5sum", "md5"},
|
||||
{"crc", "crc32"},
|
||||
};
|
||||
|
||||
static inline int
|
||||
|
@ -80,7 +82,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 +117,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
|
||||
{
|
||||
if (!uncompress)
|
||||
grub_file_filter_disable_compression ();
|
||||
file = grub_file_open (p);
|
||||
}
|
||||
if (!file)
|
||||
{
|
||||
grub_file_close (hashlist);
|
||||
|
@ -165,19 +173,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 +206,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 +215,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 +249,32 @@ 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_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.",
|
||||
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_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum, 0,
|
||||
N_("[-c FILE [-p PREFIX]] "
|
||||
"[FILE1 [FILE2 ...]]"),
|
||||
"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."),
|
||||
|
@ -274,4 +287,5 @@ GRUB_MOD_FINI(hashsum)
|
|||
grub_unregister_extcmd (cmd_md5);
|
||||
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);
|
||||
|
|
781
grub-core/commands/legacycfg.c
Normal file
781
grub-core/commands/legacycfg.c
Normal file
|
@ -0,0 +1,781 @@
|
|||
/*
|
||||
* 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);
|
||||
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);
|
||||
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 __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
|
||||
return legacy_file (args[0]);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_legacy_configfile (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char **args)
|
||||
{
|
||||
grub_err_t ret;
|
||||
if (argc != 1)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
|
||||
|
||||
grub_cls ();
|
||||
grub_env_context_open (1);
|
||||
|
||||
ret = legacy_file (args[0]);
|
||||
grub_env_context_close ();
|
||||
|
||||
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, cmd_kernel, cmd_initrd;
|
||||
static grub_command_t cmd_password, cmd_check_password, cmd_initrdnounzip;
|
||||
|
||||
GRUB_MOD_INIT(legacycfg)
|
||||
{
|
||||
cmd_source = grub_register_command ("legacy_source",
|
||||
grub_cmd_legacy_source,
|
||||
N_("FILE"), N_("Parse legacy config"));
|
||||
cmd_configfile = grub_register_command ("legacy_configfile",
|
||||
grub_cmd_legacy_configfile,
|
||||
N_("FILE"),
|
||||
N_("Parse legacy config"));
|
||||
|
||||
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_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);
|
||||
|
|
|
@ -105,6 +105,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)
|
||||
{
|
||||
|
@ -211,6 +212,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;
|
||||
|
@ -248,14 +250,16 @@ 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,
|
||||
for (i = 0; i < argc; i++)
|
||||
grub_ls_list_files (args[i], state[0].set, state[2].set,
|
||||
state[1].set);
|
||||
|
||||
return 0;
|
||||
|
@ -265,8 +269,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);
|
||||
}
|
||||
|
||||
|
|
|
@ -196,10 +196,11 @@ static const struct grub_arg_option options[] = {
|
|||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_lsacpi (struct grub_extcmd *cmd, int argc __attribute__ ((unused)),
|
||||
grub_cmd_lsacpi (struct grub_extcmd_context *ctxt,
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
if (!cmd->state[1].set)
|
||||
if (!ctxt->state[1].set)
|
||||
{
|
||||
struct grub_acpi_rsdp_v10 *rsdp1 = grub_acpi_get_rsdpv1 ();
|
||||
if (!rsdp1)
|
||||
|
@ -212,7 +213,7 @@ grub_cmd_lsacpi (struct grub_extcmd *cmd, int argc __attribute__ ((unused)),
|
|||
}
|
||||
}
|
||||
|
||||
if (!cmd->state[0].set)
|
||||
if (!ctxt->state[0].set)
|
||||
{
|
||||
struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 ();
|
||||
if (!rsdp2)
|
||||
|
@ -237,8 +238,7 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(lsapi)
|
||||
{
|
||||
cmd = grub_register_extcmd ("lsacpi", grub_cmd_lsacpi, GRUB_COMMAND_FLAG_BOTH,
|
||||
N_("[-1|-2]"),
|
||||
cmd = grub_register_extcmd ("lsacpi", grub_cmd_lsacpi, 0, N_("[-1|-2]"),
|
||||
N_("Show ACPI information."), options);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,22 +16,37 @@
|
|||
* 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)
|
||||
{
|
||||
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;
|
||||
|
|
|
@ -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,
|
||||
|
|
299
grub-core/commands/menuentry.c
Normal file
299
grub-core/commands/menuentry.c
Normal file
|
@ -0,0 +1,299 @@
|
|||
/* 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)
|
||||
{
|
||||
unsigned i;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
menu->size++;
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
fail:
|
||||
|
||||
grub_free (menu_sourcecode);
|
||||
for (i = 0; menu_classes && menu_classes[i].name; i++)
|
||||
grub_free (menu_classes[i].name);
|
||||
grub_free (menu_classes);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
src[len - 1] = ch;
|
||||
args[argc - 1] = src;
|
||||
grub_free (prefix);
|
||||
return r;
|
||||
}
|
||||
|
||||
static grub_extcmd_t cmd;
|
||||
|
||||
void
|
||||
grub_menu_init (void)
|
||||
{
|
||||
cmd = grub_register_extcmd ("menuentry", grub_cmd_menuentry,
|
||||
GRUB_COMMAND_FLAG_BLOCKS,
|
||||
N_("BLOCK"), N_("Define a menuentry."), options);
|
||||
}
|
||||
|
||||
void
|
||||
grub_menu_fini (void)
|
||||
{
|
||||
grub_unregister_extcmd (cmd);
|
||||
}
|
|
@ -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, 0,
|
||||
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)
|
||||
|
|
155
grub-core/commands/testload.c
Normal file
155
grub-core/commands/testload.c
Normal file
|
@ -0,0 +1,155 @@
|
|||
/* minicmd.c - commands for the rescue mode */
|
||||
/*
|
||||
* 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:
|
||||
|
|
|
@ -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,61 +65,126 @@ 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;
|
||||
|
||||
p = grub_malloc(sizeof (*p));
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
if (p)
|
||||
{
|
||||
p->devpath = devpath;
|
||||
p->next = *head;
|
||||
p->shortest = 0;
|
||||
*head = p;
|
||||
}
|
||||
|
||||
curcan = grub_ieee1275_canonicalise_devname (devpath);
|
||||
if (!curcan)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return p;
|
||||
}
|
||||
|
||||
static int
|
||||
grub_ofdisk_iterate (int (*hook) (const char *name))
|
||||
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 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);
|
||||
|
||||
op = ofdisk_hash_find (alias->path);
|
||||
if (!op)
|
||||
{
|
||||
char *name = grub_strdup (alias->name);
|
||||
if (!name)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return 0;
|
||||
}
|
||||
op = ofdisk_hash_add (name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (alias->path, &dev))
|
||||
if (grub_ieee1275_finddevice (ent->devpath, &dev))
|
||||
{
|
||||
grub_dprintf ("disk", "finddevice (%s) failed\n", alias->path);
|
||||
return 0;
|
||||
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");
|
||||
return 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (tmp, "sdmmc"))
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (! grub_strcmp (alias->type, "block") &&
|
||||
grub_strncmp (alias->name, "cdrom", 5))
|
||||
ret = hook (alias->name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return grub_devalias_iterate (dev_iterate);
|
||||
}
|
||||
|
||||
static char *
|
||||
compute_dev_path (const char *name)
|
||||
|
@ -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;
|
||||
|
||||
/* 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);
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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. */
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#ifdef GRUB_UTIL
|
||||
grub_util_info ("unknown pe_start\n");
|
||||
#endif
|
||||
goto pvs_fail;
|
||||
}
|
||||
|
||||
p = grub_strchr (p, '}');
|
||||
if (p == NULL)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
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)
|
||||
{
|
||||
err = grub_errno;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_ext2_iterate_dir,
|
||||
err = grub_fshelp_find_file (name, &data->diropen, &fdiro,
|
||||
grub_ext2_iterate_dir,
|
||||
grub_ext2_read_symlink, GRUB_FSHELP_REG);
|
||||
if (grub_errno)
|
||||
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
|
||||
|
|
|
@ -41,7 +41,7 @@ struct grub_pxe_disk_data
|
|||
grub_uint32_t gateway_ip;
|
||||
};
|
||||
|
||||
struct grub_pxenv *grub_pxe_pxenv;
|
||||
struct grub_pxe_bangpxe *grub_pxe_pxenv;
|
||||
static grub_uint32_t grub_pxe_your_ip;
|
||||
static grub_uint32_t grub_pxe_default_server_ip;
|
||||
static grub_uint32_t grub_pxe_default_gateway_ip;
|
||||
|
@ -58,41 +58,47 @@ struct grub_pxe_data
|
|||
|
||||
static grub_uint32_t pxe_rm_entry = 0;
|
||||
|
||||
static struct grub_pxenv *
|
||||
static struct grub_pxe_bangpxe *
|
||||
grub_pxe_scan (void)
|
||||
{
|
||||
struct grub_bios_int_registers regs;
|
||||
struct grub_pxenv *ret;
|
||||
void *pxe;
|
||||
struct grub_pxenv *pxenv;
|
||||
struct grub_pxe_bangpxe *bangpxe;
|
||||
|
||||
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
|
||||
|
||||
regs.ebx = 0;
|
||||
regs.ecx = 0;
|
||||
regs.eax = 0x5650;
|
||||
regs.es = 0;
|
||||
|
||||
grub_bios_interrupt (0x1a, ®s);
|
||||
|
||||
if ((regs.eax & 0xffff) != 0x564e)
|
||||
return NULL;
|
||||
ret = (struct grub_pxenv *) ((regs.es << 4) + (regs.ebx & 0xffff));
|
||||
if (grub_memcmp (ret->signature, GRUB_PXE_SIGNATURE, sizeof (ret->signature))
|
||||
|
||||
pxenv = (struct grub_pxenv *) ((regs.es << 4) + (regs.ebx & 0xffff));
|
||||
if (grub_memcmp (pxenv->signature, GRUB_PXE_SIGNATURE,
|
||||
sizeof (pxenv->signature))
|
||||
!= 0)
|
||||
return NULL;
|
||||
if (ret->version < 0x201)
|
||||
|
||||
if (pxenv->version < 0x201)
|
||||
return NULL;
|
||||
|
||||
pxe = (void *) ((((ret->pxe_ptr & 0xffff0000) >> 16) << 4)
|
||||
+ (ret->pxe_ptr & 0xffff));
|
||||
if (!pxe)
|
||||
bangpxe = (void *) ((((pxenv->pxe_ptr & 0xffff0000) >> 16) << 4)
|
||||
+ (pxenv->pxe_ptr & 0xffff));
|
||||
|
||||
if (!bangpxe)
|
||||
return NULL;
|
||||
|
||||
/* !PXE */
|
||||
if (*(grub_uint32_t *) pxe != 0x45585021)
|
||||
if (grub_memcmp (bangpxe->signature, GRUB_PXE_BANGPXE_SIGNATURE,
|
||||
sizeof (bangpxe->signature)) != 0)
|
||||
return NULL;
|
||||
|
||||
pxe_rm_entry = ret->rm_entry;
|
||||
return ret;
|
||||
pxe_rm_entry = bangpxe->rm_entry;
|
||||
|
||||
return bangpxe;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -170,7 +176,6 @@ grub_pxe_open (const char *name, grub_disk_t disk)
|
|||
disk->total_sectors = 0;
|
||||
disk->id = (unsigned long) data;
|
||||
|
||||
disk->has_partitions = 0;
|
||||
disk->data = data;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
|
@ -276,6 +281,7 @@ grub_pxefs_open (struct grub_file *file, const char *name)
|
|||
}
|
||||
|
||||
file->data = data;
|
||||
file->not_easly_seekable = 1;
|
||||
grub_memcpy (file_int, file, sizeof (struct grub_file));
|
||||
curr_file = file_int;
|
||||
|
||||
|
@ -321,7 +327,7 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len)
|
|||
o.gateway_ip = disk_data->gateway_ip;
|
||||
grub_strcpy ((char *)&o.filename[0], data->filename);
|
||||
o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT);
|
||||
o.packet_size = grub_pxe_blksize;
|
||||
o.packet_size = data->block_size;
|
||||
grub_pxe_call (GRUB_PXENV_TFTP_OPEN, &o, pxe_rm_entry);
|
||||
if (o.status)
|
||||
{
|
||||
|
@ -483,7 +489,7 @@ parse_dhcp_vendor (void *vend, int limit)
|
|||
static void
|
||||
grub_pxe_detect (void)
|
||||
{
|
||||
struct grub_pxenv *pxenv;
|
||||
struct grub_pxe_bangpxe *pxenv;
|
||||
struct grub_pxenv_get_cached_info ci;
|
||||
struct grub_pxenv_boot_player *bp;
|
||||
|
||||
|
|
|
@ -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_minix_uintn_t indirn;
|
||||
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);
|
||||
}
|
||||
sizeof (grub_minix_uintn_t) * num,
|
||||
sizeof (grub_minix_uintn_t), (char *) &indirn);
|
||||
return grub_minix_le_to_cpu_n (indirn);
|
||||
}
|
||||
|
||||
/* Direct block. */
|
||||
|
@ -259,8 +258,6 @@ 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))
|
||||
|
@ -268,18 +265,6 @@ grub_minix_read_inode (struct grub_minix_data *data, int ino)
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;}"
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
#! /bin/sh
|
||||
#
|
||||
# Copyright (C) 2005,2008 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 fs names.
|
||||
|
||||
module=$1
|
||||
|
||||
# Ignore kernel.mod.
|
||||
if test $module = kernel; then
|
||||
exit
|
||||
fi
|
||||
|
||||
# For now, this emits only a module name, if the module registers a filesystem.
|
||||
if grep -v "^#" | grep '^ *grub_fs_register' >/dev/null 2>&1; then
|
||||
echo $module
|
||||
fi
|
|
@ -1,19 +0,0 @@
|
|||
#! /bin/sh
|
||||
#
|
||||
# Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
#
|
||||
# This script 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_parser_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/parser.\1: $module/;p;}"
|
73
grub-core/genmod.sh.in
Normal file
73
grub-core/genmod.sh.in
Normal file
|
@ -0,0 +1,73 @@
|
|||
#! /bin/sh -e
|
||||
#
|
||||
# Copyright (C) 2010 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.
|
||||
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# genmod.sh moddep.lst normal.module normal.mod
|
||||
#
|
||||
|
||||
moddep=$1
|
||||
infile=$2
|
||||
outfile=$3
|
||||
|
||||
tmpfile=${outfile}.tmp
|
||||
modname=`echo $infile | sed -e 's@\.module.*$@@'`
|
||||
|
||||
if ! grep ^$modname: $moddep >/dev/null; then
|
||||
echo "warning: moddep.lst has no dependencies for $modname" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
deps=`grep ^$modname: $moddep | sed s@^.*:@@`
|
||||
|
||||
# remove old files if any
|
||||
rm -f $tmpfile $outfile
|
||||
|
||||
# stripout .modname and .moddeps sections from input module
|
||||
objcopy -R .modname -R .moddeps $infile $tmpfile
|
||||
|
||||
# Attach .modname and .moddeps sections
|
||||
t1=`mktemp`
|
||||
printf "$modname\0" >$t1
|
||||
|
||||
t2=`mktemp`
|
||||
for dep in $deps; do printf "$dep\0" >> $t2; done
|
||||
|
||||
if test -n "$deps"; then
|
||||
objcopy --add-section .modname=$t1 --add-section .moddeps=$t2 $tmpfile
|
||||
else
|
||||
objcopy --add-section .modname=$t1 $tmpfile
|
||||
fi
|
||||
rm -f $t1 $t2
|
||||
|
||||
if test x@TARGET_APPLE_CC@ != x1; then
|
||||
if ! test -z "@TARGET_OBJ2ELF@"; then
|
||||
./@TARGET_OBJ2ELF@ $tmpfile || exit 1
|
||||
fi
|
||||
if test x@platform@ != xemu; then
|
||||
@STRIP@ --strip-unneeded \
|
||||
-K grub_mod_init -K grub_mod_fini \
|
||||
-K _grub_mod_init -K _grub_mod_fini \
|
||||
-R .note -R .comment $tmpfile || exit 1
|
||||
fi
|
||||
else
|
||||
# XXX Test these Apple CC fixes
|
||||
cp $tmpfile $tmpfile.bin
|
||||
@OBJCONV@ -f@TARGET_MODULE_FORMAT@ \
|
||||
-nr:_grub_mod_init:grub_mod_init \
|
||||
-nr:_grub_mod_fini:grub_mod_fini \
|
||||
-wd1106 -ew2030 -ew2050 -nu -nd $tmpfile.bin $tmpfile || exit 1
|
||||
rm -f $name.bin
|
||||
fi
|
||||
mv $tmpfile $outfile
|
|
@ -11,25 +11,30 @@
|
|||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
# Read defined symbols from stdin.
|
||||
# Read symbols' info from stdin.
|
||||
BEGIN {
|
||||
error = 0
|
||||
lineno = 0;
|
||||
while (getline <"/dev/stdin") {
|
||||
symtab[$1] = $2
|
||||
}
|
||||
}
|
||||
|
||||
# The rest is undefined symbols.
|
||||
{
|
||||
module = $2
|
||||
|
||||
if ($1 in symtab) {
|
||||
modtab[module] = modtab[module] " " symtab[$1];
|
||||
}
|
||||
else if ($1 != "__gnu_local_gp") {
|
||||
printf "%s in %s is not defined\n", $1, module >"/dev/stderr";
|
||||
lineno++;
|
||||
if ($1 == "defined") {
|
||||
symtab[$3] = $2;
|
||||
modtab[$2] = "" modtab[$2]
|
||||
} else if ($1 == "undefined") {
|
||||
if ($3 in symtab)
|
||||
modtab[$2] = modtab[$2] " " symtab[$3];
|
||||
else if ($3 != "__gnu_local_gp") {
|
||||
printf "%s in %s is not defined\n", $3, $2 >"/dev/stderr";
|
||||
error++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf "error: %u: unrecognized input format\n", lineno;
|
||||
error++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Output the result.
|
||||
END {
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
#! /bin/sh
|
||||
#
|
||||
# Copyright (C) 2002,2007 Free Software Foundation, Inc.
|
||||
#
|
||||
# This genmodsrc.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.
|
||||
|
||||
set -e
|
||||
|
||||
mod_name="$1"
|
||||
deps="$2"
|
||||
|
||||
cat <<EOF
|
||||
/* This file is automatically generated by genmodsrc.sh. DO NOT EDIT! */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2002,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/dl.h>
|
||||
|
||||
EOF
|
||||
|
||||
echo "GRUB_MOD_NAME(${mod_name});"
|
||||
|
||||
for mod in `grep "^${mod_name}:" ${deps} | sed 's/^[^:]*://'`; do
|
||||
echo "GRUB_MOD_DEP(${mod});"
|
||||
done
|
|
@ -1,26 +0,0 @@
|
|||
#! /bin/sh
|
||||
#
|
||||
# Copyright (C) 2005, 2008 Free Software Foundation, Inc.
|
||||
#
|
||||
# This script 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 partmap names.
|
||||
|
||||
module=$1
|
||||
|
||||
# Ignore kernel.mod.
|
||||
if test $module = kernel; then
|
||||
exit
|
||||
fi
|
||||
|
||||
# For now, this emits only a module name, if the module registers a partition map.
|
||||
if grep -v "^#" | grep '^ *grub_partition_map_register' >/dev/null 2>&1; then
|
||||
echo $module
|
||||
fi
|
|
@ -1,19 +0,0 @@
|
|||
#! /bin/sh
|
||||
#
|
||||
# Copyright (C) 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 parttool names.
|
||||
|
||||
module=$1
|
||||
|
||||
grep -v "^#" | sed -n \
|
||||
-e "/grub_parttool_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $module/;p;}"
|
34
grub-core/gensyminfo.sh.in
Normal file
34
grub-core/gensyminfo.sh.in
Normal file
|
@ -0,0 +1,34 @@
|
|||
#! /bin/sh -e
|
||||
#
|
||||
# Copyright (C) 2010 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.
|
||||
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# gensyms.sh normal.module
|
||||
#
|
||||
|
||||
module=$1
|
||||
modname=`echo $module | sed -e 's@\.module.*$@@'`
|
||||
|
||||
# Print all symbols defined by module
|
||||
if test x@TARGET_APPLE_CC@ = x1; then
|
||||
@NM@ -g -P -p $module | \
|
||||
grep -E '^[a-zA-Z0-9_]* [TDS]' | \
|
||||
sed "s@^\([^ ]*\).*@defined $modname \1@g"
|
||||
else
|
||||
@NM@ -g --defined-only -P -p $module | \
|
||||
sed "s@^\([^ ]*\).*@defined $modname \1@g"
|
||||
fi
|
||||
|
||||
# Print all undefined symbols used by module
|
||||
@NM@ -u -P -p $module | sed "s@^\([^ ]*\).*@undefined $modname \1@g"
|
|
@ -1,20 +0,0 @@
|
|||
#! /bin/sh
|
||||
#
|
||||
# Copyright (C) 2009,2010 Free Software Foundation, Inc.
|
||||
#
|
||||
# This script 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_term_register_input *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $module/;p;}" \
|
||||
-e "/grub_term_register_output *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\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