merge with mainline
This commit is contained in:
commit
7431d7a49c
242 changed files with 11326 additions and 4857 deletions
10
.bzrignore
10
.bzrignore
|
@ -4,6 +4,8 @@
|
|||
30_os-prober
|
||||
40_custom
|
||||
41_custom
|
||||
*.1
|
||||
*.8
|
||||
aclocal.m4
|
||||
ascii.bitmaps
|
||||
ascii.h
|
||||
|
@ -18,8 +20,6 @@ config.log
|
|||
config.status
|
||||
config.sub
|
||||
configure
|
||||
conf/*.mk
|
||||
*.d
|
||||
DISTLIST
|
||||
docs/*.info
|
||||
docs/stamp-vti
|
||||
|
@ -58,11 +58,15 @@ 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
|
||||
Makefile
|
||||
*.mod
|
||||
|
@ -76,6 +80,7 @@ stamp-h
|
|||
stamp-h1
|
||||
stamp-h.in
|
||||
symlist.c
|
||||
symlist.h
|
||||
trigtables.c
|
||||
update-grub_lib
|
||||
unidata.c
|
||||
|
@ -99,3 +104,4 @@ grub-core/Makefile.gcry.am
|
|||
grub-core/Makefile.gcry.def
|
||||
grub-core/*.module
|
||||
grub-core/*.pp
|
||||
util/bash-completion.d/grub
|
||||
|
|
792
ChangeLog
792
ChangeLog
|
@ -1,3 +1,786 @@
|
|||
2010-09-19 Colin Watson <cjwatson@ubuntu.com>
|
||||
2010-09-19 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* Makefile.util.def (grub-install): Use util/grub-install.in on all
|
||||
platforms.
|
||||
* util/grub-install.in: Add EFI and IEEE1275 support.
|
||||
* util/i386/efi/grub-install.in: Removed.
|
||||
* util/ieee1275/grub-install.in: Likewise.
|
||||
|
||||
2010-09-19 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/commands/i386/cmostest.c (+parse_args): New function.
|
||||
(grub_cmd_cmosclean): Likewise.
|
||||
(GRUB_MOD_INIT): Register command cmosclean.
|
||||
* util/grub-mkconfig.in: Export GRUB_BUTTON_CMOS_CLEAN.
|
||||
* util/grub.d/00_header.in: Handle GRUB_BUTTON_CMOS_CLEAN.
|
||||
|
||||
2010-09-18 Carles Pina i Estany <carles@pina.cat>
|
||||
2010-09-18 Aleš Nesrsta <starous@volny.cz>
|
||||
2010-09-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Add keyboard layouts support.
|
||||
|
||||
* Makefile.util.def (grub-mklayout): New file.
|
||||
(grub-kbdcomp): New script.
|
||||
* grub-core/Makefile.am (KERNEL_HEADER_FILES) [COND_mips_yeeloong]:
|
||||
Add keyboard_layouts.h.
|
||||
* grub-core/Makefile.core.def (kernel): Add commands/keylayouts.c and
|
||||
commands/boot.c on yeeloong.
|
||||
(keylayouts): New module.
|
||||
* grub-core/bus/usb/ohci.c
|
||||
* grub-core/bus/usb/uhci.c
|
||||
* grub-core/bus/usb/usbhub.c (rescan): New variable.
|
||||
(grub_usb_add_hub): Poll interrupt pipe for device handling.
|
||||
(attach_root_port): Likewise.
|
||||
(poll_nonroot_hub): Likewise.
|
||||
(grub_usb_poll_devices): Likewise.
|
||||
(detach_device): Close transfer.
|
||||
* grub-core/bus/usb/usbtrans.c (grub_usb_execute_and_wait_transfer): New
|
||||
function.
|
||||
(grub_usb_bulk_setup_readwrite): Likewise.
|
||||
(grub_usb_bulk_finish_readwrite): Likewise.
|
||||
* grub-core/commands/keylayouts.c: New file.
|
||||
* grub-core/commands/keystatus.c (grub_getkeystatus): New function.
|
||||
* grub-core/commands/menuentry.c (hotkey_aliases): All several new
|
||||
aliases.
|
||||
* grub-core/term/at_keyboard.c: Restructured to use keylayouts and
|
||||
support scancode 2.
|
||||
* grub-core/term/usb_keyboard.c: Restructured to use keylayouts.
|
||||
* include/grub/keyboard_layouts.h: New file.
|
||||
* util/grub-mklayout.c: New file.
|
||||
* util/grub-kbdcomp.in: Likewise.
|
||||
|
||||
2010-09-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Unify memory types.
|
||||
|
||||
* grub-core/Makefile.am (KERNEL_HEADER_FILES): Include memory.h.
|
||||
* grub-core/commands/lsmmap.c (grub_cmd_lsmmap): Output user-readable
|
||||
types.
|
||||
* grub-core/kern/i386/multiboot_mmap.c (grub_lower_mem): Removed.
|
||||
(grub_upper_mem): Likewise.
|
||||
* grub-core/kern/ieee1275/init.c (grub_upper_mem): Likewise.
|
||||
* include/grub/memory.h (grub_memory_type_t): New enum.
|
||||
All users updated.
|
||||
|
||||
2010-09-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/Makefile.core.def (lsapm): New module.
|
||||
* grub-core/commands/i386/pc/lsapm.c: New file.
|
||||
* grub-core/loader/i386/multiboot_mbi.c (make_mbi) [GRUB_MACHINE_PCBIOS]: Pass APM info.
|
||||
* grub-core/loader/multiboot_mbi2.c (make_mbi) [GRUB_MACHINE_PCBIOS]:
|
||||
Likewise.
|
||||
* include/grub/i386/pc/apm.h: New file.
|
||||
* include/multiboot.h (multiboot_apm_info): New struct.
|
||||
|
||||
2010-09-18 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
GRUB-legacy configuration file support.
|
||||
|
||||
* Makefile.util.def (grub-menulst2cfg): New util.
|
||||
* docs/man/grub-menulst2cfg.h2m: New file.
|
||||
* grub-core/Makefile.core.def (legacycfg): New module.
|
||||
* grub-core/commands/legacycfg.c: New file.
|
||||
* grub-core/commands/menuentry.c (append_menu_entry): Rename to ...
|
||||
(grub_normal_add_menu_entry): ... this.
|
||||
* grub-core/commands/password.c (grub_cmd_password): Split main part to ...
|
||||
(grub_normal_set_password): ...this.
|
||||
* grub-core/commands/videoinfo.c (grub_cmd_videoinfo): Support MODE.
|
||||
* grub-core/loader/i386/linux.c (linux_vesafb_res): Move to ..,
|
||||
* grub-core/lib/i386/pc/vesa_modes_table.c: ... here.
|
||||
* grub-core/lib/legacy_parse.c: New file.
|
||||
* grub-core/normal/auth.c (grub_cmd_authenticate): New command.
|
||||
* include/grub/i386/pc/vesa_modes_table.h: New file.
|
||||
* include/grub/legacy_parse.h: Likewise.
|
||||
* include/grub/normal.h (grub_normal_add_menu_entry): New proto.
|
||||
* util/grub-menulst2cfg.c: New file.
|
||||
|
||||
2010-09-17 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* grub-core/kern/emu/hostdisk.c
|
||||
(convert_system_partition_to_system_disk): Initialise node.
|
||||
|
||||
2010-09-17 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* grub-core/kern/emu/hostdisk.c
|
||||
(convert_system_partition_to_system_disk): Fix devmapper memory pool
|
||||
leak.
|
||||
Reported and based on patch by: Modestas Vainius.
|
||||
|
||||
2010-09-17 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
Fix DM-RAID probing with recent versions of device-mapper udev
|
||||
rules.
|
||||
|
||||
* grub-core/kern/emu/hostdisk.c (read_device_map): Don't
|
||||
canonicalise device paths under /dev/mapper/.
|
||||
(convert_system_partition_to_system_disk): Compare the
|
||||
uncanonicalised path to /dev/mapper/ rather than the canonicalised
|
||||
path, since device nodes under /dev/mapper/ are often symlinks.
|
||||
|
||||
2010-09-17 Yves Blusseau <blusseau@zetam.org>
|
||||
|
||||
* .bzrignore: *.d removed (old rule), add *.image and symlist.h.
|
||||
|
||||
2010-09-16 Yves Blusseau <blusseau@zetam.org>
|
||||
|
||||
* configure.ac: Avoid some annoying error messages if freetype-config
|
||||
program is not found.
|
||||
|
||||
2010-09-16 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
Support RAID on virtio devices, and others.
|
||||
|
||||
* grub-core/kern/emu/getroot.c [__MINGW32__] (find_root_device):
|
||||
Rename to ...
|
||||
[__MINGW32__] (grub_find_device): ... this.
|
||||
[! __MINGW32__ && ! __CYGWIN__] (find_root_device): Rename to ...
|
||||
[! __MINGW32__ && ! __CYGWIN__] (grub_find_device): ... this. Use a
|
||||
reasonable default if dir is NULL.
|
||||
[! __MINGW32__ && __CYGWIN__] (find_cygwin_root_device): Rename to
|
||||
...
|
||||
[! __MINGW32__ && __CYGWIN__] (grub_find_device): ... this.
|
||||
(grub_guess_root_device): Update callers.
|
||||
* include/grub/emu/getroot.h (grub_find_device): Add prototype.
|
||||
|
||||
* util/raid.c (grub_util_getdiskname): Remove.
|
||||
(grub_util_raid_getmembers): Use grub_find_device rather than
|
||||
grub_util_getdiskname.
|
||||
|
||||
2010-09-16 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* docs/grub.texi (serial): Remove obsolete comment about GRUB
|
||||
needing to be compiled with serial support.
|
||||
(ls): Indicate that multiple files are accepted.
|
||||
* grub-core/commands/ls.c (GRUB_MOD_INIT): Update help text to
|
||||
indicate that multiple files are accepted.
|
||||
|
||||
2010-09-16 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* .bzrignore: Add *.1, *.8, grub-shell, grub-shell-tester,
|
||||
libgrub_a_init.c, and util/bash-completion.d/grub.
|
||||
|
||||
2010-09-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* util/grub-setup.c (setup): Fix incorrect container semantics.
|
||||
|
||||
2010-09-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/commands/parttool.c (grub_cmd_parttool): Fix a variable
|
||||
misusage.
|
||||
Reported by: J. Nick Terry
|
||||
|
||||
2010-09-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Move embedding routines to partmap sources files.
|
||||
|
||||
* grub-core/partmap/gpt.c (grub_gpt_partition_type_bios_boot)
|
||||
[GRUB_UTIL]: New variable.
|
||||
(gpt_partition_map_iterate): Set part.parent.
|
||||
(gpt_partition_map_embed) [GRUB_UTIL]: New function.
|
||||
(grub_gpt_partition_map) [GRUB_UTIL]: Set .embed.
|
||||
* grub-core/partmap/msdos.c (pc_partition_map_embed) [GRUB_UTIL]:
|
||||
New function.
|
||||
(grub_msdos_partition_map) [GRUB_UTIL]: Set .embed.
|
||||
* include/grub/partition.h (grub_embed_type_t) [GRUB_UTIL]: New type.
|
||||
(grub_partition_map) [GRUB_UTIL]: New field embed.
|
||||
* util/grub-setup.c (grub_gpt_partition_type_bios_boot): Removed.
|
||||
(setup): Use ->embed.
|
||||
|
||||
2010-09-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy): New
|
||||
function.
|
||||
* include/grub/emu/hostdisk.h (grub_util_biosdisk_is_floppy): New proto.
|
||||
* util/grub-setup.c (setup): Use grub_util_biosdisk_is_floppy.
|
||||
|
||||
2010-09-15 Yves Blusseau <blusseau@zetam.org>
|
||||
|
||||
Add function to get completions from usage.
|
||||
|
||||
* util/bash-completion.d/grub-completion.bash.in: Add function to get
|
||||
completions from usage. Use LC_ALL=C to get options properly.
|
||||
|
||||
2010-09-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/gnulib/basename-lgpl.c: Imported.
|
||||
* grub-core/gnulib/basename.c: Likewise.
|
||||
* grub-core/gnulib/dirname-lgpl.c: Likewise.
|
||||
* grub-core/gnulib/dirname.c: Likewise.
|
||||
* grub-core/gnulib/dirname.h: Likewise.
|
||||
* grub-core/gnulib/stripslash.c: Likewise.
|
||||
|
||||
2010-09-15 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/gnulib/error.c: Resynced.
|
||||
* grub-core/gnulib/getopt.c: Likewise.
|
||||
* grub-core/gnulib/getopt_int.h: Likewise.
|
||||
* grub-core/gnulib/regex.h: Likewise.
|
||||
* grub-core/gnulib/regex_internal.c: Likewise.
|
||||
* grub-core/gnulib/regex_internal.h: Likewise.
|
||||
|
||||
2010-09-15 Szymon Janc <szymon@janc.net.pl>
|
||||
|
||||
* grub-core/lib/xzembed/xz_dec_stream.c (dec_main): Fix index and block
|
||||
CRC calculations and validity checks.
|
||||
* grub-core/lib/xzembed/xz_dec_stream.c (dec_index): Fix index CRC
|
||||
calculations.
|
||||
|
||||
2010-09-15 Szymon Janc <szymon@janc.net.pl>
|
||||
|
||||
* grub-core/lib/xzembed/xz_dec_stream.c (xz_dec_end): Fix memory leak.
|
||||
|
||||
2010-09-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Fix incorrect echo options handling.
|
||||
Reported by: Yves Blusseau.
|
||||
|
||||
* include/grub/command.h (grub_command_flags_t): New flags
|
||||
GRUB_COMMAND_ACCEPT_DASH and GRUB_COMMAND_OPTIONS_AT_START.
|
||||
* grub-core/lib/arg.c (grub_arg_parse): Handle new flags.
|
||||
* grub-core/commands/echo.c (GRUB_MOD_INIT): Use new flags.
|
||||
|
||||
2010-09-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* include/grub/command.h (GRUB_COMMAND_FLAG_CMDLINE): Removed. All
|
||||
users updated.
|
||||
(GRUB_COMMAND_FLAG_MENU): Likewise.
|
||||
(GRUB_COMMAND_FLAG_BOTH): Likewise.
|
||||
(GRUB_COMMAND_FLAG_TITLE): Removed.
|
||||
(GRUB_COMMAND_FLAG_NO_ECHO): Likewise.
|
||||
(GRUB_COMMAND_FLAG_EXTCMD): Moved into enum.
|
||||
(GRUB_COMMAND_FLAG_DYNCMD): Likewise.
|
||||
(GRUB_COMMAND_FLAG_BLOCKS): Likewise.
|
||||
(grub_command_flags_t): New enum. All users updated.
|
||||
|
||||
2010-09-14 Seth Goldberg <seth.goldberg@oracle.com>
|
||||
|
||||
Fix solaris compilation.
|
||||
|
||||
* grub-core/Makefile.core.def (kernel): Include gnulib/error.c on emu.
|
||||
(grub-emu): Add LIBZFS and LIBNVPAIR to ldadd.
|
||||
(grub-emu-list): Likewise.
|
||||
|
||||
2010-09-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Remove deprecated root command.
|
||||
|
||||
* grub-core/commands/minicmd.c (grub_mini_cmd_root): Removed. All users
|
||||
updated.
|
||||
|
||||
2010-09-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* util/i386/pc/grub-setup.c: Merge this ...
|
||||
* util/sparc64/ieee1275/grub-setup.c: ... and this ...
|
||||
* util/grub-setup.c: ... into this.
|
||||
* include/grub/sparc64/ieee1275/boot.h (grub_boot_blocklist) [ASM_FILE]:
|
||||
New struct.
|
||||
|
||||
2010-09-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/fs/ext2.c (grub_ext2_open): Use return error value when
|
||||
possible.
|
||||
|
||||
2010-09-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/partmap/sun.c (sun_partition_map_iterate): Don't needlesly
|
||||
allocate p.
|
||||
|
||||
2010-09-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Add
|
||||
explicit root argument to set to prevent UUID to be interpreted as
|
||||
argument to set.
|
||||
|
||||
2010-09-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/kern/sparc64/ieee1275/crt0.S: Align stack.
|
||||
|
||||
2010-09-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Don't export grub_gate_a20.
|
||||
|
||||
* grub-core/kern/i386/pc/init.c: Remove leftovers.
|
||||
* grub-core/kern/i386/pc/startup.S (FUNCTION(grub_gate_a20)): Rename
|
||||
to ...
|
||||
(grub_gate_a20): ... this. All users updated.
|
||||
* include/grub/i386/pc/init.h: Removed. All users updated.
|
||||
|
||||
2010-09-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Create euro.pf2 which supports most European languages.
|
||||
|
||||
* Makefile.am (grubdata_DATA): Add euro.pf2.
|
||||
(euro.pf2): New target.
|
||||
(CLEANFILES): Add euro.pf2.
|
||||
|
||||
2010-09-14 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* configure.ac: Disable emu-usb by default to prevent inadvertent
|
||||
device takeover.
|
||||
|
||||
2010-09-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Disable usbserial on grub-emu since our libusb code isn't good enough
|
||||
yet.
|
||||
|
||||
* grub-core/Makefile.core.def (usbserial_common): Disable on emu.
|
||||
(usbserial_pl2303): Likewise.
|
||||
(usbserial_ftdi): Likewise.
|
||||
|
||||
2010-09-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* include/grub/disk.h (grub_disk): Remove has_partitions.
|
||||
All users updated.
|
||||
* disk/loopback.c (grub_loopback): Remove has_partitions.
|
||||
All users updated.
|
||||
(options): Remove partitions. All users updated.
|
||||
* util/grub-fstest.c (fstest): Don't pass "-p" to loopback.
|
||||
* util/i386/pc/grub-setup.c (setup): copy partition table only when
|
||||
actual partition table is found.
|
||||
|
||||
2010-09-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Remove readability checks (too many false negatives).
|
||||
|
||||
* util/grub-install.in: Remove readability checks.
|
||||
* util/grub-mkconfig.in: Likewise.
|
||||
* util/grub.d/10_hurd.in: Likewise.
|
||||
* util/grub.d/10_kfreebsd.in: Likewise.
|
||||
* util/grub.d/10_linux.in: Likewise.
|
||||
* util/grub-mkconfig_lib.in (is_path_readable_by_grub): Revert to old
|
||||
way.
|
||||
|
||||
2010-09-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Enable acpi shutdown on all ACPI platforms.
|
||||
|
||||
* grub-core/Makefile.core.def (halt): Inlude commands/acpihalt.c
|
||||
on coreboo, multiboot and EFI.
|
||||
* grub-core/commands/acpihalt.c (get_sleep_type): Add missing casts.
|
||||
(grub_acpi_halt): Likewise.
|
||||
* grub-core/commands/i386/pc/halt.c (grub_halt): Call grub_acpi_halt.
|
||||
(grub_cmd_halt): Don't call grub_acpi_halt directly.
|
||||
* grub-core/lib/efi/halt.c (grub_halt): Call grub_acpi_halt.
|
||||
* grub-core/lib/i386/halt.c (grub_halt)
|
||||
[GRUB_MACHINE_COREBOOT || GRUB_MACHINE_MULTIBOOT]: Likewise.
|
||||
|
||||
2010-09-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/commands/iorw.c (grub_cmd_read): Declare buf in smallest
|
||||
context.
|
||||
|
||||
2010-09-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/video/efi_gop.c: Fix over-80-chars line.
|
||||
* grub-core/video/efi_uga.c: Likewise.
|
||||
|
||||
2010-09-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Filter devaliases and never open same device twice.
|
||||
|
||||
* grub-core/disk/ieee1275/ofdisk.c (last_devpath): New variable.
|
||||
(last_ihandle): Likewise.
|
||||
(ofdisk_hash_ent): New member shortest.
|
||||
(ofdisk_hash_add): Add canonical path too.
|
||||
(scan): New function.
|
||||
(grub_ofdisk_iterate): Iterate over hashed entries.
|
||||
(compute_dev_path): Don't add :0.
|
||||
(grub_ofdisk_open): Don't really open the disk.
|
||||
(grub_ofdisk_close): Avoid closing unrelated disk.
|
||||
(grub_ofdisk_read): Implement reopen logic.
|
||||
* grub-core/kern/ieee1275/openfw.c (grub_ieee1275_canonicalise_devname):
|
||||
New function.
|
||||
* include/grub/ieee1275/ieee1275.h (grub_ieee1275_canonicalise_devname):
|
||||
New proto.
|
||||
|
||||
2010-09-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Fix sparc64.
|
||||
|
||||
* configure.ac (GRUB_KERNEL_MACHINE_LINK_ADDR): Removed.
|
||||
* grub-core/Makefile.core.def (kernel): Make ldflags just use the
|
||||
right address. Add sparc64_ieee1275_ldflags.
|
||||
* grub-core/loader/sparc64/ieee1275/linux.c: Remove leftover include.
|
||||
* util/grub-mkimagexx.c (locate_sections): Correct grub_host_to_target32
|
||||
to grub_host_to_target_addr
|
||||
(load_image): Likewise.
|
||||
|
||||
2010-09-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/normal/completion.c (complete_file): Handle device
|
||||
containing slash.
|
||||
Fix based on patch by Doug Nazar.
|
||||
|
||||
2010-09-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
grub-mknetdir script.
|
||||
|
||||
* Makefile.util.def (grub-mknetdir): New module.
|
||||
* tests/util/grub-shell.in: Support boot=net
|
||||
* util/grub-mknetdir.in: New file.
|
||||
|
||||
2010-09-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
videoinfo on non-vbe.
|
||||
|
||||
* grub-core/Makefile.core.def (vbeinfo): Removed.
|
||||
(vbetest): Removed.
|
||||
(videoinfo): New module.
|
||||
* grub-core/commands/i386/pc/vbeinfo.c: Removed.
|
||||
* grub-core/commands/i386/pc/vbetest.c: Removed.
|
||||
* grub-core/commands/videoinfo.c: New file.
|
||||
* grub-core/commands/videotest.c (grub_cmd_videotest): Support mode
|
||||
specification.
|
||||
(grub_cmd_videotest) [GRUB_MACHINE_PCBIOS]: Load vbe.mod when invoked
|
||||
as vbetest.
|
||||
(GRUB_MOD_INIT) [GRUB_MACHINE_PCBIOS]: New command vbetest.
|
||||
(GRUB_MOD_FINI) [GRUB_MACHINE_PCBIOS]: Unregister vbetest.
|
||||
* grub-core/video/efi_gop.c (grub_video_gop_fill_mode_info): Fill
|
||||
mode_number. New parameter mode. All users updated.
|
||||
(grub_video_gop_iterate): New function.
|
||||
(grub_video_efi_gop): New member iterate.
|
||||
* grub-core/video/i386/pc/vbe.c (framebuffer): Removed leftover fields.
|
||||
(grub_vbe_set_video_mode): Remove setting useless fields.
|
||||
(vbe2videoinfo): New function.
|
||||
(grub_video_vbe_iterate): Likewise.
|
||||
(grub_video_vbe_setup): Use vbe2videoinfo.
|
||||
(grub_video_vbe_print_adapter_specific_info): New function.
|
||||
(grub_video_vbe_adapter): New fields iterate and
|
||||
print_adapter_specific_info.
|
||||
* include/grub/video.h (GRUB_VIDEO_MODE_*): Transform into enum.
|
||||
All users updated.
|
||||
(grub_video_mode_info): New field mode_number.
|
||||
(grub_video_adapter): New fields iterate and
|
||||
print_adapter_specific_info.
|
||||
|
||||
2010-09-13 Tristan Gingold <gingold@free.fr>
|
||||
2010-09-13 Robert Millan <rmh.grub@aybabtu.com>
|
||||
2010-09-13 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.
|
||||
|
||||
2010-09-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Support explicit user claim that a device is BIOS-visible.
|
||||
|
||||
* grub-core/kern/emu/getroot.c (grub_util_get_dev_abstraction):
|
||||
Return GRUB_DEV_ABSTRACTION_NONE if device is in device.map.
|
||||
* grub-core/kern/emu/hostdisk.c
|
||||
(convert_system_partition_to_system_disk): Support mdX.
|
||||
(find_system_device): New parameter add. All users updated.
|
||||
(grub_util_biosdisk_is_present): New function.
|
||||
* include/grub/emu/hostdisk.h (grub_util_biosdisk_is_present): New
|
||||
proto.
|
||||
|
||||
2010-09-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Search hints support.
|
||||
|
||||
* commands/search.c (FUNC_NAME): New arguments hints and nhints.
|
||||
All users updated.
|
||||
|
||||
2010-09-13 Yves Blusseau <blusseau@zetam.org>
|
||||
|
||||
Bash completion script for util commands
|
||||
|
||||
* Makefile.am: Add util/bash-completion.d directory
|
||||
* configure.ac: Likewise.
|
||||
* util/bash-completion.d/Makefile.am: New file.
|
||||
* util/bash-completion.d/grub-completion.bash.in: Likewise.
|
||||
|
||||
2010-09-12 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/normal/term.c (put_glyphs_terminal): Correct sign.
|
||||
(print_backlog): set backlog_ucs4 and backlog_glyphs.
|
||||
Reported by: Yves Blusseau.
|
||||
|
||||
2010-09-12 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/normal/misc.c (grub_normal_print_device_info): Show
|
||||
partition size and offset.
|
||||
|
||||
2010-09-12 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/commands/wildcard.c (make_regex): Escape brackets.
|
||||
|
||||
2010-09-12 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/commands/ls.c (grub_cmd_ls): Accept multiple files.
|
||||
|
||||
2010-09-12 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/kern/misc.c (grub_vprintf): Use va_copy when necessary.
|
||||
(grub_xvasprintf): Likewise.
|
||||
|
||||
2010-09-12 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/kern/emu/main.c (main): Call hostfs_init only after init_all.
|
||||
|
||||
2010-09-12 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/commands/menuentry.c (append_menu_entry): Don't rely on
|
||||
args ending with NULL.
|
||||
|
||||
2010-09-12 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/lib/xzembed/xz_dec_stream.c (xz_dec_reset): Preserve context
|
||||
pointer.
|
||||
|
||||
2010-09-11 Szymon Janc <szymon@janc.net.pl>
|
||||
|
||||
* grub-core/commands/lsacpi.c (grub_cmd_lsacpi): Fix prototype.
|
||||
|
||||
2010-09-11 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Shutdown using ACPI.
|
||||
|
||||
* grub-core/Makefile.core.def (halt): Add commands/acpihalt.c on i386-pc.
|
||||
* grub-core/commands/acpihalt.c: New file.
|
||||
* grub-core/commands/i386/pc/halt.c (grub_cmd_halt): Call grub_acpi_halt.
|
||||
* include/grub/acpi.h (grub_acpi_fadt): New member pm1a.
|
||||
(grub_acpi_halt): New proto.
|
||||
(GRUB_ACPI_SLP_EN): New const.
|
||||
(GRUB_ACPI_SLP_TYP_OFFSET): Likewise.
|
||||
(GRUB_ACPI_OPCODE_*): New enum.
|
||||
(GRUB_ACPI_EXTOPCODE_*): Likewise.
|
||||
|
||||
2010-09-11 Tristan Gingold <gingold@free.fr>
|
||||
2010-09-11 Robert Millan <rmh.grub@aybabtu.com>
|
||||
2010-09-11 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.
|
||||
|
||||
2010-09-11 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Implement loading palette on ieee1275_fb.
|
||||
|
||||
* grub-core/video/ieee1275.c (stdout_ihandle): New variable.
|
||||
(have_setcolors): Likewise.
|
||||
(grub_video_ieee1275_init): Fill stdout_ihandle and have_setcolors.
|
||||
(grub_video_ieee1275_setup): Use grub_video_ieee1275_set_palette.
|
||||
(grub_video_ieee1275_set_palette): Implement.
|
||||
|
||||
2010-09-11 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
2010-09-11 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* util/grub-install.in (grub_partition): New variable.
|
||||
Set prefix_drive on EFI and PC to (,$grub_partition) as last resort.
|
||||
* util/i386/pc/grub-setup.c (setup): Don't touch prefix.
|
||||
Fixes a bug reported by Yves Blusseau.
|
||||
|
||||
2010-09-11 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Fix emu on mipsel.
|
||||
|
||||
* conf/Makefile.common (CFLAGS_PLATFORM): Add -mflush-func
|
||||
=grub_cpu_flush_cache on all mips and not only yeeloong.
|
||||
* configure.ac (COND_mips): New conditional.
|
||||
* grub-core/Makefile.am (KERNEL_HEADER_FILES): Add libgcc on all
|
||||
platforms.
|
||||
* grub-core/kern/emu/cache.S (__mips__): Use _flush_cache.
|
||||
* grub-core/kern/emu/full.c (grub_arch_dl_init_linker)
|
||||
[GRUB_LINKER_HAVE_INIT]: New function.
|
||||
(grub_emu_post_init): Likewise.
|
||||
* grub-core/kern/emu/lite.c (grub_emu_post_init): Likewise.
|
||||
* grub-core/kern/emu/main.c: Use grub_emu_post_init.
|
||||
* include/grub/cache.h (_mips): Include mips/cache.h.
|
||||
* include/grub/disk.h [GRUB_UTIL || GRUB_MACHINE_EMU]: Add missing
|
||||
LVM and RAID prototypes.
|
||||
* include/grub/emu/misc.h (grub_emu_post_init): New proto.
|
||||
* include/grub/mips/time.h (grub_cpu_idle) [GRUB_MACHINE_EMU]: New
|
||||
function.
|
||||
|
||||
2010-09-10 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* util/grub-install.in: Don't try to verify core.img until after
|
||||
running grub-mkimage to create it.
|
||||
|
||||
2010-09-10 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* util/grub.d/10_hurd.in: Add misc readability checks.
|
||||
* util/grub.d/10_kfreebsd.in: Likewise.
|
||||
* util/grub.d/10_linux.in: Likewise.
|
||||
|
||||
2010-09-10 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* util/grub-install.in: ${imgext} won't be defined here until the
|
||||
install branch is merged. For the meantime, only verify core.img on
|
||||
i386-pc and sparc64-ieee1275 platforms.
|
||||
|
||||
2010-09-10 Robert Millan <rmh@gnu.org>
|
||||
|
||||
Solaris support in grub_find_zpool_from_dir(). Thanks
|
||||
Seth Goldberg for referring to getextmntent() facility.
|
||||
|
||||
* configure.ac: Check for getextmntent(), `sys/mnttab.h' and
|
||||
`sys/mkdev.h'.
|
||||
* grub-core/kern/emu/misc.c [HAVE_SYS_MNTTAB_H]: Include
|
||||
`<sys/mnttab.h>'.
|
||||
[HAVE_SYS_MKDEV_H]: Include `<sys/mkdev.h>'.
|
||||
[HAVE_GETEXTMNTENT] (grub_find_zpool_from_dir): Add getextmntent()
|
||||
method for finding zpool name.
|
||||
|
||||
2010-09-10 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
grub-fstest needs the host and hostfs modules while other utilities
|
||||
actively require those modules to be absent, so grub-fstest needs
|
||||
its own initialisation and finalisation code.
|
||||
|
||||
* Makefile.am (grub_fstest.pp): New target.
|
||||
(grub_fstest_init.lst): Likewise.
|
||||
(grub_fstest_init.c): Likewise.
|
||||
* Makefile.util.def (grub-fstest): Add grub_fstest_init.c.
|
||||
|
||||
2010-09-10 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* configure.ac: Check for `struct statfs.f_fstypename' and
|
||||
`struct statfs.f_mntfromname'.
|
||||
|
||||
* grub-core/kern/emu/misc.c (grub_find_zpool_from_dir): Conditionalize
|
||||
kFreeBSD-specific code.
|
||||
|
||||
2010-09-10 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* util/grub.d/10_kfreebsd.in: Fix ${kfreebsd_device} initialization
|
||||
on ZFS. Now non-main filesystems are supported as / too.
|
||||
|
||||
2010-09-09 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* Makefile.util.def (libgrub.a): Move grub-core/kern/emu/hostfs.c
|
||||
and grub-core/disk/host.c to ...
|
||||
(grub-fstest): ... here. Having the host disk implementation
|
||||
present confuses grub-probe and other utility programs.
|
||||
|
||||
* util/grub-mkconfig.in: Only verify readability of grub.cfg.new
|
||||
when writing to a file, not when writing to stdout.
|
||||
|
||||
2010-09-09 BVK Chaitanya <bvk.groups@gmail.com>
|
||||
|
||||
* tests/partmap_test.in: New test for partitions.
|
||||
* Makefile.util.def: Rules for new test.
|
||||
|
||||
2010-09-09 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* util/grub-probe.c (probe): Fix a pair of unhandled error
|
||||
conditions.
|
||||
|
||||
2010-09-09 Robert Millan <rmh@gnu.org>
|
||||
|
||||
Basic Btrfs support (detection and UUID).
|
||||
|
||||
* grub-core/fs/btrfs.c: New file.
|
||||
* Makefile.util.def (library): Register btrfs.c.
|
||||
* grub-core/Makefile.core.def: Likewise.
|
||||
|
||||
2010-09-08 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* util/grub-mkconfig_lib.in (is_path_readable_by_grub): Improve
|
||||
with (optional) parameters to specify device and relative path.
|
||||
* util/grub-install.in: Use is_path_readable_by_grub() to
|
||||
verify readability of a few critical files.
|
||||
* util/grub-mkconfig.in: Use is_path_readable_by_grub() to
|
||||
verify readability of grub.cfg.new.
|
||||
|
||||
2010-09-08 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Split minix.mod into minix.mod and minix2.mod.
|
||||
|
||||
* Makefile.util.def (libgrub.a): Add grub-core/fs/minix2.c.
|
||||
* grub-core/Makefile.core.def (minix2): New module.
|
||||
* grub-core/fs/minix.c: Use definitions instead of runtime version
|
||||
checking.
|
||||
* grub-core/fs/minix2.c: New file.
|
||||
|
||||
2010-09-08 Yves Blusseau <blusseau@zetam.org>
|
||||
|
||||
Add new --boot-directory option to replace --root-directory
|
||||
|
||||
* util/grub-install.in: Add new --boot-directory option
|
||||
* util/grub-reboot.in: Likewise.
|
||||
* util/grub-set-default.in: Likewise.
|
||||
|
||||
2010-09-08 Yves Blusseau <blusseau@zetam.org>
|
||||
|
||||
* util/grub-mkconfig.in: Use new variable.
|
||||
|
||||
2010-09-08 Yves Blusseau <blusseau@zetam.org>
|
||||
|
||||
* configure.ac: Define some useful variables.
|
||||
|
||||
2010-09-08 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/kern/ieee1275/cmain.c (grub_ieee1275_find_options): Set
|
||||
GRUB_IEEE1275_FLAG_HAS_CURSORONOFF when appropriate.
|
||||
* grub-core/term/ieee1275/ofconsole.c (grub_ofconsole_setcursor):
|
||||
Use terminfo and don't use cursor-on/cursor-off unless it's known
|
||||
to work.
|
||||
* include/grub/ieee1275/ieee1275.h (grub_ieee1275_flag): New element
|
||||
GRUB_IEEE1275_FLAG_HAS_CURSORONOFF.
|
||||
|
||||
2010-09-08 Colin Watson <cjwatson@ubuntu.com>
|
||||
|
||||
* grub-core/kern/efi/init.c (grub_efi_set_prefix): If the prefix
|
||||
starts with "(,", fill the drive containing the loaded image in
|
||||
between those two characters, but expect that a full partition
|
||||
specification including partition map names will follow.
|
||||
|
||||
2010-09-08 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* configure.ac: Remove `--enable-grub-fstest' option.
|
||||
* Makefile.util.def (grub-fstest): Remove COND_GRUB_FSTEST condition.
|
||||
|
||||
* util/grub-mkconfig_lib.in (is_path_readable_by_grub): Use
|
||||
`grub-fstest' instead of `grub-probe' for readability verification.
|
||||
* util/grub-probe.c (probe): Remove readability verification kludge.
|
||||
|
||||
2010-09-08 Robert Millan <rmh@gnu.org>
|
||||
|
||||
* util/grub-mkconfig.in: Pass `--device ${GRUB_DEVICE}' when
|
||||
initializing `GRUB_FS'.
|
||||
|
||||
2010-09-08 BVK Chaitanya <bvk.groups@gmail.com>
|
||||
|
||||
Not command (!) support to GRUB script.
|
||||
|
||||
* tests/grub_script_not.in: New test.
|
||||
* Makefile.util.def: Rules for new test.
|
||||
|
||||
* grub-core/script/execute.c (grub_script_execute_cmdline): Handle
|
||||
! command as a special case.
|
||||
* grub-core/script/yylex.l (GRUB_PARSER_TOKEN_NOT): Removed.
|
||||
|
||||
2010-09-07 BVK Chaitanya <bvk.groups@gmail.com>
|
||||
|
||||
* grub-core/commands/wildcard.c (wildcard_expand): Fix wrong
|
||||
grub_free.
|
||||
|
||||
2010-09-07 BVK Chaitanya <bvk.groups@gmail.com>
|
||||
|
||||
* docs/grub.texi (Shell-like scripting): Fix @dots to @dots{}.
|
||||
|
@ -677,6 +1460,15 @@
|
|||
* util/grub-mkimage.c (generate_image): Remove font support. All users
|
||||
updated.
|
||||
|
||||
2010-08-30 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Remove leftover embedding of font objects.
|
||||
|
||||
* include/grub/kernel.h (OBJ_TYPE_FONT): Removed.
|
||||
* util/grub-install.in (font): Removed.
|
||||
* util/grub-mkimage.c (generate_image): Remove font support. All users
|
||||
updated.
|
||||
|
||||
2010-08-30 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* docs/grub.texi (Network): Fix reference to pxe_blksize.
|
||||
|
|
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;
|
||||
|
@ -179,11 +179,13 @@ 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;
|
||||
};
|
||||
|
||||
program = {
|
||||
|
@ -230,14 +232,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)';
|
||||
|
@ -257,6 +256,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;
|
||||
|
@ -346,20 +355,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;
|
||||
|
@ -393,6 +400,11 @@ script = {
|
|||
installdir = noinst;
|
||||
};
|
||||
|
||||
script = {
|
||||
name = grub-kbdcomp;
|
||||
common = util/grub-kbdcomp.in;
|
||||
};
|
||||
|
||||
script = {
|
||||
name = grub-shell;
|
||||
common = tests/util/grub-shell.in;
|
||||
|
@ -531,6 +543,18 @@ script = {
|
|||
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;
|
||||
};
|
||||
|
||||
program = {
|
||||
testcase;
|
||||
name = example_unit_test;
|
||||
|
@ -543,3 +567,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 = '$(LIBDEVMAPPER)';
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
66
configure.ac
66
configure.ac
|
@ -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.
|
||||
|
@ -677,8 +698,8 @@ if test x"$missing_ncurses" = xtrue ; then
|
|||
AC_MSG_ERROR([grub-emu can't be compiled without ncurses])
|
||||
fi
|
||||
|
||||
if test x"$enable_grub_emu_usb" = xno ; then
|
||||
grub_emu_usb_excuse="explicitly disabled"
|
||||
if test x"$enable_grub_emu_usb" != xyes ; then
|
||||
grub_emu_usb_excuse="not enabled"
|
||||
fi
|
||||
|
||||
if test x"$enable_grub_emu_pci" = xyes ; then
|
||||
|
@ -762,19 +783,6 @@ AC_SUBST([enable_grub_emu_usb])
|
|||
AC_SUBST([enable_grub_emu_pci])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE([grub-fstest],
|
||||
[AS_HELP_STRING([--enable-grub-fstest],
|
||||
[build and install the `grub-fstest' debugging utility (default=guessed)])])
|
||||
if test x"$enable_grub_fstest" = xno ; then
|
||||
grub_fstest_excuse="explicitly disabled"
|
||||
fi
|
||||
if test x"$grub_fstest_excuse" = x ; then
|
||||
enable_grub_fstest=yes
|
||||
else
|
||||
enable_grub_fstest=no
|
||||
fi
|
||||
AC_SUBST([enable_grub_fstest])
|
||||
|
||||
AC_ARG_ENABLE([grub-mkfont],
|
||||
[AS_HELP_STRING([--enable-grub-mkfont],
|
||||
[build and install the `grub-mkfont' utility (default=guessed)])])
|
||||
|
@ -788,12 +796,12 @@ if test x"$grub_mkfont_excuse" = x ; then
|
|||
if test "x$FREETYPE" = x ; then
|
||||
grub_mkfont_excuse=["need freetype2 library"]
|
||||
fi
|
||||
freetype_cflags=`freetype-config --cflags`
|
||||
freetype_libs=`freetype-config --libs`
|
||||
fi
|
||||
|
||||
if test x"$grub_mkfont_excuse" = x ; then
|
||||
# Check for freetype libraries.
|
||||
freetype_cflags=`freetype-config --cflags`
|
||||
freetype_libs=`freetype-config --libs`
|
||||
SAVED_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $freetype_cflags"
|
||||
AC_CHECK_HEADERS([ft2build.h], [],
|
||||
|
@ -859,20 +867,8 @@ 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)])
|
||||
|
||||
|
@ -892,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])
|
||||
|
@ -905,7 +902,6 @@ 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])
|
||||
|
@ -931,6 +927,7 @@ 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_OUTPUT
|
||||
|
@ -970,11 +967,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
|
||||
|
|
|
@ -2415,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
|
||||
|
||||
|
||||
|
@ -2907,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.
|
|
@ -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
|
||||
|
|
|
@ -10,20 +10,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)';
|
||||
|
||||
|
@ -138,6 +138,7 @@ kernel = {
|
|||
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;
|
||||
|
@ -150,6 +151,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;
|
||||
|
@ -173,6 +175,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;
|
||||
|
@ -187,7 +191,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;
|
||||
};
|
||||
|
@ -200,7 +204,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;
|
||||
};
|
||||
|
@ -319,25 +323,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 = {
|
||||
|
@ -404,7 +402,7 @@ module = {
|
|||
module = {
|
||||
name = acpi;
|
||||
|
||||
x86 = commands/acpi.c;
|
||||
common = commands/acpi.c;
|
||||
x86_efi = commands/efi/acpi.c;
|
||||
i386_pc = commands/i386/pc/acpi.c;
|
||||
i386_coreboot = commands/i386/pc/acpi.c;
|
||||
|
@ -416,6 +414,33 @@ module = {
|
|||
enable = i386_multiboot;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = lsacpi;
|
||||
|
||||
common = commands/lsacpi.c;
|
||||
|
||||
enable = x86_efi;
|
||||
enable = i386_pc;
|
||||
enable = i386_coreboot;
|
||||
enable = i386_multiboot;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = lsefisystab;
|
||||
|
||||
common = commands/efi/lsefisystab.c;
|
||||
|
||||
enable = x86_efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = lssal;
|
||||
|
||||
common = commands/efi/lssal.c;
|
||||
|
||||
enable = x86_efi;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = blocklist;
|
||||
common = commands/blocklist.c;
|
||||
|
@ -425,6 +450,7 @@ module = {
|
|||
name = boot;
|
||||
common = commands/boot.c;
|
||||
i386_pc = lib/i386/pc/biosnum.c;
|
||||
enable = videomodules;
|
||||
};
|
||||
|
||||
module = {
|
||||
|
@ -493,6 +519,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;
|
||||
|
@ -673,15 +703,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 = {
|
||||
|
@ -835,6 +858,11 @@ module = {
|
|||
common = fs/befs_be.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = btrfs;
|
||||
common = fs/btrfs.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = cpio;
|
||||
common = fs/cpio.c;
|
||||
|
@ -880,6 +908,11 @@ module = {
|
|||
common = fs/minix.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = minix2;
|
||||
common = fs/minix2.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = nilfs2;
|
||||
common = fs/nilfs2.c;
|
||||
|
@ -1089,6 +1122,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;
|
||||
|
@ -1384,6 +1418,14 @@ module = {
|
|||
common = hook/datehook.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = legacycfg;
|
||||
common = commands/legacycfg.c;
|
||||
common = lib/legacy_parse.c;
|
||||
enable = i386_pc;
|
||||
enable = emu;
|
||||
};
|
||||
|
||||
module = {
|
||||
name = test_blockarg;
|
||||
common = tests/test_blockarg.c;
|
||||
|
@ -1402,3 +1444,15 @@ 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;
|
||||
};
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <config.h>
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/i386/pc/memory.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/machine/boot.h>
|
||||
#include <grub/machine/kernel.h>
|
||||
|
|
|
@ -98,7 +98,6 @@ struct grub_ohci
|
|||
struct grub_pci_dma_chunk *td_chunk;
|
||||
struct grub_ohci *next;
|
||||
grub_ohci_td_t td_free; /* Pointer to first free TD */
|
||||
int bad_OHCI;
|
||||
};
|
||||
|
||||
static struct grub_ohci *ohci;
|
||||
|
@ -149,8 +148,8 @@ typedef enum
|
|||
#define GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE (1 << 4)
|
||||
|
||||
#define GRUB_OHCI_RESET_CONNECT_CHANGE (1 << 16)
|
||||
#define GRUB_OHCI_CTRL_EDS 16
|
||||
#define GRUB_OHCI_BULK_EDS 16
|
||||
#define GRUB_OHCI_CTRL_EDS 256
|
||||
#define GRUB_OHCI_BULK_EDS 510
|
||||
#define GRUB_OHCI_TDS 256
|
||||
|
||||
#define GRUB_OHCI_ED_ADDR_MASK 0x7ff
|
||||
|
@ -442,8 +441,10 @@ grub_ohci_pci_iter (grub_pci_device_t dev,
|
|||
(grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA)
|
||||
& ~GRUB_OHCI_RHUB_PORT_POWER_MASK)
|
||||
| GRUB_OHCI_RHUB_PORT_ALL_POWERED);
|
||||
#if 0 /* We don't need it at all, handled via hotplugging */
|
||||
/* Now we have hot-plugging, we need to wait for stable power only */
|
||||
grub_millisleep (100);
|
||||
#endif
|
||||
|
||||
/* Link to ohci now that initialisation is successful. */
|
||||
o->next = ohci;
|
||||
|
@ -623,7 +624,8 @@ grub_ohci_transaction (grub_ohci_td_t td,
|
|||
break;
|
||||
}
|
||||
|
||||
/* Set the token (Always generate interrupt - bits 21-23 = 0). */
|
||||
/* Set the token */
|
||||
token |= ( 7 << 21); /* Never generate interrupt */
|
||||
token |= toggle << 24;
|
||||
token |= 1 << 25;
|
||||
|
||||
|
@ -652,36 +654,31 @@ grub_ohci_transaction (grub_ohci_td_t td,
|
|||
td->next_td = 0;
|
||||
}
|
||||
|
||||
struct grub_ohci_transfer_controller_data
|
||||
{
|
||||
grub_uint32_t tderr_phys;
|
||||
grub_uint32_t td_last_phys;
|
||||
grub_ohci_ed_t ed_virt;
|
||||
grub_ohci_td_t td_current_virt;
|
||||
grub_ohci_td_t td_head_virt;
|
||||
};
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_ohci_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer, int timeout,
|
||||
grub_size_t *actual)
|
||||
grub_ohci_setup_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer)
|
||||
{
|
||||
struct grub_ohci *o = (struct grub_ohci *) dev->data;
|
||||
grub_ohci_ed_t ed_virt;
|
||||
int bulk = 0;
|
||||
grub_ohci_td_t td_head_virt;
|
||||
grub_ohci_td_t td_current_virt;
|
||||
grub_ohci_td_t td_next_virt;
|
||||
grub_ohci_td_t tderr_virt = NULL;
|
||||
grub_uint32_t target;
|
||||
grub_uint32_t td_head_phys;
|
||||
grub_uint32_t td_tail_phys;
|
||||
grub_uint32_t td_last_phys;
|
||||
grub_uint32_t tderr_phys = 0;
|
||||
grub_uint32_t status;
|
||||
grub_uint32_t control;
|
||||
grub_uint8_t errcode = 0;
|
||||
grub_usb_err_t err = GRUB_USB_ERR_NONE;
|
||||
int i;
|
||||
grub_uint64_t maxtime;
|
||||
grub_uint64_t bad_OHCI_delay = 0;
|
||||
int err_halt = 0;
|
||||
int err_timeout = 0;
|
||||
int err_unrec = 0;
|
||||
grub_uint32_t intstatus;
|
||||
struct grub_ohci_transfer_controller_data *cdata;
|
||||
|
||||
*actual = 0;
|
||||
cdata = grub_zalloc (sizeof (*cdata));
|
||||
if (!cdata)
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
|
||||
/* Pre-set target for ED - we need it to find proper ED */
|
||||
/* Set the device address. */
|
||||
|
@ -703,21 +700,23 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
case GRUB_USB_TRANSACTION_TYPE_CONTROL:
|
||||
break;
|
||||
|
||||
default :
|
||||
default:
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
/* Find proper ED or add new ED */
|
||||
ed_virt = grub_ohci_find_ed (o, bulk, target);
|
||||
if (!ed_virt)
|
||||
cdata->ed_virt = grub_ohci_find_ed (o, bulk, target);
|
||||
if (!cdata->ed_virt)
|
||||
{
|
||||
grub_dprintf ("ohci","Fatal: No free ED !\n");
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
/* Take pointer to first TD from ED */
|
||||
td_head_phys = grub_le_to_cpu32 (ed_virt->td_head) & ~0xf;
|
||||
td_tail_phys = grub_le_to_cpu32 (ed_virt->td_tail) & ~0xf;
|
||||
td_head_phys = grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf;
|
||||
td_tail_phys = grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf;
|
||||
|
||||
/* Sanity check - td_head should be equal to td_tail */
|
||||
if (td_head_phys != td_tail_phys) /* Should never happen ! */
|
||||
|
@ -726,6 +725,7 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
grub_dprintf ("ohci", "HEAD = 0x%02x, TAIL = 0x%02x\n",
|
||||
td_head_phys, td_tail_phys);
|
||||
/* XXX: Fix: What to do ? */
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
|
@ -733,65 +733,62 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
* we must allocate the first TD. */
|
||||
if (!td_head_phys)
|
||||
{
|
||||
td_head_virt = grub_ohci_alloc_td (o);
|
||||
if (!td_head_virt)
|
||||
cdata->td_head_virt = grub_ohci_alloc_td (o);
|
||||
if (!cdata->td_head_virt)
|
||||
return GRUB_USB_ERR_INTERNAL; /* We don't need de-allocate ED */
|
||||
/* We can set td_head only when ED is not active, i.e.
|
||||
* when it is newly allocated. */
|
||||
ed_virt->td_head = grub_cpu_to_le32 ( grub_ohci_td_virt2phys (o,
|
||||
td_head_virt) );
|
||||
ed_virt->td_tail = ed_virt->td_head;
|
||||
cdata->ed_virt->td_head
|
||||
= grub_cpu_to_le32 (grub_ohci_td_virt2phys (o, cdata->td_head_virt));
|
||||
cdata->ed_virt->td_tail = cdata->ed_virt->td_head;
|
||||
}
|
||||
else
|
||||
td_head_virt = grub_ohci_td_phys2virt ( o, td_head_phys );
|
||||
cdata->td_head_virt = grub_ohci_td_phys2virt ( o, td_head_phys );
|
||||
|
||||
/* Set TDs */
|
||||
td_last_phys = td_head_phys; /* initial value to make compiler happy... */
|
||||
for (i = 0, td_current_virt = td_head_virt;
|
||||
cdata->td_last_phys = td_head_phys; /* initial value to make compiler happy... */
|
||||
for (i = 0, cdata->td_current_virt = cdata->td_head_virt;
|
||||
i < transfer->transcnt; i++)
|
||||
{
|
||||
grub_usb_transaction_t tr = &transfer->transactions[i];
|
||||
|
||||
grub_ohci_transaction (td_current_virt, tr->pid, tr->toggle,
|
||||
grub_ohci_transaction (cdata->td_current_virt, tr->pid, tr->toggle,
|
||||
tr->size, tr->data);
|
||||
|
||||
/* Set index of TD in transfer */
|
||||
td_current_virt->tr_index = (grub_uint32_t) i;
|
||||
|
||||
/* No IRQ request in TD if bad_OHCI set */
|
||||
if (o->bad_OHCI)
|
||||
td_current_virt->token |= grub_cpu_to_le32 ( 7 << 21);
|
||||
cdata->td_current_virt->tr_index = (grub_uint32_t) i;
|
||||
|
||||
/* Remember last used (processed) TD phys. addr. */
|
||||
td_last_phys = grub_ohci_td_virt2phys (o, td_current_virt);
|
||||
cdata->td_last_phys = grub_ohci_td_virt2phys (o, cdata->td_current_virt);
|
||||
|
||||
/* Allocate next TD */
|
||||
td_next_virt = grub_ohci_alloc_td (o);
|
||||
if (!td_next_virt) /* No free TD, cancel transfer and free TDs except head TD */
|
||||
{
|
||||
if (i) /* if i==0 we have nothing to free... */
|
||||
grub_ohci_free_tds (o,
|
||||
grub_ohci_td_phys2virt(o,
|
||||
grub_le_to_cpu32 (td_head_virt->next_td) ) );
|
||||
grub_ohci_free_tds (o, grub_ohci_td_phys2virt(o,
|
||||
grub_le_to_cpu32 (cdata->td_head_virt->next_td)));
|
||||
/* Reset head TD */
|
||||
grub_memset ( (void*)td_head_virt, 0,
|
||||
grub_memset ( (void*)cdata->td_head_virt, 0,
|
||||
sizeof(struct grub_ohci_td) );
|
||||
grub_dprintf ("ohci", "Fatal: No free TD !");
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
/* Chain TDs */
|
||||
td_current_virt->link_td = td_next_virt;
|
||||
td_current_virt->next_td = grub_cpu_to_le32 (
|
||||
|
||||
cdata->td_current_virt->link_td = td_next_virt;
|
||||
cdata->td_current_virt->next_td = grub_cpu_to_le32 (
|
||||
grub_ohci_td_virt2phys (o,
|
||||
td_next_virt) );
|
||||
td_next_virt->prev_td_phys = grub_ohci_td_virt2phys (o,
|
||||
td_current_virt);
|
||||
td_current_virt = td_next_virt;
|
||||
cdata->td_current_virt);
|
||||
cdata->td_current_virt = td_next_virt;
|
||||
}
|
||||
|
||||
grub_dprintf ("ohci", "Tail TD (not processed) = %p\n",
|
||||
td_current_virt);
|
||||
cdata->td_current_virt);
|
||||
|
||||
/* Setup the Endpoint Descriptor for transfer. */
|
||||
/* First set necessary fields in TARGET but keep (or set) skip bit */
|
||||
|
@ -799,12 +796,12 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
* size never change after first allocation of ED.
|
||||
* But unfortunately max. packet size may change during initial
|
||||
* setup sequence and we must handle it. */
|
||||
ed_virt->target = grub_cpu_to_le32 (target | (1 << 14));
|
||||
cdata->ed_virt->target = grub_cpu_to_le32 (target | (1 << 14));
|
||||
/* Set td_tail */
|
||||
ed_virt->td_tail
|
||||
= grub_cpu_to_le32 (grub_ohci_td_virt2phys (o, td_current_virt));
|
||||
cdata->ed_virt->td_tail
|
||||
= grub_cpu_to_le32 (grub_ohci_td_virt2phys (o, cdata->td_current_virt));
|
||||
/* Now reset skip bit */
|
||||
ed_virt->target = grub_cpu_to_le32 (target);
|
||||
cdata->ed_virt->target = grub_cpu_to_le32 (target);
|
||||
/* ed_virt->td_head = grub_cpu_to_le32 (td_head); Must not be changed, it is maintained by OHCI */
|
||||
/* ed_virt->next_ed = grub_cpu_to_le32 (0); Handled by grub_ohci_find_ed, do not change ! */
|
||||
|
||||
|
@ -834,93 +831,21 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
}
|
||||
}
|
||||
|
||||
/* Safety measure to avoid a hang. */
|
||||
maxtime = grub_get_time_ms () + timeout;
|
||||
|
||||
/* Wait until the transfer is completed or STALLs. */
|
||||
do
|
||||
{
|
||||
/* Check transfer status */
|
||||
intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
|
||||
if (!o->bad_OHCI && (intstatus & 0x2) != 0)
|
||||
{
|
||||
/* Remember last successful TD */
|
||||
tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf;
|
||||
/* Reset DoneHead */
|
||||
o->hcca->donehead = 0;
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
|
||||
/* Read back of register should ensure it is really written */
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
|
||||
/* if TD is last, finish */
|
||||
if (tderr_phys == td_last_phys)
|
||||
{
|
||||
if (grub_le_to_cpu32 (ed_virt->td_head) & 1)
|
||||
err_halt = 1;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
transfer->controller_data = cdata;
|
||||
|
||||
if ((intstatus & 0x10) != 0)
|
||||
{ /* Unrecoverable error - only reset can help...! */
|
||||
err_unrec = 1;
|
||||
break;
|
||||
}
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Detected a HALT. */
|
||||
if (err_halt || (grub_le_to_cpu32 (ed_virt->td_head) & 1))
|
||||
{
|
||||
err_halt = 1;
|
||||
/* ED is halted, but donehead event can happened in the meantime */
|
||||
intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
|
||||
if (!o->bad_OHCI && (intstatus & 0x2) != 0)
|
||||
/* Don't break loop now, first do donehead action(s) */
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
/* bad OHCI handling */
|
||||
if ( (grub_le_to_cpu32 (ed_virt->td_head) & ~0xf) ==
|
||||
(grub_le_to_cpu32 (ed_virt->td_tail) & ~0xf) ) /* Empty ED */
|
||||
{
|
||||
if (o->bad_OHCI) /* Bad OHCI detected previously */
|
||||
{
|
||||
/* Try get last successful TD. */
|
||||
tderr_phys = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf;
|
||||
if (tderr_phys)/* Reset DoneHead if we were successful */
|
||||
{
|
||||
o->hcca->donehead = 0;
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
|
||||
/* Read back of register should ensure it is really written */
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
|
||||
}
|
||||
/* Check the HALT bit */
|
||||
if (grub_le_to_cpu32 (ed_virt->td_head) & 1)
|
||||
err_halt = 1;
|
||||
break;
|
||||
}
|
||||
else /* Detection of bad OHCI */
|
||||
/* We should wait short time (~2ms) before we say that
|
||||
* it is bad OHCI to prevent some hazard -
|
||||
* donehead can react in the meantime. This waiting is done
|
||||
* only once per OHCI driver "live cycle". */
|
||||
if (!bad_OHCI_delay) /* Set delay time */
|
||||
bad_OHCI_delay = grub_get_time_ms () + 2;
|
||||
else if (grub_get_time_ms () >= bad_OHCI_delay)
|
||||
o->bad_OHCI = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Timeout ? */
|
||||
if (grub_get_time_ms () > maxtime)
|
||||
{
|
||||
err_timeout = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
grub_cpu_idle ();
|
||||
}
|
||||
while (1);
|
||||
static void
|
||||
pre_finish_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer)
|
||||
{
|
||||
struct grub_ohci *o = dev->data;
|
||||
struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
grub_uint32_t target;
|
||||
grub_uint32_t status;
|
||||
grub_uint32_t control;
|
||||
grub_uint32_t intstatus;
|
||||
|
||||
/* There are many ways how the loop above can finish:
|
||||
* - normally without any error via INTSTATUS WDH bit
|
||||
|
@ -952,8 +877,8 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
/* Remember target for debug and set skip flag in ED */
|
||||
/* It should be normaly not necessary but we need it at least
|
||||
* in case of timeout */
|
||||
target = grub_le_to_cpu32 ( ed_virt->target );
|
||||
ed_virt->target = grub_cpu_to_le32 (target | (1 << 14));
|
||||
target = grub_le_to_cpu32 ( cdata->ed_virt->target );
|
||||
cdata->ed_virt->target = grub_cpu_to_le32 (target | (1 << 14));
|
||||
/* Read registers for debug - they should be read now because
|
||||
* debug prints case unwanted delays, so something can happen
|
||||
* in the meantime... */
|
||||
|
@ -963,253 +888,321 @@ grub_ohci_transfer (grub_usb_controller_t dev,
|
|||
/* Now print debug values - to have full info what happened */
|
||||
grub_dprintf ("ohci", "loop finished: control=0x%02x status=0x%02x\n",
|
||||
control, status);
|
||||
grub_dprintf ("ohci", "intstatus=0x%02x \n\t\t tderr_phys=0x%02x, td_last_phys=0x%02x\n",
|
||||
intstatus, tderr_phys, td_last_phys);
|
||||
grub_dprintf ("ohci", "err_unrec=%d, err_timeout=%d \n\t\t err_halt=%d, bad_OHCI=%d\n",
|
||||
err_unrec, err_timeout, err_halt, o->bad_OHCI);
|
||||
grub_dprintf ("ohci", "intstatus=0x%02x, td_last_phys=0x%02x\n",
|
||||
intstatus, cdata->td_last_phys);
|
||||
grub_dprintf ("ohci", "TARGET=0x%02x, HEAD=0x%02x, TAIL=0x%02x\n",
|
||||
target,
|
||||
grub_le_to_cpu32 (ed_virt->td_head),
|
||||
grub_le_to_cpu32 (ed_virt->td_tail) );
|
||||
grub_le_to_cpu32 (cdata->ed_virt->td_head),
|
||||
grub_le_to_cpu32 (cdata->ed_virt->td_tail) );
|
||||
|
||||
if (!err_halt && !err_unrec && !err_timeout) /* normal finish */
|
||||
{
|
||||
/* Simple workaround if donehead is not working */
|
||||
if (o->bad_OHCI &&
|
||||
( !tderr_phys || (tderr_phys != td_last_phys) ) )
|
||||
{
|
||||
grub_dprintf ("ohci", "normal finish, but tderr_phys corrected\n");
|
||||
tderr_phys = td_last_phys;
|
||||
/* I hope we can do it as transfer (most probably) finished OK */
|
||||
}
|
||||
/* Prepare pointer to last processed TD */
|
||||
tderr_virt = grub_ohci_td_phys2virt (o, tderr_phys);
|
||||
/* Set index of last processed TD */
|
||||
if (tderr_virt)
|
||||
transfer->last_trans = tderr_virt->tr_index;
|
||||
else
|
||||
transfer->last_trans = -1;
|
||||
*actual = transfer->size + 1;
|
||||
}
|
||||
}
|
||||
|
||||
else if (err_halt) /* error, ED is halted by OHCI, i.e. can be modified */
|
||||
{
|
||||
/* First we must get proper tderr_phys value */
|
||||
if (o->bad_OHCI) /* In case of bad_OHCI tderr_phys can be wrong */
|
||||
{
|
||||
if ( tderr_phys ) /* check if tderr_phys points to TD with error */
|
||||
errcode = grub_le_to_cpu32 ( grub_ohci_td_phys2virt (o,
|
||||
tderr_phys)->token )
|
||||
>> 28;
|
||||
if ( !tderr_phys || !errcode ) /* tderr_phys not valid or points to wrong TD */
|
||||
{ /* Retired TD with error should be previous TD to ED->td_head */
|
||||
tderr_phys = grub_ohci_td_phys2virt (o,
|
||||
grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf )
|
||||
->prev_td_phys;
|
||||
}
|
||||
}
|
||||
|
||||
/* Even if we have "good" OHCI, in some cases
|
||||
* tderr_phys can be zero, check it */
|
||||
else if ( !tderr_phys )
|
||||
{ /* Retired TD with error should be previous TD to ED->td_head */
|
||||
tderr_phys = grub_ohci_td_phys2virt (o,
|
||||
grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf )
|
||||
->prev_td_phys;
|
||||
}
|
||||
|
||||
/* Prepare pointer to last processed TD and get error code */
|
||||
tderr_virt = grub_ohci_td_phys2virt (o, tderr_phys);
|
||||
/* Set index of last processed TD */
|
||||
if (tderr_virt)
|
||||
{
|
||||
errcode = grub_le_to_cpu32 ( tderr_virt->token ) >> 28;
|
||||
transfer->last_trans = tderr_virt->tr_index;
|
||||
}
|
||||
else
|
||||
transfer->last_trans = -1;
|
||||
|
||||
/* Evaluation of error code */
|
||||
grub_dprintf ("ohci", "OHCI tderr_phys=0x%02x, errcode=0x%02x\n",
|
||||
tderr_phys, errcode);
|
||||
switch (errcode)
|
||||
{
|
||||
case 0:
|
||||
/* XXX: Should not happen! */
|
||||
grub_error (GRUB_ERR_IO, "OHCI failed without reporting the reason");
|
||||
err = GRUB_USB_ERR_INTERNAL;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* XXX: CRC error. */
|
||||
err = GRUB_USB_ERR_TIMEOUT;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
err = GRUB_USB_ERR_BITSTUFF;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* XXX: Data Toggle error. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
err = GRUB_USB_ERR_STALL;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
/* XXX: Not responding. */
|
||||
err = GRUB_USB_ERR_TIMEOUT;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
/* XXX: PID Check bits failed. */
|
||||
err = GRUB_USB_ERR_BABBLE;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
/* XXX: PID unexpected failed. */
|
||||
err = GRUB_USB_ERR_BABBLE;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
/* XXX: Data overrun error. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n",
|
||||
tderr_virt, tderr_virt->tr_index);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
/* XXX: Data underrun error. */
|
||||
grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n",
|
||||
tderr_virt, tderr_virt->tr_index);
|
||||
if (transfer->last_trans == -1)
|
||||
break;
|
||||
*actual = transfer->transactions[transfer->last_trans].size
|
||||
- (grub_le_to_cpu32 (tderr_virt->buffer_end)
|
||||
- grub_le_to_cpu32 (tderr_virt->buffer))
|
||||
+ transfer->transactions[transfer->last_trans].preceding;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
/* XXX: Reserved. */
|
||||
err = GRUB_USB_ERR_NAK;
|
||||
break;
|
||||
|
||||
case 11:
|
||||
/* XXX: Reserved. */
|
||||
err = GRUB_USB_ERR_NAK;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
/* XXX: Buffer overrun. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
break;
|
||||
|
||||
case 13:
|
||||
/* XXX: Buffer underrun. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
break;
|
||||
|
||||
default:
|
||||
err = GRUB_USB_ERR_NAK;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else if (err_unrec)
|
||||
{
|
||||
/* Don't try to get error code and last processed TD for proper
|
||||
* toggle bit value - anything can be invalid */
|
||||
err = GRUB_USB_ERR_UNRECOVERABLE;
|
||||
grub_dprintf("ohci", "Unrecoverable error!");
|
||||
|
||||
/* Do OHCI reset in case of unrecoverable error - maybe we will need
|
||||
* do more - re-enumerate bus etc. (?) */
|
||||
|
||||
/* Suspend the OHCI by issuing a reset. */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */
|
||||
/* Read back of register should ensure it is really written */
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
|
||||
grub_millisleep (1);
|
||||
grub_dprintf ("ohci", "Unrecoverable error - OHCI reset\n");
|
||||
|
||||
/* Misc. resets. */
|
||||
o->hcca->donehead = 0;
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, o->ed_ctrl_addr);
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0);
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, o->ed_bulk_addr);
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0);
|
||||
/* Read back of register should ensure it is really written */
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
|
||||
|
||||
/* Enable the OHCI. */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL,
|
||||
(2 << 6)
|
||||
| GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE
|
||||
| GRUB_OHCI_REG_CONTROL_BULK_ENABLE );
|
||||
}
|
||||
|
||||
else if (err_timeout)
|
||||
{
|
||||
/* In case of timeout do not detect error from TD */
|
||||
err = GRUB_ERR_TIMEOUT;
|
||||
grub_dprintf("ohci", "Timeout !\n");
|
||||
|
||||
/* We should wait for next SOF to be sure that ED is unaccessed
|
||||
* by OHCI */
|
||||
/* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2));
|
||||
/* Wait for new SOF */
|
||||
while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0);
|
||||
|
||||
/* Now we must find last processed TD if bad_OHCI == TRUE */
|
||||
if (o->bad_OHCI)
|
||||
{ /* Retired TD with error should be previous TD to ED->td_head */
|
||||
tderr_phys = grub_ohci_td_phys2virt (o,
|
||||
grub_le_to_cpu32 ( ed_virt->td_head) & ~0xf)
|
||||
->prev_td_phys;
|
||||
}
|
||||
tderr_virt = grub_ohci_td_phys2virt (o, tderr_phys);
|
||||
if (tderr_virt)
|
||||
transfer->last_trans = tderr_virt->tr_index;
|
||||
else
|
||||
transfer->last_trans = -1;
|
||||
}
|
||||
static void
|
||||
finish_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer)
|
||||
{
|
||||
struct grub_ohci *o = dev->data;
|
||||
struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
|
||||
/* Set empty ED - set HEAD = TAIL = last (not processed) TD */
|
||||
ed_virt->td_head = grub_cpu_to_le32 (grub_le_to_cpu32 (ed_virt->td_tail) & ~0xf);
|
||||
cdata->ed_virt->td_head = grub_cpu_to_le32 (grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf);
|
||||
|
||||
/* At this point always should be:
|
||||
* ED has skip bit set and halted or empty or after next SOF,
|
||||
* i.e. it is safe to free all TDs except last not processed
|
||||
* ED HEAD == TAIL == phys. addr. of td_current_virt */
|
||||
|
||||
/* Reset DoneHead - sanity cleanup */
|
||||
/* Un-chainig of last TD */
|
||||
if (cdata->td_current_virt->prev_td_phys)
|
||||
{
|
||||
grub_ohci_td_t td_prev_virt
|
||||
= grub_ohci_td_phys2virt (o, cdata->td_current_virt->prev_td_phys);
|
||||
|
||||
if (cdata->td_current_virt == (grub_ohci_td_t) td_prev_virt->link_td)
|
||||
td_prev_virt->link_td = 0;
|
||||
|
||||
cdata->td_current_virt->prev_td_phys = 0;
|
||||
}
|
||||
|
||||
grub_dprintf ("ohci", "OHCI finished, freeing\n");
|
||||
grub_ohci_free_tds (o, cdata->td_head_virt);
|
||||
grub_free (cdata);
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
parse_halt (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
grub_size_t *actual)
|
||||
{
|
||||
struct grub_ohci *o = dev->data;
|
||||
struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
grub_uint8_t errcode = 0;
|
||||
grub_usb_err_t err = GRUB_USB_ERR_NAK;
|
||||
grub_ohci_td_t tderr_virt = NULL;
|
||||
|
||||
*actual = 0;
|
||||
|
||||
pre_finish_transfer (dev, transfer);
|
||||
|
||||
/* First we must get proper tderr_phys value */
|
||||
/* Retired TD with error should be previous TD to ED->td_head */
|
||||
cdata->tderr_phys = grub_ohci_td_phys2virt (o,
|
||||
grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf )
|
||||
->prev_td_phys;
|
||||
|
||||
/* Prepare pointer to last processed TD and get error code */
|
||||
tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys);
|
||||
/* Set index of last processed TD */
|
||||
if (tderr_virt)
|
||||
{
|
||||
errcode = grub_le_to_cpu32 (tderr_virt->token) >> 28;
|
||||
transfer->last_trans = tderr_virt->tr_index;
|
||||
}
|
||||
else
|
||||
transfer->last_trans = -1;
|
||||
|
||||
/* Evaluation of error code */
|
||||
grub_dprintf ("ohci", "OHCI tderr_phys=0x%02x, errcode=0x%02x\n",
|
||||
cdata->tderr_phys, errcode);
|
||||
switch (errcode)
|
||||
{
|
||||
case 0:
|
||||
/* XXX: Should not happen! */
|
||||
grub_error (GRUB_ERR_IO, "OHCI failed without reporting the reason");
|
||||
err = GRUB_USB_ERR_INTERNAL;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* XXX: CRC error. */
|
||||
err = GRUB_USB_ERR_TIMEOUT;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
err = GRUB_USB_ERR_BITSTUFF;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* XXX: Data Toggle error. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
err = GRUB_USB_ERR_STALL;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
/* XXX: Not responding. */
|
||||
err = GRUB_USB_ERR_TIMEOUT;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
/* XXX: PID Check bits failed. */
|
||||
err = GRUB_USB_ERR_BABBLE;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
/* XXX: PID unexpected failed. */
|
||||
err = GRUB_USB_ERR_BABBLE;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
/* XXX: Data overrun error. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n",
|
||||
tderr_virt, tderr_virt->tr_index);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
/* XXX: Data underrun error. */
|
||||
grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n",
|
||||
tderr_virt, tderr_virt->tr_index);
|
||||
if (transfer->last_trans == -1)
|
||||
break;
|
||||
*actual = transfer->transactions[transfer->last_trans].size
|
||||
- (grub_le_to_cpu32 (tderr_virt->buffer_end)
|
||||
- grub_le_to_cpu32 (tderr_virt->buffer))
|
||||
+ transfer->transactions[transfer->last_trans].preceding;
|
||||
err = GRUB_USB_ERR_NONE;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
/* XXX: Reserved. */
|
||||
err = GRUB_USB_ERR_NAK;
|
||||
break;
|
||||
|
||||
case 11:
|
||||
/* XXX: Reserved. */
|
||||
err = GRUB_USB_ERR_NAK;
|
||||
break;
|
||||
|
||||
case 12:
|
||||
/* XXX: Buffer overrun. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
break;
|
||||
|
||||
case 13:
|
||||
/* XXX: Buffer underrun. */
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
break;
|
||||
|
||||
default:
|
||||
err = GRUB_USB_ERR_NAK;
|
||||
break;
|
||||
}
|
||||
|
||||
finish_transfer (dev, transfer);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
parse_success (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
grub_size_t *actual)
|
||||
{
|
||||
struct grub_ohci *o = dev->data;
|
||||
struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
grub_ohci_td_t tderr_virt = NULL;
|
||||
|
||||
pre_finish_transfer (dev, transfer);
|
||||
|
||||
/* I hope we can do it as transfer (most probably) finished OK */
|
||||
cdata->tderr_phys = cdata->td_last_phys;
|
||||
|
||||
/* Prepare pointer to last processed TD */
|
||||
tderr_virt = grub_ohci_td_phys2virt (o, cdata->tderr_phys);
|
||||
|
||||
/* Set index of last processed TD */
|
||||
if (tderr_virt)
|
||||
transfer->last_trans = tderr_virt->tr_index;
|
||||
else
|
||||
transfer->last_trans = -1;
|
||||
*actual = transfer->size + 1;
|
||||
|
||||
finish_transfer (dev, transfer);
|
||||
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
parse_unrec (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
grub_size_t *actual)
|
||||
{
|
||||
struct grub_ohci *o = dev->data;
|
||||
|
||||
*actual = 0;
|
||||
|
||||
pre_finish_transfer (dev, transfer);
|
||||
|
||||
/* Don't try to get error code and last processed TD for proper
|
||||
* toggle bit value - anything can be invalid */
|
||||
grub_dprintf("ohci", "Unrecoverable error!");
|
||||
|
||||
/* Do OHCI reset in case of unrecoverable error - maybe we will need
|
||||
* do more - re-enumerate bus etc. (?) */
|
||||
|
||||
/* Suspend the OHCI by issuing a reset. */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */
|
||||
/* Read back of register should ensure it is really written */
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
|
||||
grub_millisleep (1);
|
||||
grub_dprintf ("ohci", "Unrecoverable error - OHCI reset\n");
|
||||
|
||||
/* Misc. resets. */
|
||||
o->hcca->donehead = 0;
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, o->ed_ctrl_addr);
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0);
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, o->ed_bulk_addr);
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0);
|
||||
/* Read back of register should ensure it is really written */
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
|
||||
|
||||
/* Un-chainig of last TD */
|
||||
if (td_current_virt->prev_td_phys)
|
||||
{
|
||||
grub_ohci_td_t td_prev_virt
|
||||
= grub_ohci_td_phys2virt (o, td_current_virt->prev_td_phys);
|
||||
/* Enable the OHCI. */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL,
|
||||
(2 << 6)
|
||||
| GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE
|
||||
| GRUB_OHCI_REG_CONTROL_BULK_ENABLE );
|
||||
finish_transfer (dev, transfer);
|
||||
|
||||
td_next_virt = (grub_ohci_td_t) td_prev_virt->link_td;
|
||||
if (td_current_virt == td_next_virt)
|
||||
td_prev_virt->link_td = 0;
|
||||
return GRUB_USB_ERR_UNRECOVERABLE;
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_ohci_check_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
grub_size_t *actual)
|
||||
{
|
||||
struct grub_ohci *o = dev->data;
|
||||
struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
grub_uint32_t intstatus;
|
||||
|
||||
/* Check transfer status */
|
||||
intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
|
||||
|
||||
if ((intstatus & 0x10) != 0)
|
||||
/* Unrecoverable error - only reset can help...! */
|
||||
return parse_unrec (dev, transfer, actual);
|
||||
|
||||
/* Detected a HALT. */
|
||||
if ((grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1))
|
||||
return parse_halt (dev, transfer, actual);
|
||||
|
||||
/* Finished ED detection */
|
||||
if ( (grub_le_to_cpu32 (cdata->ed_virt->td_head) & ~0xf) ==
|
||||
(grub_le_to_cpu32 (cdata->ed_virt->td_tail) & ~0xf) ) /* Empty ED */
|
||||
{
|
||||
/* Check the HALT bit */
|
||||
/* It looks like nonsense - it was tested previously...
|
||||
* but it can change because OHCI is working
|
||||
* simultaneously via DMA... */
|
||||
if (grub_le_to_cpu32 (cdata->ed_virt->td_head) & 1)
|
||||
return parse_halt (dev, transfer, actual);
|
||||
else
|
||||
return parse_success (dev, transfer, actual);
|
||||
}
|
||||
|
||||
grub_dprintf ("ohci", "OHCI finished, freeing, err=0x%02x, errcode=0x%02x\n",
|
||||
err, errcode);
|
||||
grub_ohci_free_tds (o, td_head_virt);
|
||||
return GRUB_USB_ERR_WAIT;
|
||||
}
|
||||
|
||||
return err;
|
||||
static grub_usb_err_t
|
||||
grub_ohci_cancel_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer)
|
||||
{
|
||||
struct grub_ohci *o = dev->data;
|
||||
struct grub_ohci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
grub_ohci_td_t tderr_virt = NULL;
|
||||
|
||||
pre_finish_transfer (dev, transfer);
|
||||
|
||||
grub_dprintf("ohci", "Timeout !\n");
|
||||
|
||||
/* We should wait for next SOF to be sure that ED is unaccessed
|
||||
* by OHCI */
|
||||
/* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2));
|
||||
/* Wait for new SOF */
|
||||
while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0);
|
||||
|
||||
/* Possible retired TD with error should be previous TD to ED->td_head */
|
||||
cdata->tderr_phys
|
||||
= grub_ohci_td_phys2virt (o, grub_le_to_cpu32 (cdata->ed_virt->td_head)
|
||||
& ~0xf)->prev_td_phys;
|
||||
|
||||
tderr_virt = grub_ohci_td_phys2virt (o,cdata-> tderr_phys);
|
||||
|
||||
grub_dprintf ("ohci", "Cancel: tderr_phys=0x%08x, tderr_virt=0x%08x\n",
|
||||
cdata->tderr_phys, (unsigned int)tderr_virt);
|
||||
|
||||
if (tderr_virt)
|
||||
transfer->last_trans = tderr_virt->tr_index;
|
||||
else
|
||||
transfer->last_trans = -1;
|
||||
|
||||
finish_transfer (dev, transfer);
|
||||
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
|
@ -1218,6 +1211,7 @@ grub_ohci_portstatus (grub_usb_controller_t dev,
|
|||
{
|
||||
struct grub_ohci *o = (struct grub_ohci *) dev->data;
|
||||
grub_uint64_t endtime;
|
||||
int i;
|
||||
|
||||
grub_dprintf ("ohci", "begin of portstatus=0x%02x\n",
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port));
|
||||
|
@ -1238,31 +1232,47 @@ grub_ohci_portstatus (grub_usb_controller_t dev,
|
|||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
/* Reset the port */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_SET_PORT_RESET);
|
||||
grub_millisleep (50); /* For root hub should be nominaly 50ms */
|
||||
|
||||
/* End the reset signaling. */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE);
|
||||
grub_millisleep (10);
|
||||
/* OHCI does one reset signal 10ms long but USB spec.
|
||||
* requests 50ms for root hub (no need to be continuous).
|
||||
* So, we do reset 5 times... */
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
/* Reset the port - timing of reset is done by OHCI */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_SET_PORT_RESET);
|
||||
|
||||
/* Enable the port and wait for it. */
|
||||
/* Wait for reset completion */
|
||||
endtime = grub_get_time_ms () + 1000;
|
||||
while (! (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)
|
||||
& GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE))
|
||||
if (grub_get_time_ms () > endtime)
|
||||
return grub_error (GRUB_ERR_IO, "OHCI Timed out - reset");
|
||||
|
||||
/* End the reset signaling - reset the reset status change */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE);
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
|
||||
}
|
||||
|
||||
/* Enable port */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_SET_PORT_ENABLE);
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port);
|
||||
|
||||
/* Wait for signal enabled */
|
||||
endtime = grub_get_time_ms () + 1000;
|
||||
while (! (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)
|
||||
& (1 << 1)))
|
||||
if (grub_get_time_ms () > endtime)
|
||||
return grub_error (GRUB_ERR_IO, "OHCI Timed out - enable");
|
||||
|
||||
grub_millisleep (10);
|
||||
|
||||
/* Reset bit Connect Status Change */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_RESET_CONNECT_CHANGE);
|
||||
|
||||
/* "Reset recovery time" (USB spec.) */
|
||||
grub_millisleep (10);
|
||||
|
||||
grub_dprintf ("ohci", "end of portstatus=0x%02x\n",
|
||||
grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port));
|
||||
|
||||
|
@ -1279,8 +1289,16 @@ grub_ohci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
|
|||
|
||||
grub_dprintf ("ohci", "detect_dev status=0x%02x\n", status);
|
||||
|
||||
/* Connect Status Change bit - it detects change of connection */
|
||||
*changed = ((status & GRUB_OHCI_RESET_CONNECT_CHANGE) != 0);
|
||||
/* Connect Status Change bit - it detects change of connection */
|
||||
if (status & GRUB_OHCI_RESET_CONNECT_CHANGE)
|
||||
{
|
||||
*changed = 1;
|
||||
/* Reset bit Connect Status Change */
|
||||
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
|
||||
GRUB_OHCI_RESET_CONNECT_CHANGE);
|
||||
}
|
||||
else
|
||||
*changed = 0;
|
||||
|
||||
if (! (status & 1))
|
||||
return GRUB_USB_SPEED_NONE;
|
||||
|
@ -1398,7 +1416,9 @@ static struct grub_usb_controller_dev usb_controller =
|
|||
{
|
||||
.name = "ohci",
|
||||
.iterate = grub_ohci_iterate,
|
||||
.transfer = grub_ohci_transfer,
|
||||
.setup_transfer = grub_ohci_setup_transfer,
|
||||
.check_transfer = grub_ohci_check_transfer,
|
||||
.cancel_transfer = grub_ohci_cancel_transfer,
|
||||
.hubports = grub_ohci_hubports,
|
||||
.portstatus = grub_ohci_portstatus,
|
||||
.detect_dev = grub_ohci_detect_dev
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#define GRUB_UHCI_IOMASK (0x7FF << 5)
|
||||
|
||||
#define N_QH 256
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GRUB_UHCI_REG_USBCMD = 0x00,
|
||||
|
@ -39,6 +41,21 @@ 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))
|
||||
};
|
||||
|
||||
#define
|
||||
|
||||
/* UHCI Queue Head. */
|
||||
struct grub_uhci_qh
|
||||
|
@ -87,7 +104,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 +113,8 @@ struct grub_uhci
|
|||
/* Free Transfer Descriptors. */
|
||||
grub_uhci_td_t tdfree;
|
||||
|
||||
int qh_busy[N_QH];
|
||||
|
||||
struct grub_uhci *next;
|
||||
};
|
||||
|
||||
|
@ -248,7 +267,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 +280,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 +350,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 +395,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 +417,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 +442,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 +461,35 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
|
|||
return td;
|
||||
}
|
||||
|
||||
struct grub_uhci_transfer_controller_data
|
||||
{
|
||||
grub_uhci_qh_t qh;
|
||||
grub_uhci_td_t td_first;
|
||||
};
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_uhci_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
int timeout, grub_size_t *actual)
|
||||
grub_uhci_setup_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer)
|
||||
{
|
||||
struct grub_uhci *u = (struct grub_uhci *) dev->data;
|
||||
grub_uhci_qh_t qh;
|
||||
grub_uhci_td_t td;
|
||||
grub_uhci_td_t td_first = NULL;
|
||||
grub_uhci_td_t td_prev = NULL;
|
||||
grub_usb_err_t err = GRUB_USB_ERR_NONE;
|
||||
int i;
|
||||
grub_uint64_t endtime;
|
||||
struct grub_uhci_transfer_controller_data *cdata;
|
||||
|
||||
*actual = 0;
|
||||
cdata = grub_malloc (sizeof (*cdata));
|
||||
if (!cdata)
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
|
||||
cdata->td_first = NULL;
|
||||
|
||||
/* Allocate a queue head for the transfer queue. */
|
||||
qh = grub_alloc_qh (u, GRUB_USB_TRANSACTION_TYPE_CONTROL);
|
||||
if (! qh)
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
cdata->qh = grub_alloc_qh (u, GRUB_USB_TRANSACTION_TYPE_CONTROL);
|
||||
if (! cdata->qh)
|
||||
{
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
}
|
||||
|
||||
grub_dprintf ("uhci", "transfer, iobase:%08x\n", u->iobase);
|
||||
|
||||
|
@ -465,23 +497,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 +532,112 @@ grub_uhci_transfer (grub_usb_controller_t dev,
|
|||
|
||||
/* Link it into the queue and terminate. Now the transaction can
|
||||
take place. */
|
||||
qh->elinkptr = (grub_uint32_t) (grub_addr_t) td_first;
|
||||
cdata->qh->elinkptr = (grub_uint32_t) (grub_addr_t) cdata->td_first;
|
||||
|
||||
grub_dprintf ("uhci", "initiate transaction\n");
|
||||
|
||||
/* Wait until either the transaction completed or an error
|
||||
occurred. */
|
||||
endtime = grub_get_time_ms () + timeout;
|
||||
for (;;)
|
||||
transfer->controller_data = cdata;
|
||||
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_uhci_check_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
grub_size_t *actual)
|
||||
{
|
||||
struct grub_uhci *u = (struct grub_uhci *) dev->data;
|
||||
grub_uhci_td_t errtd;
|
||||
struct grub_uhci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
|
||||
*actual = 0;
|
||||
|
||||
errtd = (grub_uhci_td_t) (cdata->qh->elinkptr & ~0x0f);
|
||||
|
||||
grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n",
|
||||
errtd->ctrl_status, errtd->buffer & (~15), errtd);
|
||||
|
||||
/* Check if the transaction completed. */
|
||||
if (cdata->qh->elinkptr & 1)
|
||||
{
|
||||
grub_uhci_td_t errtd;
|
||||
grub_dprintf ("uhci", "transaction complete\n");
|
||||
|
||||
errtd = (grub_uhci_td_t) (grub_addr_t) (qh->elinkptr & ~0x0f);
|
||||
/* Place the QH back in the free list and deallocate the associated
|
||||
TDs. */
|
||||
cdata->qh->elinkptr = 1;
|
||||
grub_free_queue (u, cdata->qh, cdata->td_first, transfer, actual);
|
||||
grub_free (cdata);
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_dprintf ("uhci", ">t status=0x%02x data=0x%02x td=%p\n",
|
||||
errtd->ctrl_status, errtd->buffer & (~15), errtd);
|
||||
grub_dprintf ("uhci", "t status=0x%02x\n", errtd->ctrl_status);
|
||||
|
||||
/* Check if the transaction completed. */
|
||||
if (qh->elinkptr & 1)
|
||||
break;
|
||||
|
||||
grub_dprintf ("uhci", "t status=0x%02x\n", errtd->ctrl_status);
|
||||
if (!(errtd->ctrl_status & (1 << 23)))
|
||||
{
|
||||
grub_usb_err_t err = GRUB_USB_ERR_NONE;
|
||||
|
||||
/* Check if the endpoint is stalled. */
|
||||
if (errtd->ctrl_status & (1 << 22))
|
||||
err = GRUB_USB_ERR_STALL;
|
||||
|
||||
|
||||
/* Check if an error related to the data buffer occurred. */
|
||||
if (errtd->ctrl_status & (1 << 21))
|
||||
else if (errtd->ctrl_status & (1 << 21))
|
||||
err = GRUB_USB_ERR_DATA;
|
||||
|
||||
|
||||
/* Check if a babble error occurred. */
|
||||
if (errtd->ctrl_status & (1 << 20))
|
||||
else if (errtd->ctrl_status & (1 << 20))
|
||||
err = GRUB_USB_ERR_BABBLE;
|
||||
|
||||
|
||||
/* Check if a NAK occurred. */
|
||||
if (errtd->ctrl_status & (1 << 19))
|
||||
else if (errtd->ctrl_status & (1 << 19))
|
||||
err = GRUB_USB_ERR_NAK;
|
||||
|
||||
|
||||
/* Check if a timeout occurred. */
|
||||
if (errtd->ctrl_status & (1 << 18))
|
||||
else if (errtd->ctrl_status & (1 << 18))
|
||||
err = GRUB_USB_ERR_TIMEOUT;
|
||||
|
||||
|
||||
/* Check if a bitstuff error occurred. */
|
||||
if (errtd->ctrl_status & (1 << 17))
|
||||
else if (errtd->ctrl_status & (1 << 17))
|
||||
err = GRUB_USB_ERR_BITSTUFF;
|
||||
|
||||
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
/* Fall through, no errors occurred, so the QH might be
|
||||
updated. */
|
||||
grub_dprintf ("uhci", "transaction fallthrough\n");
|
||||
|
||||
if (grub_get_time_ms () > endtime)
|
||||
{
|
||||
err = GRUB_USB_ERR_STALL;
|
||||
grub_dprintf ("uhci", "transaction timed out\n");
|
||||
goto fail;
|
||||
grub_dprintf ("uhci", "transaction failed\n");
|
||||
|
||||
/* Place the QH back in the free list and deallocate the associated
|
||||
TDs. */
|
||||
cdata->qh->elinkptr = 1;
|
||||
grub_free_queue (u, cdata->qh, cdata->td_first, transfer, actual);
|
||||
grub_free (cdata);
|
||||
|
||||
return err;
|
||||
}
|
||||
grub_cpu_idle ();
|
||||
}
|
||||
|
||||
grub_dprintf ("uhci", "transaction complete\n");
|
||||
/* Fall through, no errors occurred, so the QH might be
|
||||
updated. */
|
||||
grub_dprintf ("uhci", "transaction fallthrough\n");
|
||||
|
||||
fail:
|
||||
return GRUB_USB_ERR_WAIT;
|
||||
}
|
||||
|
||||
if (err != GRUB_USB_ERR_NONE)
|
||||
grub_dprintf ("uhci", "transaction failed\n");
|
||||
static grub_usb_err_t
|
||||
grub_uhci_cancel_transfer (grub_usb_controller_t dev,
|
||||
grub_usb_transfer_t transfer)
|
||||
{
|
||||
struct grub_uhci *u = (struct grub_uhci *) dev->data;
|
||||
grub_size_t actual;
|
||||
struct grub_uhci_transfer_controller_data *cdata = transfer->controller_data;
|
||||
|
||||
grub_dprintf ("uhci", "transaction cancel\n");
|
||||
|
||||
/* Place the QH back in the free list and deallocate the associated
|
||||
TDs. */
|
||||
qh->elinkptr = 1;
|
||||
grub_free_queue (u, td_first, transfer, actual);
|
||||
cdata->qh->elinkptr = 1;
|
||||
grub_free_queue (u, cdata->qh, cdata->td_first, transfer, &actual);
|
||||
grub_free (cdata);
|
||||
|
||||
return err;
|
||||
return GRUB_USB_ERR_NONE;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -622,7 +688,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 +696,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 +758,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 +788,9 @@ static struct grub_usb_controller_dev usb_controller =
|
|||
{
|
||||
.name = "uhci",
|
||||
.iterate = grub_uhci_iterate,
|
||||
.transfer = grub_uhci_transfer,
|
||||
.setup_transfer = grub_uhci_setup_transfer,
|
||||
.check_transfer = grub_uhci_check_transfer,
|
||||
.cancel_transfer = grub_uhci_cancel_transfer,
|
||||
.hubports = grub_uhci_hubports,
|
||||
.portstatus = grub_uhci_portstatus,
|
||||
.detect_dev = grub_uhci_detect_dev
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
/* USB Supports 127 devices, with device 0 as special case. */
|
||||
static struct grub_usb_device *grub_usb_devs[GRUB_USBHUB_MAX_DEVICES];
|
||||
|
||||
static int rescan = 0;
|
||||
|
||||
struct grub_usb_hub
|
||||
{
|
||||
struct grub_usb_hub *next;
|
||||
|
@ -110,9 +112,6 @@ grub_usb_add_hub (grub_usb_device_t dev)
|
|||
struct grub_usb_usb_hubdesc hubdesc;
|
||||
grub_err_t err;
|
||||
int i;
|
||||
grub_uint64_t timeout;
|
||||
grub_usb_device_t next_dev;
|
||||
grub_usb_device_t *attached_devices;
|
||||
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
|
@ -131,11 +130,9 @@ grub_usb_add_hub (grub_usb_device_t dev)
|
|||
grub_dprintf ("usb", "Hub set configuration\n");
|
||||
grub_usb_set_configuration (dev, 1);
|
||||
|
||||
attached_devices = grub_zalloc (hubdesc.portcnt
|
||||
* sizeof (attached_devices[0]));
|
||||
if (!attached_devices)
|
||||
dev->children = grub_zalloc (hubdesc.portcnt * sizeof (dev->children[0]));
|
||||
if (!dev->children)
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
dev->children = attached_devices;
|
||||
dev->nports = hubdesc.portcnt;
|
||||
|
||||
/* Power on all Hub ports. */
|
||||
|
@ -143,115 +140,36 @@ grub_usb_add_hub (grub_usb_device_t dev)
|
|||
{
|
||||
grub_dprintf ("usb", "Power on - port %d\n", i);
|
||||
/* Power on the port and wait for possible device connect */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_SET_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_PORT_POWER,
|
||||
i, 0, NULL);
|
||||
/* Just ignore the device if some error happened */
|
||||
if (err)
|
||||
continue;
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_SET_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_PORT_POWER,
|
||||
i, 0, NULL);
|
||||
}
|
||||
/* Wait for port power-on */
|
||||
if (hubdesc.pwdgood >= 50)
|
||||
grub_millisleep (hubdesc.pwdgood * 2);
|
||||
else
|
||||
grub_millisleep (100);
|
||||
|
||||
/* Iterate over the Hub ports. */
|
||||
for (i = 1; i <= hubdesc.portcnt; i++)
|
||||
|
||||
/* Rest will be done on next usb poll. */
|
||||
for (i = 0; i < dev->config[0].interf[0].descif->endpointcnt;
|
||||
i++)
|
||||
{
|
||||
grub_uint32_t status;
|
||||
struct grub_usb_desc_endp *endp = NULL;
|
||||
endp = &dev->config[0].interf[0].descendp[i];
|
||||
|
||||
/* Get the port status. */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_GET_STATUS,
|
||||
0, i, sizeof (status), (char *) &status);
|
||||
/* Just ignore the device if the Hub does not report the
|
||||
status. */
|
||||
if (err)
|
||||
continue;
|
||||
grub_dprintf ("usb", "Hub port %d status: 0x%02x\n", i, status);
|
||||
|
||||
/* If connected, reset and enable the port. */
|
||||
if (status & GRUB_USB_HUB_STATUS_CONNECTED)
|
||||
if ((endp->endp_addr & 128) && grub_usb_get_ep_type(endp)
|
||||
== GRUB_USB_EP_INTERRUPT)
|
||||
{
|
||||
grub_usb_speed_t speed;
|
||||
|
||||
/* Determine the device speed. */
|
||||
if (status & GRUB_USB_HUB_STATUS_LOWSPEED)
|
||||
speed = GRUB_USB_SPEED_LOW;
|
||||
else
|
||||
{
|
||||
if (status & GRUB_USB_HUB_STATUS_HIGHSPEED)
|
||||
speed = GRUB_USB_SPEED_HIGH;
|
||||
else
|
||||
speed = GRUB_USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
/* A device is actually connected to this port.
|
||||
* Now do reset of port. */
|
||||
grub_dprintf ("usb", "Reset hub port - port %d\n", i);
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_SET_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_PORT_RESET,
|
||||
i, 0, 0);
|
||||
/* If the Hub does not cooperate for this port, just skip
|
||||
the port. */
|
||||
if (err)
|
||||
continue;
|
||||
|
||||
/* Wait for reset procedure done */
|
||||
timeout = grub_get_time_ms () + 1000;
|
||||
do
|
||||
{
|
||||
/* Get the port status. */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_GET_STATUS,
|
||||
0, i, sizeof (status), (char *) &status);
|
||||
}
|
||||
while (!err &&
|
||||
!(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) &&
|
||||
(grub_get_time_ms() < timeout) );
|
||||
if (err || !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) )
|
||||
continue;
|
||||
|
||||
/* Wait a recovery time after reset, spec. says 10ms */
|
||||
grub_millisleep (10);
|
||||
|
||||
/* Do reset of connection change bit */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_CONNECTED,
|
||||
i, 0, 0);
|
||||
/* Just ignore the device if the Hub reports some error */
|
||||
if (err)
|
||||
continue;
|
||||
grub_dprintf ("usb", "Hub port - cleared connection change\n");
|
||||
|
||||
/* Add the device and assign a device address to it. */
|
||||
grub_dprintf ("usb", "Call hub_add_dev - port %d\n", i);
|
||||
next_dev = grub_usb_hub_add_dev (&dev->controller, speed);
|
||||
if (! next_dev)
|
||||
continue;
|
||||
|
||||
attached_devices[i - 1] = next_dev;
|
||||
|
||||
/* If the device is a Hub, scan it for more devices. */
|
||||
if (next_dev->descdev.class == 0x09)
|
||||
grub_usb_add_hub (next_dev);
|
||||
dev->hub_endpoint = endp;
|
||||
dev->hub_transfer
|
||||
= grub_usb_bulk_read_background (dev, endp->endp_addr,
|
||||
grub_min (endp->maxpacket,
|
||||
sizeof (dev->statuschange)),
|
||||
(char *) &dev->statuschange);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rescan = 1;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
|
@ -261,19 +179,45 @@ attach_root_port (struct grub_usb_hub *hub, int portno,
|
|||
{
|
||||
grub_usb_device_t dev;
|
||||
grub_err_t err;
|
||||
int total, i;
|
||||
grub_usb_speed_t current_speed = GRUB_USB_SPEED_NONE;
|
||||
int changed=0;
|
||||
|
||||
#if 0
|
||||
/* Specification does not say about disabling of port when device
|
||||
* connected. If disabling is really necessary for some devices,
|
||||
* delete this #if 0 and related #endif */
|
||||
/* Disable the port. XXX: Why? */
|
||||
err = hub->controller->dev->portstatus (hub->controller, portno, 0);
|
||||
if (err)
|
||||
return;
|
||||
#endif
|
||||
/* Wait for completion of insertion and stable power (USB spec.)
|
||||
* Should be at least 100ms, some devices requires more...
|
||||
* There is also another thing - some devices have worse contacts
|
||||
* and connected signal is unstable for some time - we should handle
|
||||
* it - but prevent deadlock in case when device is too faulty... */
|
||||
for (total = i = 0; (i < 250) && (total < 2000); i++, total++)
|
||||
{
|
||||
grub_millisleep (1);
|
||||
current_speed = hub->controller->dev->detect_dev
|
||||
(hub->controller, portno, &changed);
|
||||
if (current_speed == GRUB_USB_SPEED_NONE)
|
||||
i = 0;
|
||||
}
|
||||
grub_dprintf ("usb", "total=%d\n", total);
|
||||
if (total >= 2000)
|
||||
return;
|
||||
|
||||
/* Enable the port. */
|
||||
err = hub->controller->dev->portstatus (hub->controller, portno, 1);
|
||||
if (err)
|
||||
return;
|
||||
hub->controller->dev->pending_reset = grub_get_time_ms () + 5000;
|
||||
|
||||
/* Enable the port and create a device. */
|
||||
dev = grub_usb_hub_add_dev (hub->controller, speed);
|
||||
hub->controller->dev->pending_reset = 0;
|
||||
if (! dev)
|
||||
return;
|
||||
|
||||
|
@ -320,11 +264,14 @@ grub_usb_root_hub (grub_usb_controller_t controller)
|
|||
for (i = 0; i < hub->nports; i++)
|
||||
{
|
||||
grub_usb_speed_t speed;
|
||||
speed = controller->dev->detect_dev (hub->controller, i,
|
||||
&changed);
|
||||
if (!controller->dev->pending_reset)
|
||||
{
|
||||
speed = controller->dev->detect_dev (hub->controller, i,
|
||||
&changed);
|
||||
|
||||
if (speed != GRUB_USB_SPEED_NONE)
|
||||
attach_root_port (hub, i, speed);
|
||||
if (speed != GRUB_USB_SPEED_NONE)
|
||||
attach_root_port (hub, i, speed);
|
||||
}
|
||||
}
|
||||
|
||||
return GRUB_USB_ERR_NONE;
|
||||
|
@ -341,6 +288,9 @@ detach_device (grub_usb_device_t dev)
|
|||
return;
|
||||
if (dev->descdev.class == GRUB_USB_CLASS_HUB)
|
||||
{
|
||||
if (dev->hub_transfer)
|
||||
grub_usb_cancel_transfer (dev->hub_transfer);
|
||||
|
||||
for (i = 0; i < dev->nports; i++)
|
||||
detach_device (dev->children[i]);
|
||||
grub_free (dev->children);
|
||||
|
@ -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 = 0x%0x, i = %d, status = %08x\n",
|
||||
(unsigned int) dev, i, status);
|
||||
|
||||
if (err)
|
||||
continue;
|
||||
|
||||
if (status & GRUB_USB_HUB_STATUS_C_CONNECTED)
|
||||
/* FIXME: properly handle these conditions. */
|
||||
if (status & GRUB_USB_HUB_STATUS_C_PORT_ENABLED)
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_PORT_ENABLED, i, 0, 0);
|
||||
|
||||
if (status & GRUB_USB_HUB_STATUS_C_PORT_SUSPEND)
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_PORT_SUSPEND, i, 0, 0);
|
||||
|
||||
if (status & GRUB_USB_HUB_STATUS_C_PORT_OVERCURRENT)
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_PORT_OVERCURRENT, i, 0, 0);
|
||||
|
||||
if (!dev->controller.dev->pending_reset &&
|
||||
(status & GRUB_USB_HUB_STATUS_C_PORT_CONNECTED))
|
||||
{
|
||||
detach_device (attached_devices[i-1]);
|
||||
attached_devices[i - 1] = NULL;
|
||||
}
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_PORT_CONNECTED, i, 0, 0);
|
||||
|
||||
detach_device (dev->children[i - 1]);
|
||||
dev->children[i - 1] = NULL;
|
||||
|
||||
/* Connected and status of connection changed ? */
|
||||
if ((status & GRUB_USB_HUB_STATUS_CONNECTED)
|
||||
&& (status & GRUB_USB_HUB_STATUS_C_CONNECTED))
|
||||
{
|
||||
grub_usb_speed_t speed;
|
||||
|
||||
/* Determine the device speed. */
|
||||
if (status & GRUB_USB_HUB_STATUS_LOWSPEED)
|
||||
speed = GRUB_USB_SPEED_LOW;
|
||||
else
|
||||
/* Connected and status of connection changed ? */
|
||||
if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)
|
||||
{
|
||||
if (status & GRUB_USB_HUB_STATUS_HIGHSPEED)
|
||||
speed = GRUB_USB_SPEED_HIGH;
|
||||
else
|
||||
speed = GRUB_USB_SPEED_FULL;
|
||||
/* A device is actually connected to this port. */
|
||||
/* Wait for completion of insertion and stable power (USB spec.)
|
||||
* Should be at least 100ms, some devices requires more...
|
||||
* There is also another thing - some devices have worse contacts
|
||||
* and connected signal is unstable for some time - we should handle
|
||||
* it - but prevent deadlock in case when device is too faulty... */
|
||||
for (total = j = 0; (j < 250) && (total < 2000); j++, total++)
|
||||
{
|
||||
grub_millisleep (1);
|
||||
/* Get the port status. */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_GET_STATUS,
|
||||
0, i,
|
||||
sizeof (current_status),
|
||||
(char *) ¤t_status);
|
||||
if (err)
|
||||
{
|
||||
total = 2000;
|
||||
break;
|
||||
}
|
||||
if (!(current_status & GRUB_USB_HUB_STATUS_PORT_CONNECTED))
|
||||
j = 0;
|
||||
}
|
||||
grub_dprintf ("usb", "(non-root) total=%d\n", total);
|
||||
if (total >= 2000)
|
||||
continue;
|
||||
|
||||
/* Now do reset of port. */
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_SET_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_PORT_RESET,
|
||||
i, 0, 0);
|
||||
rescan = 1;
|
||||
/* We cannot reset more than one device at the same time !
|
||||
* Resetting more devices together results in very bad
|
||||
* situation: more than one device has default address 0
|
||||
* at the same time !!!
|
||||
* Additionaly, we cannot perform another reset
|
||||
* anywhere on the same OHCI controller until
|
||||
* we will finish addressing of reseted device ! */
|
||||
dev->controller.dev->pending_reset = grub_get_time_ms () + 5000;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* A device is actually connected to this port.
|
||||
* Now do reset of port. */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_SET_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_PORT_RESET,
|
||||
i, 0, 0);
|
||||
/* If the Hub does not cooperate for this port, just skip
|
||||
the port. */
|
||||
if (err)
|
||||
continue;
|
||||
if (status & GRUB_USB_HUB_STATUS_C_PORT_RESET)
|
||||
{
|
||||
grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_PORT_RESET, i, 0, 0);
|
||||
|
||||
/* Wait for reset procedure done */
|
||||
timeout = grub_get_time_ms () + 1000;
|
||||
do
|
||||
{
|
||||
/* Get the port status. */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_GET_STATUS,
|
||||
0, i, sizeof (status), (char *) &status);
|
||||
}
|
||||
while (!err &&
|
||||
!(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) &&
|
||||
(grub_get_time_ms() < timeout) );
|
||||
if (err || !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) )
|
||||
continue;
|
||||
if (status & GRUB_USB_HUB_STATUS_PORT_CONNECTED)
|
||||
{
|
||||
grub_usb_speed_t speed;
|
||||
grub_usb_device_t next_dev;
|
||||
|
||||
/* Wait a recovery time after reset, spec. says 10ms */
|
||||
grub_millisleep (10);
|
||||
/* Determine the device speed. */
|
||||
if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED)
|
||||
speed = GRUB_USB_SPEED_LOW;
|
||||
else
|
||||
{
|
||||
if (status & GRUB_USB_HUB_STATUS_PORT_HIGHSPEED)
|
||||
speed = GRUB_USB_SPEED_HIGH;
|
||||
else
|
||||
speed = GRUB_USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
/* Do reset of connection change bit */
|
||||
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
|
||||
| GRUB_USB_REQTYPE_CLASS
|
||||
| GRUB_USB_REQTYPE_TARGET_OTHER),
|
||||
GRUB_USB_REQ_CLEAR_FEATURE,
|
||||
GRUB_USB_HUB_FEATURE_C_CONNECTED,
|
||||
i, 0, 0);
|
||||
/* Just ignore the device if the Hub reports some error */
|
||||
if (err)
|
||||
continue;
|
||||
/* Wait a recovery time after reset, spec. says 10ms */
|
||||
grub_millisleep (10);
|
||||
|
||||
/* Add the device and assign a device address to it. */
|
||||
next_dev = grub_usb_hub_add_dev (&dev->controller, speed);
|
||||
if (! next_dev)
|
||||
continue;
|
||||
/* Add the device and assign a device address to it. */
|
||||
next_dev = grub_usb_hub_add_dev (&dev->controller, speed);
|
||||
dev->controller.dev->pending_reset = 0;
|
||||
if (! next_dev)
|
||||
continue;
|
||||
|
||||
attached_devices[i - 1] = next_dev;
|
||||
dev->children[i - 1] = next_dev;
|
||||
|
||||
/* If the device is a Hub, scan it for more devices. */
|
||||
if (next_dev->descdev.class == 0x09)
|
||||
grub_usb_add_hub (next_dev);
|
||||
/* If the device is a Hub, scan it for more devices. */
|
||||
if (next_dev->descdev.class == 0x09)
|
||||
grub_usb_add_hub (next_dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -476,12 +497,21 @@ grub_usb_poll_devices (void)
|
|||
/* No, it should be never changed, it should be constant. */
|
||||
for (i = 0; i < hub->nports; i++)
|
||||
{
|
||||
grub_usb_speed_t speed;
|
||||
grub_usb_speed_t speed = GRUB_USB_SPEED_NONE;
|
||||
int changed = 0;
|
||||
|
||||
speed = hub->controller->dev->detect_dev (hub->controller, i,
|
||||
&changed);
|
||||
|
||||
if (!hub->controller->dev->pending_reset)
|
||||
{
|
||||
/* Check for possible timeout */
|
||||
if (grub_get_time_ms () > hub->controller->dev->pending_reset)
|
||||
{
|
||||
/* Something went wrong, reset device was not
|
||||
* addressed properly, timeout happened */
|
||||
hub->controller->dev->pending_reset = 0;
|
||||
speed = hub->controller->dev->detect_dev (hub->controller,
|
||||
i, &changed);
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
detach_device (hub->devices[i]);
|
||||
|
@ -492,13 +522,21 @@ grub_usb_poll_devices (void)
|
|||
}
|
||||
}
|
||||
|
||||
/* We should check changes of non-root hubs too. */
|
||||
for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++)
|
||||
while (1)
|
||||
{
|
||||
grub_usb_device_t dev = grub_usb_devs[i];
|
||||
|
||||
if (dev && dev->descdev.class == 0x09)
|
||||
poll_nonroot_hub (dev);
|
||||
rescan = 0;
|
||||
|
||||
/* We should check changes of non-root hubs too. */
|
||||
for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++)
|
||||
{
|
||||
grub_usb_device_t dev = grub_usb_devs[i];
|
||||
|
||||
if (dev && dev->descdev.class == 0x09)
|
||||
poll_nonroot_hub (dev);
|
||||
}
|
||||
if (!rescan)
|
||||
break;
|
||||
grub_millisleep (50);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,41 @@
|
|||
#include <grub/misc.h>
|
||||
#include <grub/usb.h>
|
||||
#include <grub/usbtrans.h>
|
||||
#include <grub/time.h>
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_usb_execute_and_wait_transfer (grub_usb_device_t dev,
|
||||
grub_usb_transfer_t transfer,
|
||||
int timeout, grub_size_t *actual)
|
||||
{
|
||||
grub_usb_err_t err;
|
||||
grub_uint64_t endtime;
|
||||
|
||||
err = dev->controller.dev->setup_transfer (&dev->controller, transfer);
|
||||
if (err)
|
||||
return err;
|
||||
/* endtime moved behind setup transfer to prevent false timeouts
|
||||
* while debugging... */
|
||||
endtime = grub_get_time_ms () + timeout;
|
||||
while (1)
|
||||
{
|
||||
err = dev->controller.dev->check_transfer (&dev->controller, transfer,
|
||||
actual);
|
||||
if (!err)
|
||||
return GRUB_USB_ERR_NONE;
|
||||
if (err != GRUB_USB_ERR_WAIT)
|
||||
return err;
|
||||
if (grub_get_time_ms () > endtime)
|
||||
{
|
||||
err = dev->controller.dev->cancel_transfer (&dev->controller,
|
||||
transfer);
|
||||
if (err)
|
||||
return err;
|
||||
return GRUB_USB_ERR_TIMEOUT;
|
||||
}
|
||||
grub_cpu_idle ();
|
||||
}
|
||||
}
|
||||
|
||||
grub_usb_err_t
|
||||
grub_usb_control_msg (grub_usb_device_t dev,
|
||||
|
@ -147,8 +182,8 @@ grub_usb_control_msg (grub_usb_device_t dev,
|
|||
|
||||
transfer->transactions[datablocks + 1].toggle = 1;
|
||||
|
||||
err = dev->controller.dev->transfer (&dev->controller, transfer,
|
||||
1000, &actual);
|
||||
err = grub_usb_execute_and_wait_transfer (dev, transfer, 1000, &actual);
|
||||
|
||||
grub_dprintf ("usb", "control: err=%d\n", err);
|
||||
|
||||
grub_free (transfer->transactions);
|
||||
|
@ -162,22 +197,20 @@ grub_usb_control_msg (grub_usb_device_t dev,
|
|||
return err;
|
||||
}
|
||||
|
||||
static grub_usb_err_t
|
||||
grub_usb_bulk_readwrite (grub_usb_device_t dev,
|
||||
int endpoint, grub_size_t size0, char *data_in,
|
||||
grub_transfer_type_t type, int timeout,
|
||||
grub_size_t *actual)
|
||||
static grub_usb_transfer_t
|
||||
grub_usb_bulk_setup_readwrite (grub_usb_device_t dev,
|
||||
int endpoint, grub_size_t size0, char *data_in,
|
||||
grub_transfer_type_t type)
|
||||
{
|
||||
int i;
|
||||
grub_usb_transfer_t transfer;
|
||||
int datablocks;
|
||||
unsigned int max;
|
||||
grub_usb_err_t err;
|
||||
int toggle = dev->toggle[endpoint];
|
||||
volatile char *data;
|
||||
grub_uint32_t data_addr;
|
||||
struct grub_pci_dma_chunk *data_chunk;
|
||||
grub_size_t size = size0;
|
||||
int toggle = dev->toggle[endpoint];
|
||||
|
||||
grub_dprintf ("usb", "bulk: size=0x%02lx type=%d\n", (unsigned long) size,
|
||||
type);
|
||||
|
@ -185,7 +218,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
|
|||
/* FIXME: avoid allocation any kind of buffer in a first place. */
|
||||
data_chunk = grub_memalign_dma32 (128, size);
|
||||
if (!data_chunk)
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
return NULL;
|
||||
data = grub_dma_get_virt (data_chunk);
|
||||
data_addr = grub_dma_get_phys (data_chunk);
|
||||
if (type == GRUB_USB_TRANSFER_TYPE_OUT)
|
||||
|
@ -210,18 +243,21 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
|
|||
if (! transfer)
|
||||
{
|
||||
grub_dma_free (data_chunk);
|
||||
return grub_errno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
datablocks = ((size + max - 1) / max);
|
||||
transfer->transcnt = datablocks;
|
||||
transfer->size = size - 1;
|
||||
transfer->endpoint = endpoint & 15;
|
||||
transfer->endpoint = endpoint;
|
||||
transfer->devaddr = dev->addr;
|
||||
transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK;
|
||||
transfer->dir = type;
|
||||
transfer->max = max;
|
||||
transfer->dev = dev;
|
||||
transfer->last_trans = -1; /* Reset index of last processed transaction (TD) */
|
||||
transfer->data_chunk = data_chunk;
|
||||
transfer->data = data_in;
|
||||
|
||||
/* Allocate an array of transfer data structures. */
|
||||
transfer->transactions = grub_malloc (transfer->transcnt
|
||||
|
@ -230,7 +266,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
|
|||
{
|
||||
grub_free (transfer);
|
||||
grub_dma_free (data_chunk);
|
||||
return grub_errno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set up all transfers. */
|
||||
|
@ -248,25 +284,51 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
|
|||
tr->preceding = i * max;
|
||||
size -= tr->size;
|
||||
}
|
||||
return transfer;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_usb_bulk_finish_readwrite (grub_usb_transfer_t transfer)
|
||||
{
|
||||
grub_usb_device_t dev = transfer->dev;
|
||||
int toggle = dev->toggle[transfer->endpoint];
|
||||
|
||||
err = dev->controller.dev->transfer (&dev->controller, transfer, timeout,
|
||||
actual);
|
||||
/* We must remember proper toggle value even if some transactions
|
||||
* were not processed - correct value should be inversion of last
|
||||
* processed transaction (TD). */
|
||||
if (transfer->last_trans >= 0)
|
||||
toggle = transfer->transactions[transfer->last_trans].toggle ? 0 : 1;
|
||||
else
|
||||
toggle = dev->toggle[endpoint]; /* Nothing done, take original */
|
||||
grub_dprintf ("usb", "bulk: err=%d, toggle=%d\n", err, toggle);
|
||||
dev->toggle[endpoint] = toggle;
|
||||
toggle = dev->toggle[transfer->endpoint]; /* Nothing done, take original */
|
||||
grub_dprintf ("usb", "bulk: toggle=%d\n", toggle);
|
||||
dev->toggle[transfer->endpoint] = toggle;
|
||||
|
||||
if (transfer->dir == GRUB_USB_TRANSFER_TYPE_IN)
|
||||
grub_memcpy (transfer->data, (void *)
|
||||
grub_dma_get_virt (transfer->data_chunk),
|
||||
transfer->size + 1);
|
||||
|
||||
grub_free (transfer->transactions);
|
||||
grub_free (transfer);
|
||||
grub_dma_free (data_chunk);
|
||||
grub_dma_free (transfer->data_chunk);
|
||||
}
|
||||
|
||||
if (type == GRUB_USB_TRANSFER_TYPE_IN)
|
||||
grub_memcpy (data_in, (char *) data, size0);
|
||||
static grub_usb_err_t
|
||||
grub_usb_bulk_readwrite (grub_usb_device_t dev,
|
||||
int endpoint, grub_size_t size0, char *data_in,
|
||||
grub_transfer_type_t type, int timeout,
|
||||
grub_size_t *actual)
|
||||
{
|
||||
grub_usb_err_t err;
|
||||
grub_usb_transfer_t transfer;
|
||||
|
||||
transfer = grub_usb_bulk_setup_readwrite (dev, endpoint, size0,
|
||||
data_in, type);
|
||||
if (!transfer)
|
||||
return GRUB_USB_ERR_INTERNAL;
|
||||
err = grub_usb_execute_and_wait_transfer (dev, transfer, timeout, actual);
|
||||
|
||||
grub_usb_bulk_finish_readwrite (transfer);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -298,6 +360,49 @@ grub_usb_bulk_read (grub_usb_device_t dev,
|
|||
return err;
|
||||
}
|
||||
|
||||
grub_usb_err_t
|
||||
grub_usb_check_transfer (grub_usb_transfer_t transfer, grub_size_t *actual)
|
||||
{
|
||||
grub_usb_err_t err;
|
||||
grub_usb_device_t dev = transfer->dev;
|
||||
|
||||
err = dev->controller.dev->check_transfer (&dev->controller, transfer,
|
||||
actual);
|
||||
if (err == GRUB_USB_ERR_WAIT)
|
||||
return err;
|
||||
|
||||
grub_usb_bulk_finish_readwrite (transfer);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
grub_usb_transfer_t
|
||||
grub_usb_bulk_read_background (grub_usb_device_t dev,
|
||||
int endpoint, grub_size_t size, void *data)
|
||||
{
|
||||
grub_usb_err_t err;
|
||||
grub_usb_transfer_t transfer;
|
||||
|
||||
transfer = grub_usb_bulk_setup_readwrite (dev, endpoint, size,
|
||||
data, GRUB_USB_TRANSFER_TYPE_IN);
|
||||
if (!transfer)
|
||||
return NULL;
|
||||
|
||||
err = dev->controller.dev->setup_transfer (&dev->controller, transfer);
|
||||
if (err)
|
||||
return NULL;
|
||||
|
||||
return transfer;
|
||||
}
|
||||
|
||||
void
|
||||
grub_usb_cancel_transfer (grub_usb_transfer_t transfer)
|
||||
{
|
||||
grub_usb_device_t dev = transfer->dev;
|
||||
dev->controller.dev->cancel_transfer (&dev->controller, transfer);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_usb_err_t
|
||||
grub_usb_bulk_read_extended (grub_usb_device_t dev,
|
||||
int endpoint, grub_size_t size, char *data,
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <grub/misc.h>
|
||||
#include <grub/acpi.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/machine/memory.h>
|
||||
#include <grub/memory.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
|
@ -151,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;
|
||||
|
@ -180,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;
|
||||
|
||||
|
@ -324,7 +323,7 @@ setup_common_tables (void)
|
|||
|
||||
/* If it's FADT correct DSDT and FACS addresses. */
|
||||
fadt = (struct grub_acpi_fadt *) cur->addr;
|
||||
if (grub_memcmp (fadt->hdr.signature, "FACP",
|
||||
if (grub_memcmp (fadt->hdr.signature, GRUB_ACPI_FADT_SIGNATURE,
|
||||
sizeof (fadt->hdr.signature)) == 0)
|
||||
{
|
||||
fadt->dsdt_addr = PTR_TO_UINT32 (table_dsdt);
|
||||
|
@ -527,7 +526,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
|
|||
struct grub_acpi_fadt *fadt = (struct grub_acpi_fadt *) curtable;
|
||||
|
||||
/* Set root header variables to the same values
|
||||
as FACP by default. */
|
||||
as FADT by default. */
|
||||
grub_memcpy (&root_oemid, &(fadt->hdr.oemid),
|
||||
sizeof (root_oemid));
|
||||
grub_memcpy (&root_oemtable, &(fadt->hdr.oemtable),
|
||||
|
@ -704,7 +703,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
|
|||
|
||||
playground = playground_ptr
|
||||
= grub_mmap_malign_and_register (1, playground_size, &mmapregion,
|
||||
GRUB_MACHINE_MEMORY_ACPI, 0);
|
||||
GRUB_MEMORY_ACPI, 0);
|
||||
|
||||
if (! playground)
|
||||
{
|
||||
|
@ -758,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");
|
||||
}
|
|
@ -76,7 +76,7 @@ grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||
}
|
||||
|
||||
while (grub_checkkey () >= 0 &&
|
||||
(key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != GRUB_TERM_ESC)
|
||||
(key = grub_getkey ()) != GRUB_TERM_ESC)
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -91,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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
107
grub-core/commands/efi/lsefisystab.c
Normal file
107
grub-core/commands/efi/lsefisystab.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/* systab.c - Display EFI systab. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <grub/types.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/charset.h>
|
||||
#include <grub/efi/api.h>
|
||||
#include <grub/efi/efi.h>
|
||||
|
||||
struct guid_mapping
|
||||
{
|
||||
grub_efi_guid_t guid;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static const struct guid_mapping guid_mappings[] =
|
||||
{
|
||||
{ GRUB_EFI_ACPI_20_TABLE_GUID, "ACPI-2.0"},
|
||||
{ GRUB_EFI_ACPI_TABLE_GUID, "ACPI-1.0"},
|
||||
{ GRUB_EFI_SAL_TABLE_GUID, "SAL"},
|
||||
{ GRUB_EFI_SMBIOS_TABLE_GUID, "SMBIOS"},
|
||||
{ GRUB_EFI_MPS_TABLE_GUID, "MPS"},
|
||||
{ GRUB_EFI_HCDP_TABLE_GUID, "HCDP"}
|
||||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_lsefisystab (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
const grub_efi_system_table_t *st = grub_efi_system_table;
|
||||
grub_efi_configuration_table_t *t;
|
||||
unsigned int i;
|
||||
|
||||
grub_printf ("Signature: %016" PRIxGRUB_UINT64_T " revision: %08x\n",
|
||||
st->hdr.signature, st->hdr.revision);
|
||||
{
|
||||
char *vendor;
|
||||
grub_uint16_t *vendor_utf16;
|
||||
grub_printf ("Vendor: ");
|
||||
|
||||
for (vendor_utf16 = st->firmware_vendor; *vendor_utf16; vendor_utf16++);
|
||||
vendor = grub_malloc (4 * (vendor_utf16 - st->firmware_vendor) + 1);
|
||||
if (!vendor)
|
||||
return grub_errno;
|
||||
*grub_utf16_to_utf8 ((grub_uint8_t *) vendor, st->firmware_vendor,
|
||||
vendor_utf16 - st->firmware_vendor) = 0;
|
||||
grub_printf ("%s", vendor);
|
||||
grub_free (vendor);
|
||||
}
|
||||
|
||||
grub_printf (", Version=%x\n", st->firmware_revision);
|
||||
|
||||
grub_printf ("%ld tables:\n", st->num_table_entries);
|
||||
t = st->configuration_table;
|
||||
for (i = 0; i < st->num_table_entries; i++)
|
||||
{
|
||||
unsigned int j;
|
||||
|
||||
grub_printf ("%p ", t->vendor_table);
|
||||
|
||||
grub_printf ("%08x-%04x-%04x-",
|
||||
t->vendor_guid.data1, t->vendor_guid.data2,
|
||||
t->vendor_guid.data3);
|
||||
for (j = 0; j < 8; j++)
|
||||
grub_printf ("%02x", t->vendor_guid.data4[j]);
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE (guid_mappings); j++)
|
||||
if (grub_memcmp (&guid_mappings[j].guid, &t->vendor_guid,
|
||||
sizeof (grub_efi_guid_t)) == 0)
|
||||
grub_printf (" %s", guid_mappings[j].name);
|
||||
|
||||
grub_printf ("\n");
|
||||
t++;
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(lsefisystab)
|
||||
{
|
||||
cmd = grub_register_command ("lsefisystab", grub_cmd_lsefisystab,
|
||||
"", "Display EFI system tables.");
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(lsefisystab)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
162
grub-core/commands/efi/lssal.c
Normal file
162
grub-core/commands/efi/lssal.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
/* systab.c - Display EFI systab. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <grub/types.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/charset.h>
|
||||
#include <grub/efi/api.h>
|
||||
#include <grub/efi/efi.h>
|
||||
|
||||
static void
|
||||
disp_sal (void *table)
|
||||
{
|
||||
struct grub_efi_sal_system_table *t = table;
|
||||
void *desc;
|
||||
grub_uint32_t len, l;
|
||||
|
||||
grub_printf ("SAL rev: %02x, signature: %x, len:%x\n",
|
||||
t->sal_rev, t->signature, t->total_table_len);
|
||||
grub_printf ("nbr entry: %d, chksum: %02x, SAL version A: %02x B: %02x\n",
|
||||
t->entry_count, t->checksum,
|
||||
t->sal_a_version, t->sal_b_version);
|
||||
grub_printf ("OEM-ID: %-32s\n", t->oem_id);
|
||||
grub_printf ("Product-ID: %-32s\n", t->product_id);
|
||||
|
||||
desc = t->entries;
|
||||
len = t->total_table_len - sizeof (struct grub_efi_sal_system_table);
|
||||
while (len > 0)
|
||||
{
|
||||
switch (*(grub_uint8_t *) desc)
|
||||
{
|
||||
case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_ENTRYPOINT_DESCRIPTOR:
|
||||
{
|
||||
struct grub_efi_sal_system_table_entrypoint_descriptor *c = desc;
|
||||
l = sizeof (*c);
|
||||
grub_printf (" Entry point: PAL=%016" PRIxGRUB_UINT64_T
|
||||
" SAL=%016" PRIxGRUB_UINT64_T " GP=%016"
|
||||
PRIxGRUB_UINT64_T "\n",
|
||||
c->pal_proc_addr, c->sal_proc_addr,
|
||||
c->global_data_ptr);
|
||||
}
|
||||
break;
|
||||
case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_MEMORY_DESCRIPTOR:
|
||||
{
|
||||
struct grub_efi_sal_system_table_memory_descriptor *c = desc;
|
||||
l = sizeof (*c);
|
||||
grub_printf (" Memory descriptor entry addr=%016" PRIxGRUB_UINT64_T
|
||||
" len=%" PRIuGRUB_UINT64_T "KB\n",
|
||||
c->addr, c->len * 4);
|
||||
grub_printf (" sal_used=%d attr=%x AR=%x attr_mask=%x "
|
||||
"type=%x usage=%x\n",
|
||||
c->sal_used, c->attr, c->ar, c->attr_mask, c->mem_type,
|
||||
c->usage);
|
||||
}
|
||||
break;
|
||||
case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PLATFORM_FEATURES:
|
||||
{
|
||||
struct grub_efi_sal_system_table_platform_features *c = desc;
|
||||
l = sizeof (*c);
|
||||
grub_printf (" Platform features: %02x", c->flags);
|
||||
if (c->flags & GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_BUSLOCK)
|
||||
grub_printf (" BusLock");
|
||||
if (c->flags & GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IRQREDIRECT)
|
||||
grub_printf (" IrqRedirect");
|
||||
if (c->flags & GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IPIREDIRECT)
|
||||
|
||||
grub_printf (" IPIRedirect");
|
||||
if (c->flags & GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_ITCDRIFT)
|
||||
|
||||
grub_printf (" ITCDrift");
|
||||
grub_printf ("\n");
|
||||
}
|
||||
break;
|
||||
case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_TRANSLATION_REGISTER_DESCRIPTOR:
|
||||
{
|
||||
struct grub_efi_sal_system_table_translation_register_descriptor *c
|
||||
= desc;
|
||||
l = sizeof (*c);
|
||||
grub_printf (" TR type=%d num=%d va=%016" PRIxGRUB_UINT64_T
|
||||
" pte=%016" PRIxGRUB_UINT64_T "\n",
|
||||
c->register_type, c->register_number,
|
||||
c->addr, c->page_size);
|
||||
}
|
||||
break;
|
||||
case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PURGE_TRANSLATION_COHERENCE:
|
||||
{
|
||||
struct grub_efi_sal_system_table_purge_translation_coherence *c
|
||||
= desc;
|
||||
l = sizeof (*c);
|
||||
grub_printf (" PTC coherence nbr=%d addr=%016" PRIxGRUB_UINT64_T "\n",
|
||||
c->ndomains, c->coherence);
|
||||
}
|
||||
break;
|
||||
case GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_AP_WAKEUP:
|
||||
{
|
||||
struct grub_efi_sal_system_table_ap_wakeup *c = desc;
|
||||
l = sizeof (*c);
|
||||
grub_printf (" AP wake-up: mec=%d vect=%" PRIxGRUB_UINT64_T "\n",
|
||||
c->mechanism, c->vector);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
grub_printf (" unknown entry 0x%x\n", *(grub_uint8_t *)desc);
|
||||
return;
|
||||
}
|
||||
desc = (grub_uint8_t *)desc + l;
|
||||
len -= l;
|
||||
}
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_lssal (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
const grub_efi_system_table_t *st = grub_efi_system_table;
|
||||
grub_efi_configuration_table_t *t = st->configuration_table;
|
||||
unsigned int i;
|
||||
grub_efi_guid_t guid = GRUB_EFI_SAL_TABLE_GUID;
|
||||
|
||||
for (i = 0; i < st->num_table_entries; i++)
|
||||
{
|
||||
if (grub_memcmp (&guid, &t->vendor_guid,
|
||||
sizeof (grub_efi_guid_t)) == 0)
|
||||
{
|
||||
disp_sal (t->vendor_table);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
t++;
|
||||
}
|
||||
grub_printf ("SAL not found\n");
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(lssal)
|
||||
{
|
||||
cmd = grub_register_command ("lssal", grub_cmd_lssal, "",
|
||||
"Display SAL system table.");
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(lssal)
|
||||
{
|
||||
grub_unregister_command (cmd);
|
||||
}
|
|
@ -66,7 +66,7 @@ grub_extcmd_dispatch (struct grub_command *cmd, int argc, char **args)
|
|||
|
||||
grub_extcmd_t
|
||||
grub_register_extcmd_prio (const char *name, grub_extcmd_func_t func,
|
||||
unsigned flags, const char *summary,
|
||||
grub_command_flags_t flags, const char *summary,
|
||||
const char *description,
|
||||
const struct grub_arg_option *parser,
|
||||
int prio)
|
||||
|
@ -99,7 +99,7 @@ grub_register_extcmd_prio (const char *name, grub_extcmd_func_t func,
|
|||
|
||||
grub_extcmd_t
|
||||
grub_register_extcmd (const char *name, grub_extcmd_func_t func,
|
||||
unsigned flags, const char *summary,
|
||||
grub_command_flags_t flags, const char *summary,
|
||||
const char *description,
|
||||
const struct grub_arg_option *parser)
|
||||
{
|
||||
|
|
|
@ -252,26 +252,22 @@ static grub_extcmd_t cmd, cmd_md5, cmd_sha256, cmd_sha512;
|
|||
|
||||
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."),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -38,8 +38,7 @@ grub_cmd_help (grub_extcmd_context_t ctxt __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);
|
||||
|
@ -131,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);
|
||||
}
|
||||
|
|
|
@ -119,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);
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
@ -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 ();
|
||||
|
||||
|
@ -100,6 +103,7 @@ grub_cmd_halt (grub_extcmd_context_t ctxt,
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -40,7 +40,6 @@ 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");
|
||||
|
@ -63,6 +62,7 @@ grub_cmd_read (grub_extcmd_context_t ctxt, int argc, char **argv)
|
|||
|
||||
if (ctxt->state[0].set)
|
||||
{
|
||||
char buf[sizeof ("XXXXXXXX")];
|
||||
grub_snprintf (buf, sizeof (buf), "%x", value);
|
||||
grub_env_set (ctxt->state[0].arg, buf);
|
||||
}
|
||||
|
@ -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,7 +31,23 @@ 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_context_t ctxt,
|
||||
|
@ -43,11 +59,11 @@ grub_cmd_keystatus (grub_extcmd_context_t ctxt,
|
|||
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);
|
||||
}
|
|
@ -375,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);
|
||||
|
|
|
@ -253,12 +253,14 @@ static grub_err_t
|
|||
grub_cmd_ls (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
struct grub_arg_list *state = ctxt->state;
|
||||
int i;
|
||||
|
||||
if (argc == 0)
|
||||
grub_ls_list_devices (state[0].set);
|
||||
else
|
||||
grub_ls_list_files (args[0], state[0].set, state[2].set,
|
||||
state[1].set);
|
||||
for (i = 0; i < argc; i++)
|
||||
grub_ls_list_files (args[i], state[0].set, state[2].set,
|
||||
state[1].set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -267,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);
|
||||
}
|
||||
|
||||
|
|
250
grub-core/commands/lsacpi.c
Normal file
250
grub-core/commands/lsacpi.c
Normal file
|
@ -0,0 +1,250 @@
|
|||
/* acpi.c - Display acpi tables. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <grub/types.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/normal.h>
|
||||
#include <grub/acpi.h>
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/dl.h>
|
||||
|
||||
static void
|
||||
print_strn (grub_uint8_t *str, grub_size_t len)
|
||||
{
|
||||
for (; *str && len; str++, len--)
|
||||
grub_printf ("%c", *str);
|
||||
for (len++; len; len--)
|
||||
grub_printf (" ");
|
||||
}
|
||||
|
||||
#define print_field(x) print_strn(x, sizeof (x))
|
||||
|
||||
static void
|
||||
disp_acpi_table (struct grub_acpi_table_header *t)
|
||||
{
|
||||
print_field (t->signature);
|
||||
grub_printf ("%4" PRIuGRUB_UINT32_T "B rev=%u OEM=", t->length, t->revision);
|
||||
print_field (t->oemid);
|
||||
print_field (t->oemtable);
|
||||
grub_printf ("OEMrev=%08" PRIxGRUB_UINT32_T " ", t->oemrev);
|
||||
print_field (t->creator_id);
|
||||
grub_printf (" %08" PRIxGRUB_UINT32_T "\n", t->creator_rev);
|
||||
}
|
||||
|
||||
static void
|
||||
disp_madt_table (struct grub_acpi_madt *t)
|
||||
{
|
||||
struct grub_acpi_madt_entry_header *d;
|
||||
grub_uint32_t len;
|
||||
|
||||
disp_acpi_table (&t->hdr);
|
||||
grub_printf ("Local APIC=%08" PRIxGRUB_UINT32_T " Flags=%08"
|
||||
PRIxGRUB_UINT32_T "\n",
|
||||
t->lapic_addr, t->flags);
|
||||
len = t->hdr.length - sizeof (struct grub_acpi_madt);
|
||||
d = t->entries;
|
||||
for (;len > 0; len -= d->len, d = (void *) ((grub_uint8_t *) d + d->len))
|
||||
{
|
||||
grub_printf (" type=%x l=%u ", d->type, d->len);
|
||||
|
||||
switch (d->type)
|
||||
{
|
||||
case GRUB_ACPI_MADT_ENTRY_TYPE_INTERRUPT_OVERRIDE:
|
||||
{
|
||||
struct grub_acpi_madt_entry_interrupt_override *dt = (void *) d;
|
||||
grub_printf ("Int Override bus=%x src=%x GSI=%08x Flags=%04x\n",
|
||||
dt->bus, dt->source, dt->global_sys_interrupt,
|
||||
dt->flags);
|
||||
}
|
||||
break;
|
||||
case GRUB_ACPI_MADT_ENTRY_TYPE_SAPIC:
|
||||
{
|
||||
struct grub_acpi_madt_entry_sapic *dt = (void *) d;
|
||||
grub_printf ("IOSAPIC Id=%02x GSI=%08x Addr=%016" PRIxGRUB_UINT64_T
|
||||
"\n",
|
||||
dt->id, dt->global_sys_interrupt_base,
|
||||
dt->addr);
|
||||
}
|
||||
break;
|
||||
case GRUB_ACPI_MADT_ENTRY_TYPE_LSAPIC:
|
||||
{
|
||||
struct grub_acpi_madt_entry_lsapic *dt = (void *) d;
|
||||
grub_printf ("LSAPIC ProcId=%02x ID=%02x EID=%02x Flags=%x",
|
||||
dt->cpu_id, dt->id, dt->eid, dt->flags);
|
||||
if (dt->flags & GRUB_ACPI_MADT_ENTRY_SAPIC_FLAGS_ENABLED)
|
||||
grub_printf (" Enabled\n");
|
||||
else
|
||||
grub_printf (" Disabled\n");
|
||||
if (d->len > sizeof (struct grub_acpi_madt_entry_sapic))
|
||||
grub_printf (" UID val=%08x, Str=%s\n", dt->cpu_uid,
|
||||
dt->cpu_uid_str);
|
||||
}
|
||||
break;
|
||||
case GRUB_ACPI_MADT_ENTRY_TYPE_PLATFORM_INT_SOURCE:
|
||||
{
|
||||
struct grub_acpi_madt_entry_platform_int_source *dt = (void *) d;
|
||||
static const char * const platint_type[] =
|
||||
{"Nul", "PMI", "INIT", "CPEI"};
|
||||
|
||||
grub_printf ("Platform INT flags=%04x type=%02x (%s)"
|
||||
" ID=%02x EID=%02x\n",
|
||||
dt->flags, dt->inttype,
|
||||
(dt->inttype < ARRAY_SIZE (platint_type))
|
||||
? platint_type[dt->inttype] : "??", dt->cpu_id,
|
||||
dt->cpu_eid);
|
||||
grub_printf (" IOSAPIC Vec=%02x GSI=%08x source flags=%08x\n",
|
||||
dt->sapic_vector, dt->global_sys_int, dt->src_flags);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
grub_printf (" ??\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
disp_acpi_xsdt_table (struct grub_acpi_table_header *t)
|
||||
{
|
||||
grub_uint32_t len;
|
||||
grub_uint64_t *desc;
|
||||
|
||||
disp_acpi_table (t);
|
||||
len = t->length - sizeof (*t);
|
||||
desc = (grub_uint64_t *) (t + 1);
|
||||
for (; len > 0; desc++, len -= sizeof (*desc))
|
||||
{
|
||||
if (sizeof (grub_addr_t) == 4 && *desc >= (1ULL << 32))
|
||||
{
|
||||
grub_printf ("Unreachable table\n");
|
||||
continue;
|
||||
}
|
||||
t = (struct grub_acpi_table_header *) (grub_addr_t) *desc;
|
||||
|
||||
if (t == NULL)
|
||||
continue;
|
||||
|
||||
if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE,
|
||||
sizeof (t->signature)) == 0)
|
||||
disp_madt_table ((struct grub_acpi_madt *) t);
|
||||
else
|
||||
disp_acpi_table (t);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
disp_acpi_rsdt_table (struct grub_acpi_table_header *t)
|
||||
{
|
||||
grub_uint32_t len;
|
||||
grub_uint32_t *desc;
|
||||
|
||||
disp_acpi_table (t);
|
||||
len = t->length - sizeof (*t);
|
||||
desc = (grub_uint32_t *) (t + 1);
|
||||
for (; len > 0; desc++, len -= sizeof (*desc))
|
||||
{
|
||||
t = (struct grub_acpi_table_header *) (grub_addr_t) *desc;
|
||||
|
||||
if (t == NULL)
|
||||
continue;
|
||||
|
||||
if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE,
|
||||
sizeof (t->signature)) == 0)
|
||||
disp_madt_table ((struct grub_acpi_madt *) t);
|
||||
else
|
||||
disp_acpi_table (t);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10 *rsdp)
|
||||
{
|
||||
print_field (rsdp->signature);
|
||||
grub_printf ("chksum:%02x, OEM-ID: ", rsdp->checksum);
|
||||
print_field (rsdp->oemid);
|
||||
grub_printf ("rev=%d\n", rsdp->revision);
|
||||
grub_printf ("RSDT=%08" PRIxGRUB_UINT32_T "\n", rsdp->rsdt_addr);
|
||||
}
|
||||
|
||||
static void
|
||||
disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp)
|
||||
{
|
||||
disp_acpi_rsdpv1 (&rsdp->rsdpv1);
|
||||
grub_printf ("len=%d XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length,
|
||||
rsdp->xsdt_addr);
|
||||
}
|
||||
|
||||
static const struct grub_arg_option options[] = {
|
||||
{"v1", '1', 0, N_("Show v1 tables only."), 0, ARG_TYPE_NONE},
|
||||
{"v2", '2', 0, N_("Show v2 and v3 tablesv only."), 0, ARG_TYPE_NONE}
|
||||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_lsacpi (struct grub_extcmd_context *ctxt,
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
{
|
||||
if (!ctxt->state[1].set)
|
||||
{
|
||||
struct grub_acpi_rsdp_v10 *rsdp1 = grub_acpi_get_rsdpv1 ();
|
||||
if (!rsdp1)
|
||||
grub_printf ("No RSDPv1\n");
|
||||
else
|
||||
{
|
||||
grub_printf ("RSDPv1 signature:");
|
||||
disp_acpi_rsdpv1 (rsdp1);
|
||||
disp_acpi_rsdt_table ((void *) (grub_addr_t) rsdp1->rsdt_addr);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ctxt->state[0].set)
|
||||
{
|
||||
struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 ();
|
||||
if (!rsdp2)
|
||||
grub_printf ("No RSDPv2\n");
|
||||
else
|
||||
{
|
||||
if (sizeof (grub_addr_t) == 4 && rsdp2->xsdt_addr >= (1ULL << 32))
|
||||
grub_printf ("Unreachable RSDPv2\n");
|
||||
else
|
||||
{
|
||||
grub_printf ("RSDPv2 signature:");
|
||||
disp_acpi_rsdpv2 (rsdp2);
|
||||
disp_acpi_xsdt_table ((void *) (grub_addr_t) rsdp2->xsdt_addr);
|
||||
grub_printf ("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_extcmd_t cmd;
|
||||
|
||||
GRUB_MOD_INIT(lsapi)
|
||||
{
|
||||
cmd = grub_register_extcmd ("lsacpi", grub_cmd_lsacpi, 0, N_("[-1|-2]"),
|
||||
N_("Show ACPI information."), options);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(lsacpi)
|
||||
{
|
||||
grub_unregister_extcmd (cmd);
|
||||
}
|
||||
|
||||
|
|
@ -16,24 +16,39 @@
|
|||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRUB_MACHINE_EMU
|
||||
#include <grub/machine/memory.h>
|
||||
#endif
|
||||
#include <grub/dl.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/command.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/memory.h>
|
||||
|
||||
static const char *names[] =
|
||||
{
|
||||
[GRUB_MEMORY_AVAILABLE] = "available",
|
||||
[GRUB_MEMORY_RESERVED] = "reserved",
|
||||
[GRUB_MEMORY_ACPI] = "ACPI reclamaible",
|
||||
[GRUB_MEMORY_NVS] = "NVS",
|
||||
[GRUB_MEMORY_BADRAM] = "BadRAM",
|
||||
[GRUB_MEMORY_CODE] = "firmware code",
|
||||
[GRUB_MEMORY_HOLE] = "hole"
|
||||
};
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_lsmmap (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc __attribute__ ((unused)), char **args __attribute__ ((unused)))
|
||||
int argc __attribute__ ((unused)),
|
||||
char **args __attribute__ ((unused)))
|
||||
|
||||
{
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
|
||||
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
|
||||
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_memory_type_t);
|
||||
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
|
||||
grub_memory_type_t type)
|
||||
{
|
||||
grub_printf ("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n",
|
||||
(long long) addr, (long long) size, type);
|
||||
if (type < ARRAY_SIZE (names) && names[type])
|
||||
grub_printf ("base_addr = 0x%llx, length = 0x%llx, %s\n",
|
||||
(long long) addr, (long long) size, names[type]);
|
||||
else
|
||||
grub_printf ("base_addr = 0x%llx, length = 0x%llx, type = 0x%x\n",
|
||||
(long long) addr, (long long) size, type);
|
||||
return 0;
|
||||
}
|
||||
#ifndef GRUB_MACHINE_EMU
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -46,16 +46,29 @@ static struct
|
|||
{
|
||||
{"backspace", '\b'},
|
||||
{"tab", '\t'},
|
||||
{"delete", GRUB_TERM_DC}
|
||||
{"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. */
|
||||
static grub_err_t
|
||||
append_menu_entry (int argc, const char **args, char **classes,
|
||||
const char *users, const char *hotkey,
|
||||
const char *prefix, const char *sourcecode)
|
||||
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;
|
||||
|
@ -128,7 +141,7 @@ append_menu_entry (int argc, const char **args, char **classes,
|
|||
if (! menu_args)
|
||||
goto fail;
|
||||
|
||||
for (i = 0; args[i]; i++)
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
menu_args[i] = grub_strdup (args[i]);
|
||||
if (! menu_args[i])
|
||||
|
@ -243,9 +256,10 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menuentry definition");
|
||||
|
||||
if (! ctxt->script)
|
||||
return append_menu_entry (argc, (const char **) args,
|
||||
ctxt->state[0].args, ctxt->state[1].arg,
|
||||
ctxt->state[2].arg, 0, ctxt->state[3].arg);
|
||||
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;
|
||||
|
@ -258,9 +272,9 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||
if (! prefix)
|
||||
return grub_errno;
|
||||
|
||||
r = append_menu_entry (argc - 1, (const char **) args,
|
||||
ctxt->state[0].args, ctxt->state[1].arg,
|
||||
ctxt->state[2].arg, prefix, src + 1);
|
||||
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;
|
||||
|
@ -274,7 +288,7 @@ void
|
|||
grub_menu_init (void)
|
||||
{
|
||||
cmd = grub_register_extcmd ("menuentry", grub_cmd_menuentry,
|
||||
GRUB_COMMAND_FLAG_BOTH | GRUB_COMMAND_FLAG_BLOCKS,
|
||||
GRUB_COMMAND_FLAG_BLOCKS,
|
||||
N_("BLOCK"), N_("Define a menuentry."), options);
|
||||
}
|
||||
|
||||
|
|
|
@ -108,40 +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;
|
||||
}
|
||||
|
||||
/* dump ADDRESS [SIZE] */
|
||||
static grub_err_t
|
||||
grub_mini_cmd_dump (struct grub_command *cmd __attribute__ ((unused)),
|
||||
|
@ -226,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)
|
||||
|
@ -237,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."));
|
||||
|
@ -258,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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -136,8 +136,7 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(regexp)
|
||||
{
|
||||
cmd = grub_register_extcmd ("regexp", grub_cmd_regexp,
|
||||
GRUB_COMMAND_FLAG_BOTH, N_("REGEXP 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. */
|
||||
|
|
|
@ -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;
|
||||
|
@ -114,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);
|
||||
|
@ -142,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;
|
||||
}
|
||||
|
@ -159,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,6 +50,7 @@ enum options
|
|||
SEARCH_FS_UUID,
|
||||
SEARCH_SET,
|
||||
SEARCH_NO_FLOPPY,
|
||||
SEARCH_HINT
|
||||
};
|
||||
|
||||
static grub_err_t
|
||||
|
@ -54,6 +58,11 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
|
|||
{
|
||||
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_context_t ctxt, 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"
|
||||
|
|
|
@ -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,8 +52,7 @@ 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;
|
||||
|
@ -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);
|
||||
|
|
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
|
||||
}
|
||||
|
|
|
@ -137,8 +137,10 @@ make_regex (const char *start, const char *end, regex_t *regexp)
|
|||
break;
|
||||
|
||||
case '.':
|
||||
case '(':
|
||||
case ')':
|
||||
buffer[i++] = '\\';
|
||||
buffer[i++] = '.';
|
||||
buffer[i++] = ch;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
|
@ -152,6 +154,7 @@ make_regex (const char *start, const char *end, regex_t *regexp)
|
|||
}
|
||||
buffer[i++] = '$';
|
||||
buffer[i] = '\0';
|
||||
grub_dprintf ("expand", "Regexp is %s\n", buffer);
|
||||
|
||||
if (regcomp (regexp, buffer, RE_SYNTAX_GNU_AWK))
|
||||
{
|
||||
|
@ -224,6 +227,7 @@ match_devices (const regex_t *regexp, int noparts)
|
|||
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;
|
||||
}
|
||||
|
@ -488,7 +492,7 @@ wildcard_expand (const char *s, char ***strs)
|
|||
|
||||
for (i = 0; paths && paths[i]; i++)
|
||||
grub_free (paths[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>
|
||||
|
@ -327,7 +327,6 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
|
|||
if (drive < 0)
|
||||
return grub_errno;
|
||||
|
||||
disk->has_partitions = 1;
|
||||
disk->id = drive;
|
||||
|
||||
data = (struct grub_biosdisk_data *) grub_zalloc (sizeof (*data));
|
||||
|
|
|
@ -113,7 +113,6 @@ grub_nand_open (const char *name, grub_disk_t disk)
|
|||
|
||||
disk->id = dev_ihandle;
|
||||
|
||||
disk->has_partitions = 0;
|
||||
disk->data = data;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -23,9 +23,15 @@
|
|||
#include <grub/ieee1275/ieee1275.h>
|
||||
#include <grub/ieee1275/ofdisk.h>
|
||||
|
||||
static char *last_devpath;
|
||||
static grub_ieee1275_ihandle_t last_ihandle;
|
||||
|
||||
struct ofdisk_hash_ent
|
||||
{
|
||||
char *devpath;
|
||||
/* Pointer to shortest available name on nodes representing canonical names,
|
||||
otherwise NULL. */
|
||||
const char *shortest;
|
||||
struct ofdisk_hash_ent *next;
|
||||
};
|
||||
|
||||
|
@ -59,60 +65,125 @@ static struct ofdisk_hash_ent *
|
|||
ofdisk_hash_add (char *devpath)
|
||||
{
|
||||
struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)];
|
||||
struct ofdisk_hash_ent *p = grub_malloc(sizeof (*p));
|
||||
struct ofdisk_hash_ent *p, *pcan;
|
||||
char *curcan;
|
||||
|
||||
if (p)
|
||||
p = grub_malloc(sizeof (*p));
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
p->devpath = devpath;
|
||||
p->next = *head;
|
||||
p->shortest = 0;
|
||||
*head = p;
|
||||
|
||||
curcan = grub_ieee1275_canonicalise_devname (devpath);
|
||||
if (!curcan)
|
||||
{
|
||||
p->devpath = devpath;
|
||||
p->next = *head;
|
||||
*head = p;
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return p;
|
||||
}
|
||||
|
||||
pcan = ofdisk_hash_find (curcan);
|
||||
if (!pcan)
|
||||
pcan = ofdisk_hash_add (curcan);
|
||||
else
|
||||
grub_free (curcan);
|
||||
|
||||
if (!pcan)
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
else
|
||||
{
|
||||
if (!pcan->shortest
|
||||
|| grub_strlen (pcan->shortest) > grub_strlen (devpath))
|
||||
pcan->shortest = devpath;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static int
|
||||
grub_ofdisk_iterate (int (*hook) (const char *name))
|
||||
static void
|
||||
scan (void)
|
||||
{
|
||||
auto int dev_iterate (struct grub_ieee1275_devalias *alias);
|
||||
|
||||
int dev_iterate (struct grub_ieee1275_devalias *alias)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ofdisk_hash_ent *op;
|
||||
|
||||
grub_dprintf ("disk", "device name = %s type = %s\n", alias->name,
|
||||
alias->type);
|
||||
|
||||
if (grub_strcmp (alias->type, "block") != 0)
|
||||
return 0;
|
||||
|
||||
grub_dprintf ("disk", "disk name = %s\n", alias->name);
|
||||
|
||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY))
|
||||
op = ofdisk_hash_find (alias->path);
|
||||
if (!op)
|
||||
{
|
||||
grub_ieee1275_phandle_t dev;
|
||||
char tmp[8];
|
||||
|
||||
if (grub_ieee1275_finddevice (alias->path, &dev))
|
||||
char *name = grub_strdup (alias->name);
|
||||
if (!name)
|
||||
{
|
||||
grub_dprintf ("disk", "finddevice (%s) failed\n", alias->path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (grub_ieee1275_get_property (dev, "iconname", tmp,
|
||||
sizeof tmp, 0))
|
||||
{
|
||||
grub_dprintf ("disk", "get iconname failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (grub_strcmp (tmp, "sdmmc"))
|
||||
{
|
||||
grub_dprintf ("disk", "device is not an SD card\n");
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return 0;
|
||||
}
|
||||
op = ofdisk_hash_add (name);
|
||||
}
|
||||
|
||||
if (! grub_strcmp (alias->type, "block") &&
|
||||
grub_strncmp (alias->name, "cdrom", 5))
|
||||
ret = hook (alias->name);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return grub_devalias_iterate (dev_iterate);
|
||||
grub_devalias_iterate (dev_iterate);
|
||||
grub_ieee1275_devices_iterate (dev_iterate);
|
||||
}
|
||||
|
||||
static int
|
||||
grub_ofdisk_iterate (int (*hook) (const char *name))
|
||||
{
|
||||
unsigned i;
|
||||
scan ();
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (ofdisk_hash); i++)
|
||||
{
|
||||
static struct ofdisk_hash_ent *ent;
|
||||
for (ent = ofdisk_hash[i]; ent; ent = ent->next)
|
||||
{
|
||||
if (!ent->shortest)
|
||||
continue;
|
||||
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_OFDISK_SDCARD_ONLY))
|
||||
{
|
||||
grub_ieee1275_phandle_t dev;
|
||||
char tmp[8];
|
||||
|
||||
if (grub_ieee1275_finddevice (ent->devpath, &dev))
|
||||
{
|
||||
grub_dprintf ("disk", "finddevice (%s) failed\n",
|
||||
ent->devpath);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_ieee1275_get_property (dev, "iconname", tmp,
|
||||
sizeof tmp, 0))
|
||||
{
|
||||
grub_dprintf ("disk", "get iconname failed\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (grub_strcmp (tmp, "sdmmc") != 0)
|
||||
{
|
||||
grub_dprintf ("disk", "device is not an SD card\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (grub_strncmp (ent->shortest, "cdrom", 5) == 0)
|
||||
continue;
|
||||
|
||||
if (hook (ent->shortest))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
|
@ -137,11 +208,6 @@ compute_dev_path (const char *name)
|
|||
*p++ = c;
|
||||
}
|
||||
|
||||
if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
|
||||
{
|
||||
*p++ = ':';
|
||||
*p++ = '0';
|
||||
}
|
||||
*p++ = '\0';
|
||||
|
||||
return devpath;
|
||||
|
@ -151,8 +217,6 @@ static grub_err_t
|
|||
grub_ofdisk_open (const char *name, grub_disk_t disk)
|
||||
{
|
||||
grub_ieee1275_phandle_t dev;
|
||||
grub_ieee1275_ihandle_t dev_ihandle = 0;
|
||||
struct ofdisk_hash_ent *op;
|
||||
char *devpath;
|
||||
/* XXX: This should be large enough for any possible case. */
|
||||
char prop[64];
|
||||
|
@ -162,69 +226,50 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
|
|||
if (! devpath)
|
||||
return grub_errno;
|
||||
|
||||
op = ofdisk_hash_find (devpath);
|
||||
if (!op)
|
||||
op = ofdisk_hash_add (devpath);
|
||||
grub_dprintf ("disk", "Opening `%s'.\n", devpath);
|
||||
|
||||
grub_free (devpath);
|
||||
if (!op)
|
||||
return grub_errno;
|
||||
|
||||
grub_dprintf ("disk", "Opening `%s'.\n", op->devpath);
|
||||
|
||||
if (grub_ieee1275_finddevice (op->devpath, &dev))
|
||||
{
|
||||
grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read device properties");
|
||||
goto fail;
|
||||
}
|
||||
if (grub_ieee1275_finddevice (devpath, &dev))
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read device properties");
|
||||
|
||||
if (grub_ieee1275_get_property (dev, "device_type", prop, sizeof (prop),
|
||||
&actual))
|
||||
{
|
||||
grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read the device type");
|
||||
goto fail;
|
||||
}
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read the device type");
|
||||
|
||||
if (grub_strcmp (prop, "block"))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_DEVICE, "not a block device");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
grub_ieee1275_open (op->devpath, &dev_ihandle);
|
||||
if (! dev_ihandle)
|
||||
{
|
||||
grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
grub_dprintf ("disk", "Opened `%s' as handle %p.\n", op->devpath,
|
||||
(void *) (unsigned long) dev_ihandle);
|
||||
return grub_error (GRUB_ERR_BAD_DEVICE, "not a block device");
|
||||
|
||||
/* XXX: There is no property to read the number of blocks. There
|
||||
should be a property `#blocks', but it is not there. Perhaps it
|
||||
is possible to use seek for this. */
|
||||
disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
|
||||
|
||||
disk->id = (unsigned long) op;
|
||||
{
|
||||
struct ofdisk_hash_ent *op;
|
||||
op = ofdisk_hash_find (devpath);
|
||||
if (!op)
|
||||
op = ofdisk_hash_add (devpath);
|
||||
else
|
||||
grub_free (devpath);
|
||||
if (!op)
|
||||
return grub_errno;
|
||||
disk->id = (unsigned long) op;
|
||||
disk->data = op->devpath;
|
||||
}
|
||||
|
||||
/* XXX: Read this, somehow. */
|
||||
disk->has_partitions = 1;
|
||||
disk->data = (void *) (unsigned long) dev_ihandle;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (dev_ihandle)
|
||||
grub_ieee1275_close (dev_ihandle);
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static void
|
||||
grub_ofdisk_close (grub_disk_t disk)
|
||||
{
|
||||
grub_dprintf ("disk", "Closing handle %p.\n",
|
||||
(void *) disk->data);
|
||||
grub_ieee1275_close ((grub_ieee1275_ihandle_t) (unsigned long) disk->data);
|
||||
if (disk->data == last_devpath)
|
||||
{
|
||||
if (last_ihandle)
|
||||
grub_ieee1275_close (last_ihandle);
|
||||
last_ihandle = 0;
|
||||
last_devpath = NULL;
|
||||
}
|
||||
disk->data = 0;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
|
@ -234,16 +279,40 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
|||
grub_ssize_t status, actual;
|
||||
unsigned long long pos;
|
||||
|
||||
if (disk->data != last_devpath)
|
||||
{
|
||||
if (last_ihandle)
|
||||
grub_ieee1275_close (last_ihandle);
|
||||
last_ihandle = 0;
|
||||
last_devpath = NULL;
|
||||
|
||||
if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
|
||||
{
|
||||
char name2[grub_strlen (disk->data) + 3];
|
||||
char *p;
|
||||
|
||||
grub_strcpy (name2, disk->data);
|
||||
p = name2 + grub_strlen (name2);
|
||||
*p++ = ':';
|
||||
*p++ = '0';
|
||||
*p = 0;
|
||||
grub_ieee1275_open (name2, &last_ihandle);
|
||||
}
|
||||
else
|
||||
grub_ieee1275_open (disk->data, &last_ihandle);
|
||||
if (! last_ihandle)
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
|
||||
last_devpath = disk->data;
|
||||
}
|
||||
|
||||
pos = sector * 512UL;
|
||||
|
||||
grub_ieee1275_seek ((grub_ieee1275_ihandle_t) (unsigned long) disk->data,
|
||||
pos, &status);
|
||||
grub_ieee1275_seek (last_ihandle, pos, &status);
|
||||
if (status < 0)
|
||||
return grub_error (GRUB_ERR_READ_ERROR,
|
||||
"seek error, can't seek block %llu",
|
||||
(long long) sector);
|
||||
grub_ieee1275_read ((grub_ieee1275_ihandle_t) (unsigned long) disk->data,
|
||||
buf, size * 512UL, &actual);
|
||||
grub_ieee1275_read (last_ihandle, buf, size * 512UL, &actual);
|
||||
if (actual != (grub_ssize_t) (size * 512UL))
|
||||
return grub_error (GRUB_ERR_READ_ERROR, "read error on block: %llu",
|
||||
(long long) sector);
|
||||
|
@ -281,5 +350,10 @@ grub_ofdisk_init (void)
|
|||
void
|
||||
grub_ofdisk_fini (void)
|
||||
{
|
||||
if (last_ihandle)
|
||||
grub_ieee1275_close (last_ihandle);
|
||||
last_ihandle = 0;
|
||||
last_devpath = NULL;
|
||||
|
||||
grub_disk_dev_unregister (&grub_ofdisk_dev);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ struct grub_loopback
|
|||
{
|
||||
char *devname;
|
||||
grub_file_t file;
|
||||
int has_partitions;
|
||||
struct grub_loopback *next;
|
||||
};
|
||||
|
||||
|
@ -38,7 +37,6 @@ static struct grub_loopback *loopback_list;
|
|||
static const struct grub_arg_option options[] =
|
||||
{
|
||||
{"delete", 'd', 0, N_("Delete the loopback device entry."), 0, 0},
|
||||
{"partitions", 'p', 0, N_("Simulate a hard drive with partitions."), 0, 0},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -106,9 +104,6 @@ grub_cmd_loopback (grub_extcmd_context_t ctxt, 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_context_t ctxt, 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;
|
||||
|
@ -174,7 +166,6 @@ grub_loopback_open (const char *name, grub_disk_t disk)
|
|||
disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
|
||||
disk->id = (unsigned long) dev;
|
||||
|
||||
disk->has_partitions = dev->has_partitions;
|
||||
disk->data = dev->file;
|
||||
|
||||
return 0;
|
||||
|
@ -230,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;
|
||||
|
@ -280,7 +279,11 @@ grub_lvm_scan_device (const char *name)
|
|||
|
||||
disk = grub_disk_open (name);
|
||||
if (!disk)
|
||||
return 0;
|
||||
{
|
||||
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Search for label. */
|
||||
for (i = 0; i < GRUB_LVM_LABEL_SCAN_SECTORS; i++)
|
||||
|
@ -725,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;
|
||||
}
|
||||
|
||||
|
|
132
grub-core/fs/btrfs.c
Normal file
132
grub-core/fs/btrfs.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
/* btrfs.c - B-tree file system. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GRUB is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <grub/err.h>
|
||||
#include <grub/file.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/types.h>
|
||||
|
||||
#define BTRFS_SIGNATURE "_BHRfS_M"
|
||||
|
||||
struct btrfs_superblock
|
||||
{
|
||||
grub_uint8_t dummy1[32];
|
||||
grub_uint16_t uuid[8];
|
||||
grub_uint8_t dummy2[16];
|
||||
grub_uint8_t signature[sizeof (BTRFS_SIGNATURE) - 1];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct grub_btrfs_data
|
||||
{
|
||||
struct btrfs_superblock sblock;
|
||||
};
|
||||
|
||||
static struct grub_btrfs_data *
|
||||
grub_btrfs_mount (grub_disk_t disk)
|
||||
{
|
||||
struct grub_btrfs_data *data = grub_malloc (sizeof (*data));
|
||||
if (! data)
|
||||
return NULL;
|
||||
|
||||
if (grub_disk_read (disk, 128, 0, sizeof (data->sblock),
|
||||
&data->sblock) != GRUB_ERR_NONE)
|
||||
goto fail;
|
||||
|
||||
if (grub_strncmp ((char *) data->sblock.signature, BTRFS_SIGNATURE, sizeof (BTRFS_SIGNATURE) - 1))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
fail:
|
||||
grub_free (data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_btrfs_open (struct grub_file *file __attribute__ ((unused)),
|
||||
const char *name __attribute__ ((unused)))
|
||||
{
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "only detection is supported for Btrfs");
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_btrfs_dir (grub_device_t device,
|
||||
const char *path __attribute__ ((unused)),
|
||||
int (*hook) (const char *filename,
|
||||
const struct grub_dirhook_info *info)
|
||||
__attribute__ ((unused)))
|
||||
{
|
||||
struct grub_btrfs_data *data = grub_btrfs_mount (device->disk);
|
||||
if (grub_errno)
|
||||
return grub_errno;
|
||||
|
||||
grub_free (data);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_btrfs_uuid (grub_device_t device, char **uuid)
|
||||
{
|
||||
struct grub_btrfs_data *data;
|
||||
|
||||
*uuid = NULL;
|
||||
|
||||
data = grub_btrfs_mount (device->disk);
|
||||
if (! data)
|
||||
return grub_errno;
|
||||
|
||||
*uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
|
||||
grub_be_to_cpu16 (data->sblock.uuid[0]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[1]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[2]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[3]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[4]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[5]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[6]),
|
||||
grub_be_to_cpu16 (data->sblock.uuid[7]));
|
||||
|
||||
grub_free (data);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static struct grub_fs grub_btrfs_fs =
|
||||
{
|
||||
.name = "btrfs",
|
||||
.dir = grub_btrfs_dir,
|
||||
.open = grub_btrfs_open,
|
||||
.uuid = grub_btrfs_uuid,
|
||||
};
|
||||
|
||||
GRUB_MOD_INIT(btrfs)
|
||||
{
|
||||
grub_fs_register (&grub_btrfs_fs);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(btrfs)
|
||||
{
|
||||
grub_fs_unregister (&grub_btrfs_fs);
|
||||
}
|
|
@ -728,22 +728,27 @@ grub_ext2_open (struct grub_file *file, const char *name)
|
|||
{
|
||||
struct grub_ext2_data *data;
|
||||
struct grub_fshelp_node *fdiro = 0;
|
||||
grub_err_t err;
|
||||
|
||||
grub_dl_ref (my_mod);
|
||||
|
||||
data = grub_ext2_mount (file->device->disk);
|
||||
if (! data)
|
||||
goto fail;
|
||||
{
|
||||
err = grub_errno;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_ext2_iterate_dir,
|
||||
grub_ext2_read_symlink, GRUB_FSHELP_REG);
|
||||
if (grub_errno)
|
||||
err = grub_fshelp_find_file (name, &data->diropen, &fdiro,
|
||||
grub_ext2_iterate_dir,
|
||||
grub_ext2_read_symlink, GRUB_FSHELP_REG);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
if (! fdiro->inode_read)
|
||||
{
|
||||
grub_ext2_read_inode (data, fdiro->ino, &fdiro->inode);
|
||||
if (grub_errno)
|
||||
err = grub_ext2_read_inode (data, fdiro->ino, &fdiro->inode);
|
||||
if (err)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -763,7 +768,7 @@ grub_ext2_open (struct grub_file *file, const char *name)
|
|||
|
||||
grub_dl_unref (my_mod);
|
||||
|
||||
return grub_errno;
|
||||
return err;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
|
|
|
@ -176,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;
|
||||
|
|
|
@ -25,10 +25,13 @@
|
|||
#include <grub/dl.h>
|
||||
#include <grub/types.h>
|
||||
|
||||
#ifdef MODE_MINIX2
|
||||
#define GRUB_MINIX_MAGIC 0x2468
|
||||
#define GRUB_MINIX_MAGIC_30 0x2478
|
||||
#else
|
||||
#define GRUB_MINIX_MAGIC 0x137F
|
||||
#define GRUB_MINIX2_MAGIC 0x2468
|
||||
#define GRUB_MINIX_MAGIC_30 0x138F
|
||||
#define GRUB_MINIX2_MAGIC_30 0x2478
|
||||
#endif
|
||||
#define GRUB_MINIX_BSIZE 1024U
|
||||
#define GRUB_MINIX_LOG2_BSIZE 1
|
||||
#define GRUB_MINIX_ROOT_INODE 1
|
||||
|
@ -38,20 +41,25 @@
|
|||
#define GRUB_MINIX_IFDIR 0040000U
|
||||
#define GRUB_MINIX_IFLNK 0120000U
|
||||
|
||||
#define GRUB_MINIX_INODE(data,field) (data->version == 1 ? \
|
||||
data->inode. field : data->inode2. field)
|
||||
#define GRUB_MINIX_INODE_ENDIAN(data,field,bits1,bits2) (data->version == 1 ? \
|
||||
grub_le_to_cpu##bits1 (data->inode.field) : \
|
||||
grub_le_to_cpu##bits2 (data->inode2.field))
|
||||
#define GRUB_MINIX_INODE_SIZE(data) GRUB_MINIX_INODE_ENDIAN (data,size,16,32)
|
||||
#define GRUB_MINIX_INODE_MODE(data) GRUB_MINIX_INODE_ENDIAN (data,mode,16,16)
|
||||
#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) GRUB_MINIX_INODE_ENDIAN \
|
||||
(data,dir_zones[blk],16,32)
|
||||
#define GRUB_MINIX_INODE_INDIR_ZONE(data) \
|
||||
GRUB_MINIX_INODE_ENDIAN (data,indir_zone,16,32)
|
||||
#define GRUB_MINIX_INODE_DINDIR_ZONE(data) \
|
||||
GRUB_MINIX_INODE_ENDIAN (data,double_indir_zone,16,32)
|
||||
#define GRUB_MINIX_INODE_BLKSZ(data) (data->version == 1 ? 2 : 4)
|
||||
#ifdef MODE_MINIX2
|
||||
typedef grub_uint32_t grub_minix_uintn_t;
|
||||
#define grub_minix_le_to_cpu_n grub_le_to_cpu32
|
||||
#else
|
||||
typedef grub_uint16_t grub_minix_uintn_t;
|
||||
#define grub_minix_le_to_cpu_n grub_le_to_cpu16
|
||||
#endif
|
||||
|
||||
#define GRUB_MINIX_INODE_BLKSZ(data) sizeof (grub_minix_uintn_t)
|
||||
|
||||
#define GRUB_MINIX_INODE_SIZE(data) (grub_minix_le_to_cpu_n (data->inode.size))
|
||||
#define GRUB_MINIX_INODE_MODE(data) (grub_le_to_cpu16 (data->inode.mode))
|
||||
#define GRUB_MINIX_INODE_DIR_ZONES(data,blk) (grub_minix_le_to_cpu_n \
|
||||
(data->inode.dir_zones[blk]))
|
||||
#define GRUB_MINIX_INODE_INDIR_ZONE(data) (grub_minix_le_to_cpu_n \
|
||||
(data->inode.indir_zone))
|
||||
#define GRUB_MINIX_INODE_DINDIR_ZONE(data) (grub_minix_le_to_cpu_n \
|
||||
(data->inode.double_indir_zone))
|
||||
|
||||
#define GRUB_MINIX_LOG2_ZONESZ (GRUB_MINIX_LOG2_BSIZE \
|
||||
+ grub_le_to_cpu16 (sblock->log2_zone_size))
|
||||
#define GRUB_MINIX_ZONESZ (GRUB_MINIX_BSIZE \
|
||||
|
@ -69,6 +77,7 @@ struct grub_minix_sblock
|
|||
grub_uint16_t magic;
|
||||
};
|
||||
|
||||
#ifndef MODE_MINIX2
|
||||
struct grub_minix_inode
|
||||
{
|
||||
grub_uint16_t mode;
|
||||
|
@ -82,7 +91,9 @@ struct grub_minix_inode
|
|||
grub_uint16_t double_indir_zone;
|
||||
};
|
||||
|
||||
struct grub_minix2_inode
|
||||
#else
|
||||
|
||||
struct grub_minix_inode
|
||||
{
|
||||
grub_uint16_t mode;
|
||||
grub_uint16_t nlinks;
|
||||
|
@ -99,16 +110,16 @@ struct grub_minix2_inode
|
|||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* Information about a "mounted" minix filesystem. */
|
||||
struct grub_minix_data
|
||||
{
|
||||
struct grub_minix_sblock sblock;
|
||||
struct grub_minix_inode inode;
|
||||
struct grub_minix2_inode inode2;
|
||||
int ino;
|
||||
int linknest;
|
||||
grub_disk_t disk;
|
||||
int version;
|
||||
int filename_size;
|
||||
};
|
||||
|
||||
|
@ -128,24 +139,12 @@ grub_minix_get_file_block (struct grub_minix_data *data, unsigned int blk)
|
|||
/* Read the block pointer in ZONE, on the offset NUM. */
|
||||
int grub_get_indir (int zone, int num)
|
||||
{
|
||||
if (data->version == 1)
|
||||
{
|
||||
grub_uint16_t indir16;
|
||||
grub_disk_read (data->disk,
|
||||
zone << GRUB_MINIX_LOG2_ZONESZ,
|
||||
sizeof (grub_uint16_t) * num,
|
||||
sizeof (grub_uint16_t), (char *) &indir16);
|
||||
return grub_le_to_cpu16 (indir16);
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_uint32_t indir32;
|
||||
grub_disk_read (data->disk,
|
||||
zone << GRUB_MINIX_LOG2_ZONESZ,
|
||||
sizeof (grub_uint32_t) * num,
|
||||
sizeof (grub_uint32_t), (char *) &indir32);
|
||||
return grub_le_to_cpu32 (indir32);
|
||||
}
|
||||
grub_minix_uintn_t indirn;
|
||||
grub_disk_read (data->disk,
|
||||
zone << GRUB_MINIX_LOG2_ZONESZ,
|
||||
sizeof (grub_minix_uintn_t) * num,
|
||||
sizeof (grub_minix_uintn_t), (char *) &indirn);
|
||||
return grub_minix_le_to_cpu_n (indirn);
|
||||
}
|
||||
|
||||
/* Direct block. */
|
||||
|
@ -259,27 +258,13 @@ grub_minix_read_inode (struct grub_minix_data *data, int ino)
|
|||
+ grub_le_to_cpu16 (sblock->zone_bmap_size))
|
||||
<< GRUB_MINIX_LOG2_BSIZE);
|
||||
|
||||
if (data->version == 1)
|
||||
{
|
||||
block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
|
||||
int offs = (ino % (GRUB_DISK_SECTOR_SIZE
|
||||
/ sizeof (struct grub_minix_inode))
|
||||
* sizeof (struct grub_minix_inode));
|
||||
|
||||
grub_disk_read (data->disk, block, offs,
|
||||
sizeof (struct grub_minix_inode), &data->inode);
|
||||
}
|
||||
else
|
||||
{
|
||||
block += ino / (GRUB_DISK_SECTOR_SIZE
|
||||
/ sizeof (struct grub_minix2_inode));
|
||||
int offs = (ino
|
||||
% (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix2_inode))
|
||||
* sizeof (struct grub_minix2_inode));
|
||||
|
||||
grub_disk_read (data->disk, block, offs,
|
||||
sizeof (struct grub_minix2_inode),&data->inode2);
|
||||
}
|
||||
block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
|
||||
int offs = (ino % (GRUB_DISK_SECTOR_SIZE
|
||||
/ sizeof (struct grub_minix_inode))
|
||||
* sizeof (struct grub_minix_inode));
|
||||
|
||||
grub_disk_read (data->disk, block, offs,
|
||||
sizeof (struct grub_minix_inode), &data->inode);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
@ -424,25 +409,9 @@ grub_minix_mount (grub_disk_t disk)
|
|||
goto fail;
|
||||
|
||||
if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC)
|
||||
{
|
||||
data->version = 1;
|
||||
data->filename_size = 14;
|
||||
}
|
||||
else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC)
|
||||
{
|
||||
data->version = 2;
|
||||
data->filename_size = 14;
|
||||
}
|
||||
data->filename_size = 14;
|
||||
else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX_MAGIC_30)
|
||||
{
|
||||
data->version = 1;
|
||||
data->filename_size = 30;
|
||||
}
|
||||
else if (grub_le_to_cpu16 (data->sblock.magic) == GRUB_MINIX2_MAGIC_30)
|
||||
{
|
||||
data->version = 2;
|
||||
data->filename_size = 30;
|
||||
}
|
||||
data->filename_size = 30;
|
||||
else
|
||||
goto fail;
|
||||
|
||||
|
@ -453,7 +422,11 @@ grub_minix_mount (grub_disk_t disk)
|
|||
|
||||
fail:
|
||||
grub_free (data);
|
||||
#ifdef MODE_MINIX2
|
||||
grub_error (GRUB_ERR_BAD_FS, "not a minix2 filesystem");
|
||||
#else
|
||||
grub_error (GRUB_ERR_BAD_FS, "not a minix filesystem");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -583,32 +556,36 @@ grub_minix_close (grub_file_t file)
|
|||
}
|
||||
|
||||
|
||||
static grub_err_t
|
||||
grub_minix_label (grub_device_t device __attribute ((unused)),
|
||||
char **label __attribute ((unused)))
|
||||
{
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
static struct grub_fs grub_minix_fs =
|
||||
{
|
||||
#ifdef MODE_MINIX2
|
||||
.name = "minix2",
|
||||
#else
|
||||
.name = "minix",
|
||||
#endif
|
||||
.dir = grub_minix_dir,
|
||||
.open = grub_minix_open,
|
||||
.read = grub_minix_read,
|
||||
.close = grub_minix_close,
|
||||
.label = grub_minix_label,
|
||||
.next = 0
|
||||
};
|
||||
|
||||
#ifdef MODE_MINIX2
|
||||
GRUB_MOD_INIT(minix2)
|
||||
#else
|
||||
GRUB_MOD_INIT(minix)
|
||||
#endif
|
||||
{
|
||||
grub_fs_register (&grub_minix_fs);
|
||||
my_mod = mod;
|
||||
}
|
||||
|
||||
#ifdef MODE_MINIX2
|
||||
GRUB_MOD_FINI(minix2)
|
||||
#else
|
||||
GRUB_MOD_FINI(minix)
|
||||
#endif
|
||||
{
|
||||
grub_fs_unregister (&grub_minix_fs);
|
||||
}
|
||||
|
|
2
grub-core/fs/minix2.c
Normal file
2
grub-core/fs/minix2.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define MODE_MINIX2 1
|
||||
#include "minix.c"
|
75
grub-core/gnulib/basename-lgpl.c
Normal file
75
grub-core/gnulib/basename-lgpl.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* basename.c -- return the last element in a file name
|
||||
|
||||
Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2010 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "dirname.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Return the address of the last file name component of NAME. If
|
||||
NAME has no relative file name components because it is a file
|
||||
system root, return the empty string. */
|
||||
|
||||
char *
|
||||
last_component (char const *name)
|
||||
{
|
||||
char const *base = name + FILE_SYSTEM_PREFIX_LEN (name);
|
||||
char const *p;
|
||||
bool saw_slash = false;
|
||||
|
||||
while (ISSLASH (*base))
|
||||
base++;
|
||||
|
||||
for (p = base; *p; p++)
|
||||
{
|
||||
if (ISSLASH (*p))
|
||||
saw_slash = true;
|
||||
else if (saw_slash)
|
||||
{
|
||||
base = p;
|
||||
saw_slash = false;
|
||||
}
|
||||
}
|
||||
|
||||
return (char *) base;
|
||||
}
|
||||
|
||||
/* Return the length of the basename NAME. Typically NAME is the
|
||||
value returned by base_name or last_component. Act like strlen
|
||||
(NAME), except omit all trailing slashes. */
|
||||
|
||||
size_t
|
||||
base_len (char const *name)
|
||||
{
|
||||
size_t len;
|
||||
size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (name);
|
||||
|
||||
for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--)
|
||||
continue;
|
||||
|
||||
if (DOUBLE_SLASH_IS_DISTINCT_ROOT && len == 1
|
||||
&& ISSLASH (name[0]) && ISSLASH (name[1]) && ! name[2])
|
||||
return 2;
|
||||
|
||||
if (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE && prefix_len
|
||||
&& len == prefix_len && ISSLASH (name[prefix_len]))
|
||||
return prefix_len + 1;
|
||||
|
||||
return len;
|
||||
}
|
58
grub-core/gnulib/basename.c
Normal file
58
grub-core/gnulib/basename.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* basename.c -- return the last element in a file name
|
||||
|
||||
Copyright (C) 1990, 1998-2001, 2003-2006, 2009-2010 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "dirname.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "xalloc.h"
|
||||
#include "xstrndup.h"
|
||||
|
||||
char *
|
||||
base_name (char const *name)
|
||||
{
|
||||
char const *base = last_component (name);
|
||||
size_t length;
|
||||
|
||||
/* If there is no last component, then name is a file system root or the
|
||||
empty string. */
|
||||
if (! *base)
|
||||
return xstrndup (name, base_len (name));
|
||||
|
||||
/* Collapse a sequence of trailing slashes into one. */
|
||||
length = base_len (base);
|
||||
if (ISSLASH (base[length]))
|
||||
length++;
|
||||
|
||||
/* On systems with drive letters, `a/b:c' must return `./b:c' rather
|
||||
than `b:c' to avoid confusion with a drive letter. On systems
|
||||
with pure POSIX semantics, this is not an issue. */
|
||||
if (FILE_SYSTEM_PREFIX_LEN (base))
|
||||
{
|
||||
char *p = xmalloc (length + 3);
|
||||
p[0] = '.';
|
||||
p[1] = '/';
|
||||
memcpy (p + 2, base, length);
|
||||
p[length + 2] = '\0';
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Finally, copy the basename. */
|
||||
return xstrndup (base, length);
|
||||
}
|
86
grub-core/gnulib/dirname-lgpl.c
Normal file
86
grub-core/gnulib/dirname-lgpl.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
/* dirname.c -- return all but the last element in a file name
|
||||
|
||||
Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2010 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "dirname.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Return the length of the prefix of FILE that will be used by
|
||||
dir_name. If FILE is in the working directory, this returns zero
|
||||
even though `dir_name (FILE)' will return ".". Works properly even
|
||||
if there are trailing slashes (by effectively ignoring them). */
|
||||
|
||||
size_t
|
||||
dir_len (char const *file)
|
||||
{
|
||||
size_t prefix_length = FILE_SYSTEM_PREFIX_LEN (file);
|
||||
size_t length;
|
||||
|
||||
/* Advance prefix_length beyond important leading slashes. */
|
||||
prefix_length += (prefix_length != 0
|
||||
? (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
||||
&& ISSLASH (file[prefix_length]))
|
||||
: (ISSLASH (file[0])
|
||||
? ((DOUBLE_SLASH_IS_DISTINCT_ROOT
|
||||
&& ISSLASH (file[1]) && ! ISSLASH (file[2])
|
||||
? 2 : 1))
|
||||
: 0));
|
||||
|
||||
/* Strip the basename and any redundant slashes before it. */
|
||||
for (length = last_component (file) - file;
|
||||
prefix_length < length; length--)
|
||||
if (! ISSLASH (file[length - 1]))
|
||||
break;
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
/* In general, we can't use the builtin `dirname' function if available,
|
||||
since it has different meanings in different environments.
|
||||
In some environments the builtin `dirname' modifies its argument.
|
||||
|
||||
Return the leading directories part of FILE, allocated with malloc.
|
||||
Works properly even if there are trailing slashes (by effectively
|
||||
ignoring them). Return NULL on failure.
|
||||
|
||||
If lstat (FILE) would succeed, then { chdir (dir_name (FILE));
|
||||
lstat (base_name (FILE)); } will access the same file. Likewise,
|
||||
if the sequence { chdir (dir_name (FILE));
|
||||
rename (base_name (FILE), "foo"); } succeeds, you have renamed FILE
|
||||
to "foo" in the same directory FILE was in. */
|
||||
|
||||
char *
|
||||
mdir_name (char const *file)
|
||||
{
|
||||
size_t length = dir_len (file);
|
||||
bool append_dot = (length == 0
|
||||
|| (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
||||
&& length == FILE_SYSTEM_PREFIX_LEN (file)
|
||||
&& file[2] != '\0' && ! ISSLASH (file[2])));
|
||||
char *dir = malloc (length + append_dot + 1);
|
||||
if (!dir)
|
||||
return NULL;
|
||||
memcpy (dir, file, length);
|
||||
if (append_dot)
|
||||
dir[length++] = '.';
|
||||
dir[length] = '\0';
|
||||
return dir;
|
||||
}
|
38
grub-core/gnulib/dirname.c
Normal file
38
grub-core/gnulib/dirname.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* dirname.c -- return all but the last element in a file name
|
||||
|
||||
Copyright (C) 1990, 1998, 2000-2001, 2003-2006, 2009-2010 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "dirname.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "xalloc.h"
|
||||
|
||||
/* Just like mdir_name (dirname-lgpl.c), except, rather than
|
||||
returning NULL upon malloc failure, here, we report the
|
||||
"memory exhausted" condition and exit. */
|
||||
|
||||
char *
|
||||
dir_name (char const *file)
|
||||
{
|
||||
char *result = mdir_name (file);
|
||||
if (!result)
|
||||
xalloc_die ();
|
||||
return result;
|
||||
}
|
74
grub-core/gnulib/dirname.h
Normal file
74
grub-core/gnulib/dirname.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/* Take file names apart into directory and base names.
|
||||
|
||||
Copyright (C) 1998, 2001, 2003-2006, 2009-2010 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef DIRNAME_H_
|
||||
# define DIRNAME_H_ 1
|
||||
|
||||
# include <stdbool.h>
|
||||
# include <stddef.h>
|
||||
|
||||
# ifndef DIRECTORY_SEPARATOR
|
||||
# define DIRECTORY_SEPARATOR '/'
|
||||
# endif
|
||||
|
||||
# ifndef ISSLASH
|
||||
# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
|
||||
# endif
|
||||
|
||||
# ifndef FILE_SYSTEM_PREFIX_LEN
|
||||
# if FILE_SYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
|
||||
/* This internal macro assumes ASCII, but all hosts that support drive
|
||||
letters use ASCII. */
|
||||
# define _IS_DRIVE_LETTER(c) (((unsigned int) (c) | ('a' - 'A')) - 'a' \
|
||||
<= 'z' - 'a')
|
||||
# define FILE_SYSTEM_PREFIX_LEN(Filename) \
|
||||
(_IS_DRIVE_LETTER ((Filename)[0]) && (Filename)[1] == ':' ? 2 : 0)
|
||||
# else
|
||||
# define FILE_SYSTEM_PREFIX_LEN(Filename) 0
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifndef FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
||||
# define FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE 0
|
||||
# endif
|
||||
|
||||
# ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
|
||||
# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
|
||||
# endif
|
||||
|
||||
# if FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
|
||||
# define IS_ABSOLUTE_FILE_NAME(F) ISSLASH ((F)[FILE_SYSTEM_PREFIX_LEN (F)])
|
||||
# else
|
||||
# define IS_ABSOLUTE_FILE_NAME(F) \
|
||||
(ISSLASH ((F)[0]) || 0 < FILE_SYSTEM_PREFIX_LEN (F))
|
||||
# endif
|
||||
# define IS_RELATIVE_FILE_NAME(F) (! IS_ABSOLUTE_FILE_NAME (F))
|
||||
|
||||
# if GNULIB_DIRNAME
|
||||
char *base_name (char const *file);
|
||||
char *dir_name (char const *file);
|
||||
# endif
|
||||
|
||||
char *mdir_name (char const *file);
|
||||
size_t base_len (char const *file);
|
||||
size_t dir_len (char const *file);
|
||||
char *last_component (char const *file);
|
||||
|
||||
bool strip_trailing_slashes (char *file);
|
||||
|
||||
#endif /* not DIRNAME_H_ */
|
|
@ -88,6 +88,15 @@ extern void __error_at_line (int status, int errnum, const char *file_name,
|
|||
# include <fcntl.h>
|
||||
# include <unistd.h>
|
||||
|
||||
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
/* Get declarations of the Win32 API functions. */
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
# endif
|
||||
|
||||
/* The gnulib override of fcntl is not needed in this file. */
|
||||
# undef fcntl
|
||||
|
||||
# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
|
||||
# ifndef HAVE_DECL_STRERROR_R
|
||||
"this configure-time declaration test was not run"
|
||||
|
@ -104,10 +113,29 @@ extern char *program_name;
|
|||
# endif /* HAVE_STRERROR_R || defined strerror_r */
|
||||
#endif /* not _LIBC */
|
||||
|
||||
#if !_LIBC
|
||||
/* Return non-zero if FD is open. */
|
||||
static inline int
|
||||
is_open (int fd)
|
||||
{
|
||||
# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
|
||||
/* On Win32: The initial state of unassigned standard file descriptors is
|
||||
that they are open but point to an INVALID_HANDLE_VALUE. There is no
|
||||
fcntl, and the gnulib replacement fcntl does not support F_GETFL. */
|
||||
return (HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE;
|
||||
# else
|
||||
# ifndef F_GETFL
|
||||
# error Please port fcntl to your platform
|
||||
# endif
|
||||
return 0 <= fcntl (fd, F_GETFL);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
flush_stdout (void)
|
||||
{
|
||||
#if !_LIBC && defined F_GETFL
|
||||
#if !_LIBC
|
||||
int stdout_fd;
|
||||
|
||||
# if GNULIB_FREOPEN_SAFER
|
||||
|
@ -124,7 +152,7 @@ flush_stdout (void)
|
|||
/* POSIX states that fflush (stdout) after fclose is unspecified; it
|
||||
is safe in glibc, but not on all other platforms. fflush (NULL)
|
||||
is always defined, but too draconian. */
|
||||
if (0 <= stdout_fd && 0 <= fcntl (stdout_fd, F_GETFL))
|
||||
if (0 <= stdout_fd && is_open (stdout_fd))
|
||||
#endif
|
||||
fflush (stdout);
|
||||
}
|
||||
|
|
|
@ -348,8 +348,6 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||
int long_only, struct _getopt_data *d, int posixly_correct)
|
||||
{
|
||||
int print_errors = d->opterr;
|
||||
if (optstring[0] == ':')
|
||||
print_errors = 0;
|
||||
|
||||
if (argc < 1)
|
||||
return -1;
|
||||
|
@ -364,6 +362,10 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||
posixly_correct);
|
||||
d->__initialized = 1;
|
||||
}
|
||||
else if (optstring[0] == '-' || optstring[0] == '+')
|
||||
optstring++;
|
||||
if (optstring[0] == ':')
|
||||
print_errors = 0;
|
||||
|
||||
/* Test whether ARGV[optind] points to a non-option argument.
|
||||
Either it does not have option syntax, or there is an environment flag
|
||||
|
@ -633,8 +635,8 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||
char *buf;
|
||||
|
||||
if (__asprintf (&buf, _("\
|
||||
%s: option '%s' requires an argument\n"),
|
||||
argv[0], argv[d->optind - 1]) >= 0)
|
||||
%s: option '--%s' requires an argument\n"),
|
||||
argv[0], pfound->name) >= 0)
|
||||
{
|
||||
_IO_flockfile (stderr);
|
||||
|
||||
|
@ -651,8 +653,8 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||
}
|
||||
#else
|
||||
fprintf (stderr,
|
||||
_("%s: option '%s' requires an argument\n"),
|
||||
argv[0], argv[d->optind - 1]);
|
||||
_("%s: option '--%s' requires an argument\n"),
|
||||
argv[0], pfound->name);
|
||||
#endif
|
||||
}
|
||||
d->__nextchar += strlen (d->__nextchar);
|
||||
|
@ -736,13 +738,13 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||
|
||||
{
|
||||
char c = *d->__nextchar++;
|
||||
char *temp = strchr (optstring, c);
|
||||
const char *temp = strchr (optstring, c);
|
||||
|
||||
/* Increment `optind' when we start to process its last character. */
|
||||
if (*d->__nextchar == '\0')
|
||||
++d->optind;
|
||||
|
||||
if (temp == NULL || c == ':')
|
||||
if (temp == NULL || c == ':' || c == ';')
|
||||
{
|
||||
if (print_errors)
|
||||
{
|
||||
|
@ -864,7 +866,10 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
else if (long_only
|
||||
|| pfound->has_arg != p->has_arg
|
||||
|| pfound->flag != p->flag
|
||||
|| pfound->val != p->val)
|
||||
/* Second or later nonexact match found. */
|
||||
ambig = 1;
|
||||
}
|
||||
|
@ -876,7 +881,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||
char *buf;
|
||||
|
||||
if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"),
|
||||
argv[0], argv[d->optind]) >= 0)
|
||||
argv[0], d->optarg) >= 0)
|
||||
{
|
||||
_IO_flockfile (stderr);
|
||||
|
||||
|
@ -892,7 +897,7 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||
}
|
||||
#else
|
||||
fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"),
|
||||
argv[0], argv[d->optind]);
|
||||
argv[0], d->optarg);
|
||||
#endif
|
||||
}
|
||||
d->__nextchar += strlen (d->__nextchar);
|
||||
|
@ -955,8 +960,8 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||
char *buf;
|
||||
|
||||
if (__asprintf (&buf, _("\
|
||||
%s: option '%s' requires an argument\n"),
|
||||
argv[0], argv[d->optind - 1]) >= 0)
|
||||
%s: option '-W %s' requires an argument\n"),
|
||||
argv[0], pfound->name) >= 0)
|
||||
{
|
||||
_IO_flockfile (stderr);
|
||||
|
||||
|
@ -972,15 +977,17 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
|
|||
free (buf);
|
||||
}
|
||||
#else
|
||||
fprintf (stderr,
|
||||
_("%s: option '%s' requires an argument\n"),
|
||||
argv[0], argv[d->optind - 1]);
|
||||
fprintf (stderr, _("\
|
||||
%s: option '-W %s' requires an argument\n"),
|
||||
argv[0], pfound->name);
|
||||
#endif
|
||||
}
|
||||
d->__nextchar += strlen (d->__nextchar);
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
else
|
||||
d->optarg = NULL;
|
||||
d->__nextchar += strlen (d->__nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
|
|
|
@ -30,6 +30,40 @@ extern int _getopt_internal (int ___argc, char **___argv,
|
|||
/* Reentrant versions which can handle parsing multiple argument
|
||||
vectors at the same time. */
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
If the caller did not specify anything,
|
||||
the default is REQUIRE_ORDER if the environment variable
|
||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options;
|
||||
stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
This mode of operation is selected by either setting the environment
|
||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||
of the list of option characters, or by calling getopt.
|
||||
|
||||
PERMUTE is the default. We permute the contents of ARGV as we
|
||||
scan, so that eventually all the non-options are at the end.
|
||||
This allows options to be given in any order, even with programs
|
||||
that were not written to expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were
|
||||
written to expect options and other ARGV-elements in any order
|
||||
and that care about the ordering of the two. We describe each
|
||||
non-option ARGV-element as if it were the argument of an option
|
||||
with character code 1. Using `-' as the first character of the
|
||||
list of option characters selects this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
|
||||
|
||||
enum __ord
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
};
|
||||
|
||||
/* Data type for reentrant functions. */
|
||||
struct _getopt_data
|
||||
{
|
||||
|
@ -54,39 +88,8 @@ struct _getopt_data
|
|||
by advancing to the next ARGV-element. */
|
||||
char *__nextchar;
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
If the caller did not specify anything,
|
||||
the default is REQUIRE_ORDER if the environment variable
|
||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options;
|
||||
stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
This mode of operation is selected by either setting the environment
|
||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||
of the list of option characters, or by calling getopt.
|
||||
|
||||
PERMUTE is the default. We permute the contents of ARGV as we
|
||||
scan, so that eventually all the non-options are at the end.
|
||||
This allows options to be given in any order, even with programs
|
||||
that were not written to expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were
|
||||
written to expect options and other ARGV-elements in any order
|
||||
and that care about the ordering of the two. We describe each
|
||||
non-option ARGV-element as if it were the argument of an option
|
||||
with character code 1. Using `-' as the first character of the
|
||||
list of option characters selects this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
|
||||
|
||||
enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} __ordering;
|
||||
/* See __ord above. */
|
||||
enum __ord __ordering;
|
||||
|
||||
/* If the POSIXLY_CORRECT environment variable is set
|
||||
or getopt was called. */
|
||||
|
|
|
@ -114,10 +114,10 @@ typedef unsigned long int reg_syntax_t;
|
|||
/* If this bit is set, then ^ and $ are always anchors (outside bracket
|
||||
expressions, of course).
|
||||
If this bit is not set, then it depends:
|
||||
^ is an anchor if it is at the beginning of a regular
|
||||
expression or after an open-group or an alternation operator;
|
||||
$ is an anchor if it is at the end of a regular expression, or
|
||||
before a close-group or an alternation operator.
|
||||
^ is an anchor if it is at the beginning of a regular
|
||||
expression or after an open-group or an alternation operator;
|
||||
$ is an anchor if it is at the end of a regular expression, or
|
||||
before a close-group or an alternation operator.
|
||||
|
||||
This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
|
||||
POSIX draft 11.2 says that * etc. in leading positions is undefined.
|
||||
|
@ -219,8 +219,8 @@ typedef unsigned long int reg_syntax_t;
|
|||
whether ^ should be special. */
|
||||
# define RE_CARET_ANCHORS_HERE (RE_ICASE << 1)
|
||||
|
||||
/* If this bit is set, then \{ cannot be first in an bre or
|
||||
immediately after an alternation or begin-group operator. */
|
||||
/* If this bit is set, then \{ cannot be first in a regex or
|
||||
immediately after an alternation, open-group or \} operator. */
|
||||
# define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1)
|
||||
|
||||
/* If this bit is set, then no_sub will be set to 1 during
|
||||
|
@ -495,8 +495,8 @@ struct re_pattern_buffer
|
|||
#endif
|
||||
unsigned int _REG_RE_NAME (regs_allocated) : 2;
|
||||
|
||||
/* Set to zero when `regex_compile' compiles a pattern; set to one
|
||||
by `re_compile_fastmap' if it updates the fastmap. */
|
||||
/* Set to zero when `re_compile_pattern' compiles a pattern; set to
|
||||
one by `re_compile_fastmap' if it updates the fastmap. */
|
||||
unsigned int _REG_RE_NAME (fastmap_accurate) : 1;
|
||||
|
||||
/* If set, `re_match_2' does not return information about
|
||||
|
@ -610,8 +610,8 @@ extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer,
|
|||
register data.
|
||||
|
||||
Unless this function is called, the first search or match using
|
||||
PATTERN_BUFFER will allocate its own register data, without
|
||||
freeing the old data. */
|
||||
BUFFER will allocate its own register data, without freeing the old
|
||||
data. */
|
||||
extern void re_set_registers (struct re_pattern_buffer *__buffer,
|
||||
struct re_registers *__regs,
|
||||
__re_size_t __num_regs,
|
||||
|
|
|
@ -733,15 +733,17 @@ re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
|
|||
mbstate_t cur_state;
|
||||
wchar_t wc2;
|
||||
Idx mlen = raw + pstr->len - p;
|
||||
unsigned char buf[6];
|
||||
size_t mbclen;
|
||||
|
||||
#if 0 /* dead code: buf is set but never used */
|
||||
unsigned char buf[6];
|
||||
if (BE (pstr->trans != NULL, 0))
|
||||
{
|
||||
int i = mlen < 6 ? mlen : 6;
|
||||
while (--i >= 0)
|
||||
buf[i] = pstr->trans[p[i]];
|
||||
}
|
||||
#endif
|
||||
/* XXX Don't use mbrtowc, we know which conversion
|
||||
to use (UTF-8 -> UCS4). */
|
||||
memset (&cur_state, 0, sizeof (cur_state));
|
||||
|
|
|
@ -467,6 +467,8 @@ static unsigned int re_string_context_at (const re_string_t *input, Idx idx,
|
|||
# else
|
||||
/* alloca is implemented with malloc, so just use malloc. */
|
||||
# define __libc_use_alloca(n) 0
|
||||
# undef alloca
|
||||
# define alloca(n) malloc (n)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
|
45
grub-core/gnulib/stripslash.c
Normal file
45
grub-core/gnulib/stripslash.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/* stripslash.c -- remove redundant trailing slashes from a file name
|
||||
|
||||
Copyright (C) 1990, 2001, 2003-2006, 2009-2010 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "dirname.h"
|
||||
|
||||
/* Remove trailing slashes from FILE. Return true if a trailing slash
|
||||
was removed. This is useful when using file name completion from a
|
||||
shell that adds a "/" after directory names (such as tcsh and
|
||||
bash), because on symlinks to directories, several system calls
|
||||
have different semantics according to whether a trailing slash is
|
||||
present. */
|
||||
|
||||
bool
|
||||
strip_trailing_slashes (char *file)
|
||||
{
|
||||
char *base = last_component (file);
|
||||
char *base_lim;
|
||||
bool had_slash;
|
||||
|
||||
/* last_component returns "" for file system roots, but we need to turn
|
||||
`///' into `/'. */
|
||||
if (! *base)
|
||||
base = file;
|
||||
base_lim = base + base_len (base);
|
||||
had_slash = (*base_lim != '\0');
|
||||
*base_lim = '\0';
|
||||
return had_slash;
|
||||
}
|
|
@ -39,8 +39,8 @@ static grub_extcmd_t cmd;
|
|||
|
||||
GRUB_MOD_INIT(hello)
|
||||
{
|
||||
cmd = grub_register_extcmd ("hello", grub_cmd_hello, GRUB_COMMAND_FLAG_BOTH,
|
||||
0, N_("Say \"Hello World\"."), 0);
|
||||
cmd = grub_register_extcmd ("hello", grub_cmd_hello, 0, 0,
|
||||
N_("Say \"Hello World\"."), 0);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(hello)
|
||||
|
|
|
@ -40,7 +40,7 @@ grub_register_command_prio (const char *name,
|
|||
cmd->summary = (summary) ? summary : "";
|
||||
cmd->description = description;
|
||||
|
||||
cmd->flags = GRUB_COMMAND_FLAG_BOTH;
|
||||
cmd->flags = 0;
|
||||
cmd->prio = prio;
|
||||
|
||||
grub_prio_list_insert (GRUB_AS_PRIO_LIST_P (&grub_command_list),
|
||||
|
|
|
@ -103,7 +103,7 @@ grub_device_iterate (int (*hook) (const char *name))
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (dev->disk && dev->disk->has_partitions)
|
||||
if (dev->disk)
|
||||
{
|
||||
struct part_ent *p;
|
||||
int ret = 0;
|
||||
|
|
|
@ -281,12 +281,6 @@ grub_disk_open (const char *name)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (p && ! disk->has_partitions)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_DEVICE, "no partition on this disk");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
disk->dev = dev;
|
||||
|
||||
if (p)
|
||||
|
|
|
@ -66,10 +66,33 @@ grub_efi_set_prefix (void)
|
|||
path = grub_strdup (pptr);
|
||||
}
|
||||
|
||||
if (!device || !path)
|
||||
if ((!device || device[0] == ',' || !device[0]) || !path)
|
||||
image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||
if (image && !device)
|
||||
device = grub_efidisk_get_device_name (image->device_handle);
|
||||
if (image)
|
||||
{
|
||||
if (!device)
|
||||
device = grub_efidisk_get_device_name (image->device_handle);
|
||||
else if (device[0] == ',' || !device[0])
|
||||
{
|
||||
/* We have a partition, but still need to fill in the drive. */
|
||||
char *image_device, *comma, *new_device;
|
||||
|
||||
image_device = grub_efidisk_get_device_name (image->device_handle);
|
||||
comma = grub_strchr (image_device, ',');
|
||||
if (comma)
|
||||
{
|
||||
char *drive = grub_strndup (image_device, comma - image_device);
|
||||
new_device = grub_xasprintf ("%s%s", drive, device);
|
||||
grub_free (drive);
|
||||
}
|
||||
else
|
||||
new_device = grub_xasprintf ("%s%s", image_device, device);
|
||||
|
||||
grub_free (image_device);
|
||||
grub_free (device);
|
||||
device = new_device;
|
||||
}
|
||||
}
|
||||
|
||||
if (image && !path)
|
||||
{
|
||||
|
|
|
@ -7,7 +7,20 @@
|
|||
#elif defined(__sparc__)
|
||||
#include "../sparc64/cache.S"
|
||||
#elif defined(__mips__)
|
||||
#include "../mips/cache.S"
|
||||
/* On MIPS we must go through standard functions. */
|
||||
#include <grub/symbol.h>
|
||||
|
||||
FUNCTION (grub_cpu_flush_cache)
|
||||
FUNCTION (grub_arch_sync_caches)
|
||||
.set nomacro
|
||||
.set noreorder
|
||||
lui $t0, %hi(_flush_cache)
|
||||
addui $t0, $t0, %lo(_flush_cache)
|
||||
move $a3, $zero
|
||||
jr $t0
|
||||
nop
|
||||
.set reorder
|
||||
.set macro
|
||||
#elif defined(__powerpc__)
|
||||
#include "../powerpc/cache.S"
|
||||
#else
|
||||
|
|
|
@ -102,49 +102,18 @@ grub_ncurses_setcolorstate (struct grub_term_output *term,
|
|||
}
|
||||
}
|
||||
|
||||
static int saved_char = ERR;
|
||||
|
||||
static int
|
||||
grub_ncurses_checkkey (struct grub_term_input *term __attribute__ ((unused)))
|
||||
{
|
||||
int c;
|
||||
|
||||
/* Check for SAVED_CHAR. This should not be true, because this
|
||||
means checkkey is called twice continuously. */
|
||||
if (saved_char != ERR)
|
||||
return saved_char;
|
||||
|
||||
wtimeout (stdscr, 100);
|
||||
c = getch ();
|
||||
/* If C is not ERR, then put it back in the input queue. */
|
||||
if (c != ERR)
|
||||
{
|
||||
saved_char = c;
|
||||
return c;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused)))
|
||||
{
|
||||
int c;
|
||||
|
||||
/* If checkkey has already got a character, then return it. */
|
||||
if (saved_char != ERR)
|
||||
{
|
||||
c = saved_char;
|
||||
saved_char = ERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
wtimeout (stdscr, -1);
|
||||
c = getch ();
|
||||
}
|
||||
wtimeout (stdscr, 100);
|
||||
c = getch ();
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case ERR:
|
||||
return -1;
|
||||
case KEY_LEFT:
|
||||
c = GRUB_TERM_LEFT;
|
||||
break;
|
||||
|
@ -288,7 +257,6 @@ grub_ncurses_fini (struct grub_term_output *term __attribute__ ((unused)))
|
|||
static struct grub_term_input grub_ncurses_term_input =
|
||||
{
|
||||
.name = "console",
|
||||
.checkkey = grub_ncurses_checkkey,
|
||||
.getkey = grub_ncurses_getkey,
|
||||
};
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <grub/kernel.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/emu/misc.h>
|
||||
#include <grub/disk.h>
|
||||
|
||||
void
|
||||
grub_register_exported_symbols (void)
|
||||
|
@ -48,3 +49,21 @@ grub_emu_init (void)
|
|||
{
|
||||
grub_no_autoload = 1;
|
||||
}
|
||||
|
||||
#ifdef GRUB_LINKER_HAVE_INIT
|
||||
void
|
||||
grub_arch_dl_init_linker (void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
grub_emu_post_init (void)
|
||||
{
|
||||
grub_lvm_fini ();
|
||||
grub_mdraid_fini ();
|
||||
grub_raid_fini ();
|
||||
grub_raid_init ();
|
||||
grub_mdraid_init ();
|
||||
grub_lvm_init ();
|
||||
}
|
||||
|
|
|
@ -228,8 +228,8 @@ find_root_device_from_libzfs (const char *dir)
|
|||
|
||||
#ifdef __MINGW32__
|
||||
|
||||
static char *
|
||||
find_root_device (const char *dir __attribute__ ((unused)),
|
||||
char *
|
||||
grub_find_device (const char *dir __attribute__ ((unused)),
|
||||
dev_t dev __attribute__ ((unused)))
|
||||
{
|
||||
return 0;
|
||||
|
@ -237,13 +237,22 @@ find_root_device (const char *dir __attribute__ ((unused)),
|
|||
|
||||
#elif ! defined(__CYGWIN__)
|
||||
|
||||
static char *
|
||||
find_root_device (const char *dir, dev_t dev)
|
||||
char *
|
||||
grub_find_device (const char *dir, dev_t dev)
|
||||
{
|
||||
DIR *dp;
|
||||
char *saved_cwd;
|
||||
struct dirent *ent;
|
||||
|
||||
if (! dir)
|
||||
{
|
||||
#ifdef __CYGWIN__
|
||||
return NULL;
|
||||
#else
|
||||
dir = "/dev";
|
||||
#endif
|
||||
}
|
||||
|
||||
dp = opendir (dir);
|
||||
if (! dp)
|
||||
return 0;
|
||||
|
@ -292,7 +301,7 @@ find_root_device (const char *dir, dev_t dev)
|
|||
/* Find it recursively. */
|
||||
char *res;
|
||||
|
||||
res = find_root_device (ent->d_name, dev);
|
||||
res = grub_find_device (ent->d_name, dev);
|
||||
|
||||
if (res)
|
||||
{
|
||||
|
@ -402,8 +411,8 @@ get_bootsec_serial (const char *os_dev, int mbr)
|
|||
return serial;
|
||||
}
|
||||
|
||||
static char *
|
||||
find_cygwin_root_device (const char *path, dev_t dev)
|
||||
char *
|
||||
grub_find_device (const char *path, dev_t dev)
|
||||
{
|
||||
/* No root device for /cygdrive. */
|
||||
if (dev == (DEV_CYGDRIVE_MAJOR << 16))
|
||||
|
@ -424,7 +433,7 @@ find_cygwin_root_device (const char *path, dev_t dev)
|
|||
|
||||
/* Cygwin returns the partition serial number in stat.st_dev.
|
||||
This is never identical to the device number of the emulated
|
||||
/dev/sdXN device, so above find_root_device () does not work.
|
||||
/dev/sdXN device, so above grub_find_device () does not work.
|
||||
Search the partition with the same serial in boot sector instead. */
|
||||
char devpath[sizeof ("/dev/sda15") + 13]; /* Size + Paranoia. */
|
||||
int d;
|
||||
|
@ -529,12 +538,12 @@ grub_guess_root_device (const char *dir)
|
|||
|
||||
#ifdef __CYGWIN__
|
||||
/* Cygwin specific function. */
|
||||
os_dev = find_cygwin_root_device (dir, st.st_dev);
|
||||
os_dev = grub_find_device (dir, st.st_dev);
|
||||
|
||||
#else
|
||||
|
||||
/* This might be truly slow, but is there any better way? */
|
||||
os_dev = find_root_device ("/dev", st.st_dev);
|
||||
os_dev = grub_find_device ("/dev", st.st_dev);
|
||||
#endif
|
||||
#endif /* !__GNU__ */
|
||||
|
||||
|
@ -572,6 +581,10 @@ int
|
|||
grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused)))
|
||||
{
|
||||
#ifdef __linux__
|
||||
/* User explicitly claims that this drive is visible by BIOS. */
|
||||
if (grub_util_biosdisk_is_present (os_dev))
|
||||
return GRUB_DEV_ABSTRACTION_NONE;
|
||||
|
||||
/* Check for LVM. */
|
||||
if (!strncmp (os_dev, "/dev/mapper/", 12)
|
||||
&& ! grub_util_is_dmraid (os_dev)
|
||||
|
|
|
@ -221,7 +221,6 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk)
|
|||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
|
||||
"no mapping exists for `%s'", name);
|
||||
|
||||
disk->has_partitions = 1;
|
||||
disk->id = drive;
|
||||
disk->data = data = xmalloc (sizeof (struct grub_util_biosdisk_data));
|
||||
data->dev = NULL;
|
||||
|
@ -956,13 +955,16 @@ read_device_map (const char *dev_map)
|
|||
#ifdef __linux__
|
||||
/* On Linux, the devfs uses symbolic links horribly, and that
|
||||
confuses the interface very much, so use realpath to expand
|
||||
symbolic links. */
|
||||
map[drive].device = xmalloc (PATH_MAX);
|
||||
if (! realpath (p, map[drive].device))
|
||||
grub_util_error ("cannot get the real path of `%s'", p);
|
||||
#else
|
||||
map[drive].device = xstrdup (p);
|
||||
symbolic links. Leave /dev/mapper/ alone, though. */
|
||||
if (strncmp (p, "/dev/mapper/", 12) != 0)
|
||||
{
|
||||
map[drive].device = xmalloc (PATH_MAX);
|
||||
if (! realpath (p, map[drive].device))
|
||||
grub_util_error ("cannot get the real path of `%s'", p);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
map[drive].device = xstrdup (p);
|
||||
}
|
||||
|
||||
fclose (fp);
|
||||
|
@ -1117,6 +1119,16 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
|
|||
return path;
|
||||
}
|
||||
|
||||
if (strncmp ("md", p, 2) == 0
|
||||
&& p[2] >= '0' && p[2] <= '9')
|
||||
{
|
||||
char *ptr = p + 2;
|
||||
while (*ptr >= '0' && *ptr <= '9')
|
||||
ptr++;
|
||||
*ptr = 0;
|
||||
return path;
|
||||
}
|
||||
|
||||
/* If this is an IDE, SCSI or Virtio disk. */
|
||||
if (strncmp ("vdisk", p, 5) == 0
|
||||
&& p[5] >= 'a' && p[5] <= 'z')
|
||||
|
@ -1144,22 +1156,22 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
|
|||
}
|
||||
|
||||
#ifdef HAVE_DEVICE_MAPPER
|
||||
/* If this is a DM-RAID device. */
|
||||
if ((strncmp ("mapper/", p, 7) == 0))
|
||||
/* If this is a DM-RAID device.
|
||||
Compare os_dev rather than path here, since nodes under
|
||||
/dev/mapper/ are often symlinks. */
|
||||
if ((strncmp ("/dev/mapper/", os_dev, 12) == 0))
|
||||
{
|
||||
static struct dm_tree *tree = NULL;
|
||||
struct dm_tree *tree;
|
||||
uint32_t maj, min;
|
||||
struct dm_tree_node *node, *child;
|
||||
struct dm_tree_node *node = NULL, *child;
|
||||
void *handle;
|
||||
const char *node_uuid, *mapper_name, *child_uuid, *child_name;
|
||||
|
||||
if (! tree)
|
||||
tree = dm_tree_create ();
|
||||
const char *node_uuid, *mapper_name = NULL, *child_uuid, *child_name;
|
||||
|
||||
tree = dm_tree_create ();
|
||||
if (! tree)
|
||||
{
|
||||
grub_dprintf ("hostdisk", "dm_tree_create failed\n");
|
||||
return NULL;
|
||||
goto devmapper_out;
|
||||
}
|
||||
|
||||
maj = major (st->st_rdev);
|
||||
|
@ -1167,29 +1179,30 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
|
|||
if (! dm_tree_add_dev (tree, maj, min))
|
||||
{
|
||||
grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n");
|
||||
return NULL;
|
||||
goto devmapper_out;
|
||||
}
|
||||
|
||||
node = dm_tree_find_node (tree, maj, min);
|
||||
if (! node)
|
||||
{
|
||||
grub_dprintf ("hostdisk", "dm_tree_find_node failed\n");
|
||||
return NULL;
|
||||
goto devmapper_out;
|
||||
}
|
||||
node_uuid = dm_tree_node_get_uuid (node);
|
||||
if (! node_uuid)
|
||||
{
|
||||
grub_dprintf ("hostdisk", "%s has no DM uuid\n", path);
|
||||
return NULL;
|
||||
node = NULL;
|
||||
goto devmapper_out;
|
||||
}
|
||||
else if (strncmp (node_uuid, "DMRAID-", 7) != 0)
|
||||
{
|
||||
grub_dprintf ("hostdisk", "%s is not DM-RAID\n", path);
|
||||
return NULL;
|
||||
node = NULL;
|
||||
goto devmapper_out;
|
||||
}
|
||||
|
||||
handle = NULL;
|
||||
mapper_name = NULL;
|
||||
/* Counter-intuitively, device-mapper refers to the disk-like
|
||||
device containing a DM-RAID partition device as a "child" of
|
||||
the partition device. */
|
||||
|
@ -1219,17 +1232,20 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st)
|
|||
mapper_name = child_name;
|
||||
|
||||
devmapper_out:
|
||||
if (! mapper_name)
|
||||
if (! mapper_name && node)
|
||||
{
|
||||
/* This is a DM-RAID disk, not a partition. */
|
||||
mapper_name = dm_tree_node_get_name (node);
|
||||
if (! mapper_name)
|
||||
{
|
||||
grub_dprintf ("hostdisk", "%s has no DM name\n", path);
|
||||
return NULL;
|
||||
}
|
||||
grub_dprintf ("hostdisk", "%s has no DM name\n", path);
|
||||
}
|
||||
return xasprintf ("/dev/mapper/%s", mapper_name);
|
||||
if (tree)
|
||||
dm_tree_free (tree);
|
||||
free (path);
|
||||
if (mapper_name)
|
||||
return xasprintf ("/dev/mapper/%s", mapper_name);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
#endif /* HAVE_DEVICE_MAPPER */
|
||||
}
|
||||
|
@ -1334,7 +1350,7 @@ device_is_wholedisk (const char *os_dev)
|
|||
#endif /* defined(__NetBSD__) */
|
||||
|
||||
static int
|
||||
find_system_device (const char *os_dev, struct stat *st)
|
||||
find_system_device (const char *os_dev, struct stat *st, int add)
|
||||
{
|
||||
unsigned int i;
|
||||
char *os_disk;
|
||||
|
@ -1352,6 +1368,9 @@ find_system_device (const char *os_dev, struct stat *st)
|
|||
return i;
|
||||
}
|
||||
|
||||
if (!add)
|
||||
return -1;
|
||||
|
||||
if (i == ARRAY_SIZE (map))
|
||||
grub_util_error (_("device count exceeds limit"));
|
||||
|
||||
|
@ -1361,6 +1380,17 @@ find_system_device (const char *os_dev, struct stat *st)
|
|||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
grub_util_biosdisk_is_present (const char *os_dev)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (stat (os_dev, &st) < 0)
|
||||
return 0;
|
||||
|
||||
return find_system_device (os_dev, &st, 0) != -1;
|
||||
}
|
||||
|
||||
char *
|
||||
grub_util_biosdisk_get_grub_dev (const char *os_dev)
|
||||
{
|
||||
|
@ -1373,7 +1403,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
drive = find_system_device (os_dev, &st);
|
||||
drive = find_system_device (os_dev, &st, 1);
|
||||
if (drive < 0)
|
||||
{
|
||||
grub_error (GRUB_ERR_UNKNOWN_DEVICE,
|
||||
|
@ -1552,3 +1582,29 @@ grub_util_biosdisk_get_osdev (grub_disk_t disk)
|
|||
{
|
||||
return map[disk->id].device;
|
||||
}
|
||||
|
||||
int
|
||||
grub_util_biosdisk_is_floppy (grub_disk_t disk)
|
||||
{
|
||||
struct stat st;
|
||||
int fd;
|
||||
|
||||
fd = open (map[disk->id].device, O_RDONLY);
|
||||
/* Shouldn't happen. */
|
||||
if (fd == -1)
|
||||
return 0;
|
||||
|
||||
/* Shouldn't happen either. */
|
||||
if (fstat (fd, &st) < 0)
|
||||
return 0;
|
||||
|
||||
#if defined(__NetBSD__)
|
||||
if (major(st.st_rdev) == RAW_FLOPPY_MAJOR)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
if (major(st.st_rdev) == FLOPPY_MAJOR)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -38,3 +38,8 @@ grub_emu_init (void)
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
grub_emu_post_init (void)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -190,19 +190,15 @@ main (int argc, char *argv[])
|
|||
grub_emu_init ();
|
||||
grub_console_init ();
|
||||
grub_host_init ();
|
||||
grub_hostfs_init ();
|
||||
|
||||
/* XXX: This is a bit unportable. */
|
||||
grub_util_biosdisk_init (dev_map);
|
||||
|
||||
grub_init_all ();
|
||||
|
||||
grub_lvm_fini ();
|
||||
grub_mdraid_fini ();
|
||||
grub_raid_fini ();
|
||||
grub_raid_init ();
|
||||
grub_mdraid_init ();
|
||||
grub_lvm_init ();
|
||||
grub_hostfs_init ();
|
||||
|
||||
grub_emu_post_init ();
|
||||
|
||||
/* Make sure that there is a root device. */
|
||||
if (! root_dev)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue