merge trunk

This commit is contained in:
BVK Chaitanya 2010-01-18 16:58:03 +05:30
commit d8d4217e3c
133 changed files with 5807 additions and 2525 deletions

549
ChangeLog
View file

@ -1,3 +1,552 @@
2010-01-18 Robert Millan <rmh.grub@aybabtu.com>
* include/grub/i386/linux.h (GRUB_VIDEO_TYPE_TEXT): Rename to ...
(GRUB_VIDEO_LINUX_TYPE_TEXT): ... this. Update all users.
(GRUB_VIDEO_TYPE_VLFB): Rename to ...
(GRUB_VIDEO_LINUX_TYPE_VESA): ... this. Update all users.
(GRUB_VIDEO_TYPE_EFI): Rename to ...
(GRUB_VIDEO_LINUX_TYPE_SIMPLE): ... this. Update all users.
2010-01-17 Robert Millan <rmh.grub@aybabtu.com>
* include/grub/test.h: Add license header.
* tests/example_functional_test.c: Likewise.
* tests/example_unit_test.c: Likewise.
* tests/lib/functional_test.c: Likewise.
* tests/lib/test.c: Likewise.
* tests/lib/unit_test.c: Likewise.
2010-01-17 Vladimir Serbinenko <phcoder@gmail.com>
Use flag-based instead of hook-based video mode selection and "auto"
keyword.
* include/grub/video.h (grub_video_adapter): Changed 'setup' member.
(grub_video_set_mode): Changed prototype. All users updated.
(grub_video_check_mode_flag): New inline function.
* video/video.c (parse_modespec): New function.
(grub_video_set_mode): Parse flags and keywords.
2010-01-17 Carles Pina i Estany <carles@pina.cat>
* util/misc.c (grub_util_info): Fix the order of the parameters in a
fprintf call.
2010-01-16 Grégoire Sutre <gregoire.sutre@gmail.com>
* genmk.rb (class SCRIPT): Replace option -i of sed by a pipe.
2010-01-16 Carles Pina i Estany <carles@pina.cat>
* util/grub-editenv.c (usage): Use `program_name' instead of hardcoded
string.
* util/grub-emu.c (usage): Likewise.
* util/grub-mkpasswd-pbkdf2.c (usage): Likewise.
* util/i386/efi/grub-mkimage.c (usage): Likewise.
* util/i386/pc/grub-mkimage.c (usage): Likewise.
* util/i386/pc/grub-setup.c (usage): Likewise.
2010-01-16 Carles Pina i Estany <carles@pina.cat>
* util/misc.c (grub_util_warn): Gettextizze, print full stop after
the message.
(grub_util_info): Likewise.
(grub_util_error): Likewise.
* util/elf/grub-mkimage.c: Fix capitalisation, quotes, full stops
and/or new lines in `grub_util_warna', `grub_util_info',
`grub_util_error' calls.
* util/getroot.c: Likewise.
* util/grub-editenv.c: Likewise.
* util/grub-emu.c: Likewise.
* util/grub-fstest.c: Likewise.
* util/grub-mkdevicemap.c: Likewise.
* util/grub-mkfont.c: Likewise.
* util/grub-mkpasswd-pbkdf2.c: Likewise.
* util/grub-mkrelpath.c: Likewise.
* util/grub-pe2elf.c: Likewise.
* util/grub-probe.c: Likewise.
* util/hostdisk.c: Likewise.
* util/i386/efi/grub-mkimage.c: Likewise.
* util/i386/pc/grub-mkimage.c: Likewise.
* util/i386/pc/grub-setup.c: Likewise.
* util/ieee1275/ofpath.c: Likewise.
* util/mkisofs/eltorito.c: Likewise.
* util/mkisofs/rock.c: Likewise.
* util/mkisofs/write.c: Likewise.
* util/raid.c: Likewise.
* util/sparc64/ieee1275/grub-mkimage.c: Likewise.
* util/sparc64/ieee1275/grub-setup.c: Likewise.
2010-01-15 Vladimir Serbinenko <phcoder@gmail.com>
Enable multiboot on non-pc.
* conf/i386-coreboot.rmk, conf/i386-pc.rmk (pkglib_MODULES): Move
multiboot.mod and multiboot2.mod to ...
* conf/i386.rmk (pkglib_MODULES): ... here.
* conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_SOURCES):
Moved to ...
* conf/i386.rmk (multiboot_mod_SOURCES): .. here.
* conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_CFLAGS):
Moved to ...
* conf/i386.rmk (multiboot_mod_CFLAGS): .. here.
* conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_ASFLAGS):
Moved to ...
* conf/i386.rmk (multiboot_mod_ASFLAGS): .. here.
* conf/i386-coreboot.rmk, conf/i386-pc.rmk (multiboot_mod_LDFLAGS):
Moved to ...
* conf/i386.rmk (multiboot_mod_LDFLAGS): .. here.
* conf/x86_64-efi.rmk (pkglib_MODULES): Remove ata.mod and
relocator.mod.
(ata_mod_SOURCES): Removed.
(ata_mod_CFLAGS): Likewise.
(ata_mod_LDFLAGS): Likewise.
(relocator_mod_SOURCES): Removed.
(relocator_mod_CFLAGS): Likewise.
(relocator_mod_ASFLAGS): Likewise.
(relocator_mod_LDFLAGS): Likewise.
Include i386.mk.
* include/grub/x86_64/multiboot.h: New file.
* loader/i386/multiboot.c (grub_multiboot_boot) [GRUB_MACHINE_EFI]:
Terminate EFI.
2010-01-15 Vladimir Serbinenko <phcoder@gmail.com>
Video multiboot support.
* include/grub/multiboot.h (grub_multiboot_set_accepts_video):
New prototype.
* include/multiboot.h: Resynced with multiboot specification.
* include/multiboot2.h: Likewise.
* loader/i386/multiboot.c (UNSUPPORTED_FLAGS): Support video flags.
(grub_multiboot): Parse MULTIBOOT_VIDEO_MODE fields.
* loader/i386/multiboot_mbi.c (DEFAULT_VIDEO_MODE): New constant.
(HAS_VGA_TEXT): Likewise.
(accepts_video): New variable.
(grub_multiboot_set_accepts_video): New function.
(grub_multiboot_get_mbi_size): Account for video structures.
(set_video_mode): New function.
(retrieve_video_parameters): Likewise.
(grub_multiboot_make_mbi): Fill video fields.
2010-01-15 Vladimir Serbinenko <phcoder@gmail.com>
Video driver ids.
* include/grub/video.h (grub_video_driver_id): New type.
(grub_video_adapter): New member 'id'. All users updated.
(grub_video_get_driver_id): New proto.
* video/video.c (grub_video_get_driver_id): New function.
2010-01-14 Carles Pina i Estany <carles@pina.cat>
* util/grub.d/30_os-prober.in: Use `set var=val' rather than plain
`var=val'.
2010-01-14 Carles Pina i Estany <carles@pina.cat>
* normal/cmdline.c (print_completion): Gettextizze.
2001-01-14 Carles Pina i Estany <carles@pina.cat>
* loader/i386/pc/chainloader.c: Include `<grub/mm.h>'.
2010-01-14 Carles Pina i Estany <carles@pina.cat>
* gettext/gettext.c (grub_gettext_translate): Push and pop
grub_errno.
(grub_gettext_delete_list): Change comment style.
* kern/err.c (grub_error): Gettextizze.
(grub_fatal): Gettextizze.
2010-01-14 Robert Millan <rmh.grub@aybabtu.com>
* include/grub/i386/loader.h (grub_linux16_boot): Renamed to ...
(grub_linux16_real_boot): ... this.
* kern/i386/loader.S: Likewise.
* loader/i386/pc/linux.c: Include `<grub/video.h>' and `<grub/mm.h>'.
(grub_linux16_boot): New function. Switches to text mode and calls
grub_linux16_real_boot().
* loader/i386/bsd.c: Include `<grub/video.h>'.
(grub_freebsd_boot, grub_openbsd_boot, grub_netbsd_boot): Switch to
text mode before calling grub_unix_real_boot().
* loader/i386/multiboot.c: Include `<grub/video.h>'.
(grub_multiboot_boot): Switch to text mode before calling
grub_relocator32_boot().
* loader/i386/pc/chainloader.c: Include `<grub/video.h>'.
(grub_chainloader_boot): Switch to text mode before calling
grub_chainloader_real_boot().
2010-01-05 Jordan Uggla <jordan.uggla@gmail.com>
2010-01-05 Colin Watson <cjwatson@ubuntu.com>
* util/grub-reboot.in: Make sure prev_saved_entry always gets a
non-empty value.
2010-01-05 Jordan Uggla <jordan.uggla@gmail.com>
2010-01-05 Colin Watson <cjwatson@ubuntu.com>
* util/grub.d/00_header.in: Define a "savedefault" function for use
in menu entries.
* util/grub-mkconfig_lib.in (save_default_entry): Use it.
2010-01-05 Jordan Uggla <jordan.uggla@gmail.com>
2010-01-05 Colin Watson <cjwatson@ubuntu.com>
* util/grub-mkconfig_lib.in (save_default_entry): Only set
saved_entry if boot_once is unset.
* util/grub.d/00_header.in: Set boot_once to "true" if there was a
previous saved entry (i.e. grub-reboot).
2009-12-08 Colin Watson <cjwatson@ubuntu.com>
* util/grub.d/30_os-prober.in: Call save_default_entry for hurd.
2009-12-08 Colin Watson <cjwatson@ubuntu.com>
* util/grub.d/00_header.in: Use `set var=val' rather than plain
`var=val'.
* util/grub-mkconfig_lib.in (save_default_entry): Likewise.
2009-12-08 Colin Watson <cjwatson@ubuntu.com>
* util/grub-reboot.in: Fix --version output.
* util/grub-set-default.in: Likewise.
2009-12-08 Colin Watson <cjwatson@ubuntu.com>
* util/grub.d/00_header.in: Silently ignore zero-sized environment
blocks.
2009-12-08 Colin Watson <cjwatson@ubuntu.com>
* util/grub.d/00_header.in: Quote the value assigned to `default',
in case it contains spaces.
2009-12-08 Colin Watson <cjwatson@ubuntu.com>
* util/grub.d/30_os-prober.in: Fix merge error that moved a
`save_default_entry' call from the macosx case to the linux case.
2009-10-25 Vladimir Serbinenko <phcoder@gmail.com>
2009-10-25 Colin Watson <cjwatson@ubuntu.com>
* normal/menu.c (grub_menu_execute_entry): Save selected entry title
in `chosen' environment variable.
* normal/menu_text.c (get_entry_number): Check if the variable
matches the title of a menu entry.
(run_menu): Pass menu to get_entry_number.
* util/grub-reboot.in: New file.
* util/grub-set-default.in: New file.
* conf/common.rmk (grub-reboot): New utility.
(grub-set-default): New utility.
* util/grub-mkconfig_lib.in (save_default_entry): New function.
* util/grub.d/00_header.in: If GRUB_DEFAULT is `saved', set
default to `${saved_entry}'. If `${prev_saved_entry}' is non-empty,
move it to `saved_entry' for the next boot. Load environment on
initialisation.
* util/grub.d/10_kfreebsd.in: Call save_default_entry.
* util/grub.d/10_hurd.in: Likewise.
* util/grub.d/10_linux.in (linux_entry): Likewise.
* util/grub.d/10_windows.in: Likewise.
* util/grub.d/30_os-prober.in: Likewise.
* util/grub-install.in: Create environment block.
* util/i386/efi/grub-install.in: Likewise.
* util/ieee1275/grub-install.in: Likewise.
* util/sparc64/ieee1275/grub-install.in: Likewise.
2010-01-14 BVK Chaitanya <bvk.groups@gmail.com>
Unit testing framework for GRUB.
* Makefile.in: Test framework build rules for 'make check'.
* conf/tests.rmk: Build rules for individual tests and framework.
* include/grub/test.h: Header file for whitebox tests.
* tests/lib/functional_test.c: Framework support for whitebox
functional tests.
* tests/lib/test.c: Common whitebox testing code for unit and
functional tests.
* tests/lib/unit_test.c: Framework support for whitebox unit
tests.
* tests/util/grub-shell-tester.in: Support utility for grub-script
tests.
* tests/util/grub-shell.in: Utility to execute grub-script
commands in a Qemu instance.
* tests/example_functional_test.c: Example whitebox functional
test.
* tests/example_grub_script_test.in: Example grub-script test.
* tests/example_scripted_test.in: Example scripted test.
* tests/example_unit_test.c: Example whitebox unit test.
2010-01-14 Vladimir Serbinenko <phcoder@gmail.com>
* conf/i386-coreboot.rmk (multiboot_mod_SOURCES):
Add loader/i386/multiboot_mbi.c.
(multiboot2_mod_SOURCES): Likewise.
* conf/i386-pc.rmk (multiboot_mod_SOURCES): Likewise.
(multiboot2_mod_SOURCES): Likewise.
* include/grub/multiboot.h (grub_multiboot_get_mbi_size): New proto.
(grub_multiboot_make_mbi): Likewise.
(grub_multiboot_free_mbi): Likewise.
(grub_multiboot_init_mbi): Likewise.
(grub_multiboot_add_module): Likewise.
(grub_multiboot_set_bootdev): Likewise.
* loader/i386/multiboot.c (mbi): Removed.
(mbi_dest): Likewise.
(alloc_mbi): New variable.
(grub_multiboot_payload_size): Removed. All users updated.
(grub_multiboot_pure_size): New variable.
(grub_multiboot_boot): Use grub_multiboot_make_mbi.
(grub_multiboot_unload): Use grub_multiboot_free_mbi.
(grub_get_multiboot_mmap_len): Moved to loader/i386/multiboot_mbi.c.
(grub_fill_multiboot_mmap): Likewise.
(grub_multiboot_get_bootdev): Likewise.
(grub_multiboot): Use multiboot_mbi functions.
* loader/i386/multiboot_mbi.c: New file.
2010-01-13 Vladimir Serbinenko <phcoder@gmail.com>
* kern/efi/init.c (grub_efi_fini): Don't call grub_efi_mm_fini as
it would result in module crash.
2010-01-13 Vladimir Serbinenko <phcoder@gmail.com>
* term/ieee1275/ofconsole.c (grub_ofconsole_putchar): Handle '\r'.
(grub_ofconsole_getwh): Split to ...
(grub_ofconsole_getwh): ... this.
(grub_ofconsole_dimensions): ...and this.
(grub_ofconsole_init_output): Call grub_ofconsole_dimensions.
2010-01-13 Robert Millan <rmh.grub@aybabtu.com>
* util/mkisofs/rock.c (generate_rock_ridge_attributes): Fix a typo.
2010-01-12 Vladimir Serbinenko <phcoder@gmail.com>
* loader/i386/pc/multiboot2.c: Removed stalled file.
2010-01-12 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub-mkpasswd-pbkdf2.c (main): Use grub_util_init_nls.
Reported by: Grégoire Sutre
2010-01-11 Robert Millan <rmh.grub@aybabtu.com>
* util/misc.c (canonicalize_file_name): New function.
(make_system_path_relative_to_its_root): Use canonicalize_file_name()
instead of realpath().
2010-01-11 Colin Watson <cjwatson@ubuntu.com>
* util/grub-install.in (usage): Clarify meaning of --root-directory,
and make it clearer that it's optional. Based on confusion
witnessed on IRC.
2010-01-10 Vladimir Serbinenko <phcoder@gmail.com>
* term/i386/pc/vga_text.c (inc_y): Fix off-by-one error which resulted
in premature implicit newline.
2010-01-10 Vladimir Serbinenko <phcoder@gmail.com>
* normal/cmdline.c (grub_cmdline_get): Fix off-by-one error
which resulted in garbled command line at the end of screen.
2010-01-10 Robert Millan <rmh.grub@aybabtu.com>
* loader/i386/ieee1275/linux.c (grub_linux_boot): Rework video position
initialization with similar approach as with other Linux loaders.
2010-01-10 Robert Millan <rmh.grub@aybabtu.com>
Fix i386-ieee1275 build.
* loader/i386/ieee1275/linux.c (grub_linux_boot): Use grub_term_width()
and grub_term_height() for video_{width,height} initialization.
2010-01-10 Robert Millan <rmh.grub@aybabtu.com>
Fix grub-emu build.
* conf/any-emu.rmk (grub_emu_SOURCES): Remove `kern/reader.c'.
2010-01-07 Vladimir Serbinenko <phcoder@gmail.com>
2010-01-09 Robert Millan <rmh.grub@aybabtu.com>
Support for multiple terminals.
* Makefile.in (pkglib_DATA): terminal.lst.
(terminal.lst): New target.
* commands/handler.c (grub_cmd_handler): Don't handle terminals.
(GRUB_MOD_INIT(handler)): Likewise.
(GRUB_MOD_FINI(handler)): Likewise.
* commands/help.c (grub_cmd_help): Handle multiple terminals.
* commands/keystatus.c (grub_cmd_keystatus): Likewise.
* commands/sleep.c (do_print): Use grub_term_restore_pos.
(grub_cmd_sleep): Use grub_term_save_pos.
* commands/terminal.c: New file.
* conf/any-emu.rmk (grub_emu_SOURCES): Add normal/term.c
commands/terminal.c and lib/charset.c.
* conf/common.rmk (normal_mod_SOURCES): Add normal/term.c.
(pkglib_MODULES): Add terminal.mod.
(terminal_mod_SOURCES): New variable.
(terminal_mod_CFLAGS): Likewise.
(terminal_mod_LDFLAGS): Likewise.
* genhandlerlist.sh: Don't handle terminals.
* genmk.rb: Generate terminal-*.lst.
* genterminallist.sh: New file.
* include/grub/charset.h (grub_ucs4_to_utf8_alloc): New proto.
(grub_is_valid_utf8): Likewise.
(grub_utf8_to_ucs4_alloc): Likewise.
* include/grub/menu_viewer.h (grub_menu_viewer): Rewritten.
(grub_menu_register_viewer): Changed argument.
(grub_menu_try_text): New proto.
(grub_gfxmenu_try_hook): New declaration.
* include/grub/normal.h (grub_normal_exit_level): New declaration.
(grub_menu_init_page): Additional argument term.
(grub_normal_init_page): Likewise.
(grub_cmdline_get): Arguments simplified.
(grub_utf8_to_ucs4_alloc): Removed.
(grub_print_ucs4): Additional argument term.
(grub_getstringwidth): Likewise.
(grub_print_message_indented): Likewise.
(grub_menu_text_register_instances): New proto.
(grub_show_menu): Likewise.
(read_terminal_list): Likewise.
(grub_set_more): Likewise.
* include/grub/parser.h: Include handler.h.
* include/grub/reader.h: Rewritten.
* include/grub/term.h (GRUB_TERM_NEED_INIT): Removed.
(GRUB_TERM_WIDTH): Changed to function.
(GRUB_TERM_HEIGHT): Likewise.
(GRUB_TERM_BORDER_WIDTH): Likewise.
(GRUB_TERM_BORDER_HEIGHT): Likewise.
(GRUB_TERM_NUM_ENTRIES): Likewise.
(GRUB_TERM_ENTRY_WIDTH): Likewise.
(GRUB_TERM_CURSOR_X): Likewise.
(grub_term_input_class): Likewise.
(grub_term_output_class): Likewise.
(grub_term_outputs_disabled): New declaration.
(grub_term_inputs_disabled): Likewise.
(grub_term_outputs): Likewise.
(grub_term_inputs): Likewise.
(grub_term_register_input): Rewritten.
(grub_term_register_output): Likewise.
(grub_term_unregister_input): Likewise.
(grub_term_unregister_output): Likewise.
(FOR_ACTIVE_TERM_INPUTS): New macro.
(FOR_DISABLED_TERM_INPUTS): Likewise.
(FOR_ACTIVE_TERM_OUTPUTS): Likewise.
(FOR_DISABLED_TERM_OUTPUTS): Likewise.
* include/grub/terminfo.h: Add oterm argument to all protypes.
* kern/main.c (grub_main): Don't call grub_register_rescue_reader.
Use grub_rescue_run.
* kern/misc.c (grub_utf8_to_ucs4): Put '?' for invalid characters.
All users updated.
* kern/reader.c: Removed. All users updated.
* kern/rescue_reader.c (grub_rescue_init): Removed.
(grub_rescue_reader): Likewise.
(grub_register_rescue_reader): Likewise.
(grub_rescue_run): New function based on kern/reader.c.
* kern/term.c: Adapted for multiterm.
* lib/charset.c (grub_ucs4_to_utf8_alloc): New function.
(grub_is_valid_utf8): Likewise.
(grub_utf8_to_ucs4_alloc): Moved from normal/menu_text.c.
* loader/i386/efi/linux.c (grub_cmd_linux): Retrieve parameters of
right terminal.
* loader/i386/linux.c (grub_linux_boot): Likewise.
* normal/auth.c (grub_username_get): New function.
(grub_auth_check_authentication): Use grub_username_get.
* normal/cmdline.c: Changed to UCS4. Adapted for multiterm.
* normal/color.c: Adapt for multiterm.
* normal/main.c (read_config_file): Don't use grub_reader_loop.
(grub_normal_init_page): Additional argument term.
(read_lists): Call read_terminal_lists.
(grub_enter_normal_mode): Call grub_cmdline_run.
Handle grub_normal_exit_level.
(grub_cmd_normal): Make reentrant.
(grub_cmd_normal_exit): New function.
(grub_normal_reader_init): Additional argument nested. Handle multiterm.
* normal/menu.c: Adapt for multiterm.
* normal/menu_entry.c: Likewise.
* normal/menu_text.c: Likewise.
* normal/menu_viewer.c: Removed. All users updated.
* normal/term.c: New file.
* util/console.c: Change order of includes to workaround a bug in
ncurses headers.
* term/terminfo.c: New argument oterm on all exported functions.
All users updated.
* util/grub-editenv.c (grub_term_input_class): Removed.
(grub_term_output_class): Likewise.
2010-01-09 Robert Millan <rmh.grub@aybabtu.com>
Make loader output a bit more user-friendly.
* util/grub.d/10_hurd.in: Print message indicating that GNU Mach
is being loaded. Likewise for the Hurd.
* util/grub.d/10_kfreebsd.in (kfreebsd_entry): Print message indicating
that kernel of FreeBSD ${version} is being loaded.
* loader/i386/linux.c (grub_cmd_linux): Move debug info to
grub_dprintf().
(grub_cmd_initrd): Likewise.
* util/grub.d/10_linux.in (linux_entry): Print message indicating
that Linux ${version} is being loaded. Likewise for initrd.
2010-01-09 Carles Pina i Estany <carles@pina.cat>
* gettext/gettext.c (GRUB_MOD_INIT): Gettextizze.
2010-01-08 Carles Pina i Estany <carles@pina.cat>
* loader/efi/appleloader.c: Include `<grub/i18n.h>'.
(GRUB_MOD_INIT): Gettextizze.
* loader/efi/chainloader.c: Include `<grub/i18n.h>'.
(GRUB_MOD_INIT): Gettextizze.
* loader/i386/efi/linux.c: Include `<grub/i18n.h>'.
(grub_cmd_linux): Capitalise Linux.
(GRUB_MOD_INIT): Gettextizze.
* loader/i386/ieee1275/linux.c: Include `<grub/i18n.h>'.
(grub_cmd_linux): Capitalise Linux.
(GRUB_MOD_INIT): Gettextizze.
* loader/i386/linux.c: Include `<grub/i18n.h>'.
(grub_cmd_linux): Capitalise Linux.
(GRUB_MOD_INIT): Gettextizze.
* loader/i386/pc/chainloader.c: Include `<grub/i18n.h>'.
(GRUB_MOD_INIT): Gettextizze.
* loader/i386/pc/linux.c: Include `<grub/i18n.h>'.
(grub_cmd_linux): Capitalise Linux.
(GRUB_MOD_INIT): Gettextizze.
* loader/i386/xnu.c: Include `<grub/i18n.h>'.
(grub_cpu_xnu_init): Gettextizze.
* loader/multiboot_loader.c: Include `<grub/i18n.h>'.
(GRUB_MOD_INIT): Gettextizze.
* loader/powerpc/ieee1275/linux.c: Include `<grub/i18n.h>'.
(GRUB_MOD_INIT): Gettextizze.
* loader/sparc64/ieee1275/linux.c: Include `<grub/i18n.h>'.
(grub_linux_load64): Capitalise Linux.
(GRUB_MOD_INIT): Gettextizze.
* loader/xnu.c: Include `<grub/i18n.h>'.
(GRUB_MOD_INIT): Gettextizze.
* po/POTFILES: Add `loader/efi/appleloader.c',
`loader/efi/chainloader.c', `loader/i386/efi/linux.c',
`loader/i386/ieee1275/linux.c', `loader/i386/linux.c',
`loader/i386/pc/chainloader.c', `loader/i386/pc/linux.c',
`loader/i386/xnu.c', `loader/multiboot_loader.c',
`loader/powerpc/ieee1275/linux.c', `loader/sparc64/ieee1275/linux.c'
and `loader/xnu.c'.
2010-01-08 Robert Millan <rmh.grub@aybabtu.com>
* src/mkisofs.c: Remove `ifdef linux' portability kludge.

View file

@ -167,6 +167,8 @@ ifeq ($(platform), emu)
include $(srcdir)/conf/any-emu.mk
else
include $(srcdir)/conf/$(target_cpu)-$(platform).mk
# For tests.
include $(srcdir)/conf/tests.mk
# For external modules.
-include $(wildcard $(GRUB_CONTRIB)/*/conf/common.mk)
endif
@ -174,7 +176,7 @@ endif
### General targets.
CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA) po/*.mo
pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst
pkglib_DATA += moddep.lst command.lst fs.lst partmap.lst parttool.lst handler.lst video.lst crypto.lst terminal.lst
moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep.awk
cat $(DEFSYMFILES) /dev/null \
| $(AWK) -f $(srcdir)/genmoddep.awk $(UNDSYMFILES) > $@ \
@ -192,6 +194,9 @@ partmap.lst: $(PARTMAPFILES)
handler.lst: $(HANDLERFILES)
cat $^ /dev/null | sort > $@
terminal.lst: $(TERMINALFILES)
cat $^ /dev/null | sort > $@
parttool.lst: $(PARTTOOLFILES)
cat $^ /dev/null | sort | uniq > $@
@ -458,7 +463,26 @@ distcheck: dist
@echo "$(distdir).tar.gz is ready for distribution" | \
sed 'h;s/./=/g;p;x;p;x'
check:
check: all $(UNIT_TESTS) $(FUNCTIONAL_TESTS) $(SCRIPTED_TESTS)
@list="$(UNIT_TESTS)"; \
for file in $$list; do \
$(builddir)/$$file; \
done
@list="$(FUNCTIONAL_TESTS)"; \
for file in $$list; do \
mod=`basename $$file .mod`; \
echo "insmod functional_test; insmod $$mod; functional_test" \
| $(builddir)/grub-shell; \
done
@list="$(SCRIPTED_TESTS)"; \
for file in $$list; do \
echo "$$file:"; \
if $(builddir)/$$file; then \
echo "$$file: PASS"; \
else \
echo "$$file: FAIL"; \
fi; \
done
.SUFFIX:
.SUFFIX: .c .o .S .d

View file

@ -26,10 +26,9 @@
#include <grub/i18n.h>
static grub_err_t
grub_cmd_handler (struct grub_command *cmd,
grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)),
int argc, char **args)
{
char *class_name;
void *curr_item = 0;
grub_handler_class_t head;
@ -44,23 +43,19 @@ grub_cmd_handler (struct grub_command *cmd,
return 0;
}
class_name = (grub_strcmp (cmd->name, "handler")) ? (char *) cmd->name : 0;
head = grub_handler_class_list;
if ((argc == 0) && (class_name == 0))
if (argc == 0)
{
grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_item);
}
else
{
char *class_name;
grub_handler_class_t class;
if (class_name == 0)
{
class_name = args[0];
argc--;
args++;
}
class = grub_named_list_find (GRUB_AS_NAMED_LIST (head), class_name);
if (! class)
@ -90,7 +85,7 @@ grub_cmd_handler (struct grub_command *cmd,
return 0;
}
static grub_command_t cmd_handler, cmd_terminal_input, cmd_terminal_output;
static grub_command_t cmd_handler;
GRUB_MOD_INIT(handler)
{
@ -98,19 +93,9 @@ GRUB_MOD_INIT(handler)
grub_register_command ("handler", grub_cmd_handler,
N_("[class [handler]]"),
N_("List or select a handler."));
cmd_terminal_input =
grub_register_command ("terminal_input", grub_cmd_handler,
N_("[handler]"),
N_("List or select an input terminal."));
cmd_terminal_output =
grub_register_command ("terminal_output", grub_cmd_handler,
N_("[handler]"),
N_("List or select an output terminal."));
}
GRUB_MOD_FINI(handler)
{
grub_unregister_command (cmd_handler);
grub_unregister_command (cmd_terminal_input);
grub_unregister_command (cmd_terminal_output);
}

View file

@ -24,6 +24,7 @@
#include <grub/i18n.h>
#include <grub/mm.h>
#include <grub/normal.h>
#include <grub/charset.h>
static grub_err_t
grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
@ -40,12 +41,11 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) &&
(cmd->flags & GRUB_COMMAND_FLAG_CMDLINE))
{
struct grub_term_output *term;
const char *summary_translated = _(cmd->summary);
char *command_help;
int stringwidth;
grub_uint32_t *unicode_command_help;
grub_uint32_t *unicode_last_position;
grub_uint32_t *unicode_last_screen_position;
const char *summary_translated = _(cmd->summary);
command_help = grub_malloc (grub_strlen (cmd->name) +
sizeof (" ") - 1 +
@ -56,27 +56,33 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help,
&unicode_last_position);
FOR_ACTIVE_TERM_OUTPUTS(term)
{
unsigned stringwidth;
grub_uint32_t *unicode_last_screen_position;
unicode_last_screen_position = unicode_command_help;
stringwidth = 0;
while (unicode_last_screen_position < unicode_last_position &&
stringwidth < ((GRUB_TERM_WIDTH / 2) - 2))
stringwidth < ((grub_term_width (term) / 2) - 2))
{
stringwidth += grub_getcharwidth (*unicode_last_screen_position);
stringwidth
+= grub_term_getcharwidth (term,
*unicode_last_screen_position);
unicode_last_screen_position++;
}
grub_print_ucs4 (unicode_command_help, unicode_last_screen_position);
if ((cnt++) % 2)
{
grub_putchar ('\n');
}
else
{
grub_print_spaces (GRUB_TERM_WIDTH / 2 - stringwidth);
grub_print_ucs4 (unicode_command_help,
unicode_last_screen_position, term);
if (!(cnt % 2))
grub_print_spaces (term, grub_term_width (term) / 2
- stringwidth);
}
if (cnt % 2)
grub_printf ("\n");
cnt++;
grub_free (command_help);
grub_free (unicode_command_help);
@ -104,7 +110,11 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
}
if (argc == 0)
{
grub_command_iterate (print_command_info);
if (!(cnt % 2))
grub_printf ("\n");
}
else
{
int i;

View file

@ -49,13 +49,24 @@ grub_cmd_keystatus (grub_extcmd_t cmd,
if (state[2].set)
expect_mods |= GRUB_TERM_STATUS_ALT;
grub_dprintf ("keystatus", "expect_mods: %d\n", expect_mods);
/* Without arguments, just check whether getkeystatus is supported at
all. */
if (!grub_cur_term_input->getkeystatus)
if (expect_mods == 0)
{
grub_term_input_t term;
int nterms = 0;
FOR_ACTIVE_TERM_INPUTS (term)
if (!term->getkeystatus)
return grub_error (GRUB_ERR_TEST_FAILURE, "false");
else
nterms++;
if (!nterms)
return grub_error (GRUB_ERR_TEST_FAILURE, "false");
grub_dprintf ("keystatus", "expect_mods: %d\n", expect_mods);
if (!expect_mods)
return 0;
}
mods = grub_getkeystatus ();
grub_dprintf ("keystatus", "mods: %d\n", mods);

View file

@ -33,12 +33,12 @@ static const struct grub_arg_option options[] =
{0, 0, 0, 0, 0, 0}
};
static grub_uint8_t x, y;
static grub_uint16_t *pos;
static void
do_print (int n)
{
grub_gotoxy (x, y);
grub_term_restore_pos (pos);
/* NOTE: Do not remove the trailing space characters.
They are required to clear the line. */
grub_printf ("%d ", n);
@ -64,7 +64,6 @@ static grub_err_t
grub_cmd_sleep (grub_extcmd_t cmd, int argc, char **args)
{
struct grub_arg_list *state = cmd->state;
grub_uint16_t xy;
int n;
if (argc != 1)
@ -78,9 +77,7 @@ grub_cmd_sleep (grub_extcmd_t cmd, int argc, char **args)
return 0;
}
xy = grub_getxy ();
x = xy >> 8;
y = xy & 0xff;
pos = grub_term_save_pos ();
for (; n; n--)
{

364
commands/terminal.c Normal file
View file

@ -0,0 +1,364 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/mm.h>
#include <grub/dl.h>
#include <grub/command.h>
#include <grub/term.h>
#include <grub/i18n.h>
#include <grub/misc.h>
struct grub_term_autoload *grub_term_input_autoload = NULL;
struct grub_term_autoload *grub_term_output_autoload = NULL;
static grub_err_t
grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
int i;
grub_term_input_t term;
struct grub_term_autoload *aut;
if (argc == 0)
{
grub_puts_ (N_ ("Active input terminals:"));
FOR_ACTIVE_TERM_INPUTS(term)
grub_printf ("%s ", term->name);
grub_printf ("\n");
grub_puts_ (N_ ("Available input terminals:"));
FOR_DISABLED_TERM_INPUTS(term)
grub_printf ("%s ", term->name);
/* This is quadratic but we don't expect mode than 30 terminal
modules ever. */
for (aut = grub_term_input_autoload; aut; aut = aut->next)
{
FOR_DISABLED_TERM_INPUTS(term)
if (grub_strcmp (term->name, aut->name) == 0)
break;
if (!term)
FOR_ACTIVE_TERM_INPUTS(term)
if (grub_strcmp (term->name, aut->name) == 0)
break;
if (!term)
grub_printf ("%s ", aut->name);
}
grub_printf ("\n");
return GRUB_ERR_NONE;
}
i = 0;
if (grub_strcmp (args[0], "--append") == 0
|| grub_strcmp (args[0], "--remove") == 0)
i++;
if (i == argc)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
for (; i < argc; i++)
{
int again = 0;
while (1)
{
FOR_DISABLED_TERM_INPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term == 0)
FOR_ACTIVE_TERM_INPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
break;
if (again)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
args[i]);
for (aut = grub_term_input_autoload; aut; aut = aut->next)
if (grub_strcmp (args[i], aut->name) == 0)
{
grub_dl_t mod;
mod = grub_dl_load (aut->modname);
if (mod)
grub_dl_ref (mod);
grub_errno = GRUB_ERR_NONE;
break;
}
if (!aut)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
args[i]);
again = 1;
}
}
if (grub_strcmp (args[0], "--append") == 0)
{
for (i = 1; i < argc; i++)
{
FOR_DISABLED_TERM_INPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
{
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)),
GRUB_AS_LIST (term));
if (term->init)
term->init ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs),
GRUB_AS_LIST (term));
}
}
return GRUB_ERR_NONE;
}
if (grub_strcmp (args[0], "--remove") == 0)
{
for (i = 1; i < argc; i++)
{
FOR_ACTIVE_TERM_INPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
{
if (!term->next && term == grub_term_inputs)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)),
GRUB_AS_LIST (term));
if (term->fini)
term->fini ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
GRUB_AS_LIST (term));
}
}
return GRUB_ERR_NONE;
}
for (i = 0; i < argc; i++)
{
FOR_DISABLED_TERM_INPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
{
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)),
GRUB_AS_LIST (term));
if (term->init)
term->init ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs),
GRUB_AS_LIST (term));
}
}
FOR_ACTIVE_TERM_INPUTS(term)
{
for (i = 0; i < argc; i++)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (i == argc)
{
if (!term->next && term == grub_term_inputs)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)),
GRUB_AS_LIST (term));
if (term->fini)
term->fini ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
GRUB_AS_LIST (term));
}
}
return GRUB_ERR_NONE;
}
static grub_err_t
grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
int i;
grub_term_output_t term;
struct grub_term_autoload *aut;
if (argc == 0)
{
grub_puts_ (N_ ("Active output terminals:"));
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_printf ("%s ", term->name);
grub_printf ("\n");
grub_puts_ (N_ ("Available output terminals:"));
FOR_DISABLED_TERM_OUTPUTS(term)
grub_printf ("%s ", term->name);
/* This is quadratic but we don't expect mode than 30 terminal
modules ever. */
for (aut = grub_term_output_autoload; aut; aut = aut->next)
{
FOR_DISABLED_TERM_OUTPUTS(term)
if (grub_strcmp (term->name, aut->name) == 0)
break;
if (!term)
FOR_ACTIVE_TERM_OUTPUTS(term)
if (grub_strcmp (term->name, aut->name) == 0)
break;
if (!term)
grub_printf ("%s ", aut->name);
}
grub_printf ("\n");
return GRUB_ERR_NONE;
}
i = 0;
if (grub_strcmp (args[0], "--append") == 0
|| grub_strcmp (args[0], "--remove") == 0)
i++;
if (i == argc)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
for (; i < argc; i++)
{
int again = 0;
while (1)
{
FOR_DISABLED_TERM_OUTPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term == 0)
FOR_ACTIVE_TERM_OUTPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
break;
if (again)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
args[i]);
for (aut = grub_term_output_autoload; aut; aut = aut->next)
if (grub_strcmp (args[i], aut->name) == 0)
{
grub_dl_t mod;
mod = grub_dl_load (aut->modname);
if (mod)
grub_dl_ref (mod);
grub_errno = GRUB_ERR_NONE;
break;
}
if (!aut)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
args[i]);
again = 1;
}
}
if (grub_strcmp (args[0], "--append") == 0)
{
for (i = 1; i < argc; i++)
{
FOR_DISABLED_TERM_OUTPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
{
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
GRUB_AS_LIST (term));
if (term->init)
term->init ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
GRUB_AS_LIST (term));
}
}
return GRUB_ERR_NONE;
}
if (grub_strcmp (args[0], "--remove") == 0)
{
for (i = 1; i < argc; i++)
{
FOR_ACTIVE_TERM_OUTPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
{
if (!term->next && term == grub_term_outputs)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)),
GRUB_AS_LIST (term));
if (term->fini)
term->fini ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
GRUB_AS_LIST (term));
}
}
return GRUB_ERR_NONE;
}
for (i = 0; i < argc; i++)
{
FOR_DISABLED_TERM_OUTPUTS(term)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (term)
{
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
GRUB_AS_LIST (term));
if (term->init)
term->init ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
GRUB_AS_LIST (term));
}
}
FOR_ACTIVE_TERM_OUTPUTS(term)
{
for (i = 0; i < argc; i++)
if (grub_strcmp (args[i], term->name) == 0)
break;
if (i == argc)
{
if (!term->next && term == grub_term_outputs)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"can't remove the last terminal");
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)),
GRUB_AS_LIST (term));
if (term->fini)
term->fini ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
GRUB_AS_LIST (term));
}
}
return GRUB_ERR_NONE;
}
static grub_command_t cmd_terminal_input, cmd_terminal_output;
GRUB_MOD_INIT(terminal)
{
cmd_terminal_input =
grub_register_command ("terminal_input", grub_cmd_terminal_input,
"[--append|--remove] "
"[TERMINAL1] [TERMINAL2] ...",
"List or select an input terminal.");
cmd_terminal_output =
grub_register_command ("terminal_output", grub_cmd_terminal_output,
"[--append|--remove] "
"[TERMINAL1] [TERMINAL2] ...",
"List or select an output terminal.");
}
GRUB_MOD_FINI(terminal)
{
grub_unregister_command (cmd_terminal_input);
grub_unregister_command (cmd_terminal_output);
}

View file

@ -31,9 +31,7 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
if (grub_video_set_mode ("1024x768;800x600;640x480", 0) != GRUB_ERR_NONE)
return grub_errno;
grub_err_t err;
grub_video_color_t color;
unsigned int x;
unsigned int y;
@ -50,6 +48,10 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
const char *str;
int texty;
err = grub_video_set_mode ("auto", GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
if (err)
return err;
grub_video_get_viewport (&x, &y, &width, &height);
grub_video_create_render_target (&text_layer, width, height,
@ -153,12 +155,13 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
for (i = 0; i < 255; i++)
for (i = 0; i < 5; i++)
{
color = grub_video_map_rgb (i, 33, 77);
grub_video_fill_rect (color, 0, 0, width, height);
grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, 0, 0,
0, 0, width, height);
grub_video_swap_buffers ();
}
grub_getkey ();

View file

@ -23,13 +23,14 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.c \
kern/err.c kern/list.c kern/handler.c \
kern/command.c kern/corecmd.c commands/extcmd.c kern/file.c \
kern/fs.c commands/boot.c kern/main.c kern/misc.c kern/parser.c \
kern/partition.c kern/reader.c kern/term.c \
kern/partition.c kern/term.c \
kern/rescue_reader.c kern/rescue_parser.c \
lib/arg.c normal/cmdline.c normal/datetime.c normal/misc.c \
normal/handler.c normal/auth.c lib/crypto.c normal/autofs.c \
normal/completion.c normal/main.c normal/color.c \
normal/menu.c normal/menu_entry.c normal/menu_viewer.c \
normal/menu_text.c normal/crypto.c \
normal/menu.c normal/menu_entry.c \
normal/menu_text.c normal/crypto.c normal/term.c \
commands/terminal.c lib/charset.c \
script/main.c script/execute.c script/function.c \
script/lexer.c script/script.c grub_script.tab.c \
partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.c \

View file

@ -206,6 +206,20 @@ CLEANFILES += $(grub-mkconfig_SCRIPTS)
grub-mkconfig_DATA += util/grub.d/README
# For grub-set-default.
grub-set-default: util/grub-set-default.in config.status
./config.status --file=$@:$<
chmod +x $@
sbin_SCRIPTS += grub-set-default
CLEANFILES += grub-set-default
# For grub-reboot.
grub-reboot: util/grub-reboot.in config.status
./config.status --file=$@:$<
chmod +x $@
sbin_SCRIPTS += grub-reboot
CLEANFILES += grub-reboot
# Filing systems.
pkglib_MODULES += fshelp.mod fat.mod ufs1.mod ufs2.mod ext2.mod ntfs.mod \
ntfscomp.mod minix.mod hfs.mod jfs.mod iso9660.mod xfs.mod \
@ -570,8 +584,8 @@ keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS)
normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
normal/auth.c normal/autofs.c normal/handler.c \
normal/color.c normal/completion.c normal/datetime.c normal/menu.c \
normal/menu_entry.c normal/menu_text.c normal/menu_viewer.c \
normal/misc.c normal/crypto.c
normal/menu_entry.c normal/menu_text.c \
normal/misc.c normal/crypto.c normal/term.c
normal_mod_CFLAGS = $(COMMON_CFLAGS)
normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
@ -672,6 +686,11 @@ charset_mod_SOURCES = lib/charset.c
charset_mod_CFLAGS = $(COMMON_CFLAGS)
charset_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += terminal.mod
terminal_mod_SOURCES = commands/terminal.c
terminal_mod_CFLAGS = $(COMMON_CFLAGS)
terminal_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += crypto.mod
crypto_mod_SOURCES = lib/crypto.c
crypto_mod_CFLAGS = $(COMMON_CFLAGS)

View file

@ -21,7 +21,7 @@ kernel_img_SOURCES = kern/i386/coreboot/startup.S \
kern/i386/halt.c \
kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/reader.c kern/term.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
@ -65,7 +65,7 @@ kernel_img_SOURCES = kern/i386/qemu/startup.S \
kern/i386/halt.c \
kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/reader.c kern/term.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
@ -140,20 +140,6 @@ serial_mod_SOURCES = term/i386/pc/serial.c
serial_mod_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += multiboot.mod
multiboot_mod_SOURCES = loader/i386/multiboot.c \
loader/multiboot_loader.c
multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
pkglib_MODULES += multiboot2.mod
multiboot2_mod_SOURCES = loader/i386/multiboot.c \
loader/multiboot_loader.c
multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2
multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS)
multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS)
# For aout.mod.
aout_mod_SOURCES = loader/aout.c
aout_mod_CFLAGS = $(COMMON_CFLAGS)

View file

@ -39,7 +39,7 @@ pkglib_MODULES = kernel.img chain.mod appleldr.mod \
kernel_img_EXPORTS = no
kernel_img_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/reader.c kern/term.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/$(target_cpu)/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \

View file

@ -19,7 +19,7 @@ kernel_img_SOURCES = kern/i386/ieee1275/startup.S \
kern/ieee1275/cmain.c kern/ieee1275/openfw.c \
kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/reader.c kern/term.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
kern/env.c \

View file

@ -48,7 +48,7 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \
kern/i386/misc.S \
kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/reader.c kern/term.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/$(target_cpu)/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \
@ -201,20 +201,6 @@ serial_mod_SOURCES = term/i386/pc/serial.c
serial_mod_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += multiboot.mod
multiboot_mod_SOURCES = loader/i386/multiboot.c \
loader/multiboot_loader.c
multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
pkglib_MODULES += multiboot2.mod
multiboot2_mod_SOURCES = loader/i386/multiboot.c \
loader/multiboot_loader.c
multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2
multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS)
multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS)
# For vbe.mod.
vbe_mod_SOURCES = video/i386/pc/vbe.c
vbe_mod_CFLAGS = $(COMMON_CFLAGS)

View file

@ -25,3 +25,19 @@ pkglib_MODULES += ata.mod
ata_mod_SOURCES = disk/ata.c
ata_mod_CFLAGS = $(COMMON_CFLAGS)
ata_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += multiboot.mod
multiboot_mod_SOURCES = loader/i386/multiboot.c \
loader/i386/multiboot_mbi.c \
loader/multiboot_loader.c
multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
pkglib_MODULES += multiboot2.mod
multiboot2_mod_SOURCES = loader/i386/multiboot.c \
loader/i386/multiboot_mbi.c \
loader/multiboot_loader.c
multiboot2_mod_CFLAGS = $(COMMON_CFLAGS) -DGRUB_USE_MULTIBOOT2
multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS)
multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS)

View file

@ -31,7 +31,7 @@ pkglib_PROGRAMS = kernel.img
kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \
kern/ieee1275/ieee1275.c kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \
kern/misc.c kern/mm.c kern/reader.c kern/term.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/ieee1275/init.c \

View file

@ -35,7 +35,7 @@ kernel_img_HEADERS = boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \
kern/ieee1275/ieee1275.c kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \
kern/misc.c kern/mm.c kern/reader.c kern/term.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/sparc64/ieee1275/ieee1275.c \

50
conf/tests.rmk Normal file
View file

@ -0,0 +1,50 @@
# -*- makefile -*-
# For grub-shell
grub-shell: tests/util/grub-shell.in config.status
./config.status --file=$@:$<
chmod +x $@
check_SCRIPTS += grub-shell
CLEANFILES += grub-shell
# For grub-shell-tester
grub-shell-tester: tests/util/grub-shell-tester.in config.status
./config.status --file=$@:$<
chmod +x $@
check_SCRIPTS += grub-shell-tester
CLEANFILES += grub-shell-tester
pkglib_MODULES += functional_test.mod
functional_test_mod_SOURCES = tests/lib/functional_test.c tests/lib/test.c
functional_test_mod_CFLAGS = $(COMMON_CFLAGS)
functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS)
# Rules for unit tests
check_UTILITIES += example_unit_test
example_unit_test_SOURCES = tests/example_unit_test.c kern/list.c kern/misc.c tests/lib/test.c tests/lib/unit_test.c
example_unit_test_CFLAGS = -Wno-format
# Rules for functional tests
pkglib_MODULES += example_functional_test.mod
example_functional_test_mod_SOURCES = tests/example_functional_test.c
example_functional_test_mod_CFLAGS = -Wno-format $(COMMON_CFLAGS)
example_functional_test_mod_LDFLAGS = $(COMMON_LDFLAGS)
# Rules for scripted tests
check_SCRIPTS += example_scripted_test
example_scripted_test_SOURCES = tests/example_scripted_test.in
check_SCRIPTS += example_grub_script_test
example_grub_script_test_SOURCES = tests/example_grub_script_test.in
# List of tests to execute on "make check"
SCRIPTED_TESTS = example_scripted_test
SCRIPTED_TESTS += example_grub_script_test
UNIT_TESTS = example_unit_test
FUNCTIONAL_TESTS = example_functional_test.mod
# dependencies between tests and testing-tools
$(SCRIPTED_TESTS): grub-shell grub-shell-tester
$(FUNCTIONAL_TESTS): functional_test.mod

View file

@ -32,14 +32,14 @@ grub_install_SOURCES = util/i386/efi/grub-install.in
pkglib_MODULES = kernel.img chain.mod appleldr.mod \
halt.mod reboot.mod linux.mod pci.mod lspci.mod \
datetime.mod date.mod datehook.mod loadbios.mod \
fixvideo.mod mmap.mod acpi.mod ata.mod
fixvideo.mod mmap.mod acpi.mod
# For kernel.img.
kernel_img_EXPORTS = no
kernel_img_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \
kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
kern/misc.c kern/mm.c kern/reader.c kern/term.c \
kern/misc.c kern/mm.c kern/term.c \
kern/rescue_parser.c kern/rescue_reader.c \
kern/$(target_cpu)/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
@ -77,11 +77,6 @@ acpi_mod_SOURCES = commands/acpi.c commands/efi/acpi.c
acpi_mod_CFLAGS = $(COMMON_CFLAGS)
acpi_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ata.mod
ata_mod_SOURCES = disk/ata.c
ata_mod_CFLAGS = $(COMMON_CFLAGS)
ata_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For mmap.mod.
mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \
mmap/efi/mmap.c
@ -166,10 +161,5 @@ xnu_mod_CFLAGS = $(COMMON_CFLAGS)
xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
pkglib_MODULES += relocator.mod
relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S
relocator_mod_CFLAGS = $(COMMON_CFLAGS)
relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
relocator_mod_LDFLAGS = $(COMMON_LDFLAGS)
include $(srcdir)/conf/i386.mk
include $(srcdir)/conf/common.mk

View file

@ -16,8 +16,4 @@
module=$1
grep -v "^#" | sed -n \
-e "/grub_parser_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/parser.\1: $module/;p;}" \
-e "/grub_reader_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/reader.\1: $module/;p;}" \
-e "/grub_term_register_input *( *\"/{s/.*( *\"\([^\"]*\)\".*/terminal_input.\1: $module/;p;}" \
-e "/grub_term_register_output *( *\"/{s/.*( *\"\([^\"]*\)\".*/terminal_output.\1: $module/;p;}" \
-e "/grub_menu_viewer_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/menu_viewer.\1: $module/;p;}"
-e "/grub_parser_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/parser.\1: $module/;p;}"

View file

@ -192,6 +192,7 @@ endif
fs = 'fs-' + obj.suffix('lst')
partmap = 'partmap-' + obj.suffix('lst')
handler = 'handler-' + obj.suffix('lst')
terminal = 'terminal-' + obj.suffix('lst')
parttool = 'parttool-' + obj.suffix('lst')
video = 'video-' + obj.suffix('lst')
dep = deps[i]
@ -213,6 +214,7 @@ FSFILES += #{fs}
PARTTOOLFILES += #{parttool}
PARTMAPFILES += #{partmap}
HANDLERFILES += #{handler}
TERMINALFILES += #{terminal}
VIDEOFILES += #{video}
#{command}: #{src} $(#{src}_DEPENDENCIES) gencmdlist.sh
@ -240,6 +242,11 @@ VIDEOFILES += #{video}
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
| sh $(srcdir)/genhandlerlist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
#{terminal}: #{src} $(#{src}_DEPENDENCIES) genterminallist.sh
set -e; \
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
| sh $(srcdir)/genterminallist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
#{video}: #{src} $(#{src}_DEPENDENCIES) genvideolist.sh
set -e; \
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
@ -363,8 +370,7 @@ class Script
"CLEANFILES += #{@name}
#{@name}: #{src} $(#{src}_DEPENDENCIES) config.status
./config.status --file=#{name}:#{src}
sed -i -e 's,@pkglib_DATA@,$(pkglib_DATA),g' $@
./config.status --file=-:#{src} | sed -e 's,@pkglib_DATA@,$(pkglib_DATA),g' > $@
chmod +x $@
"

20
genterminallist.sh Normal file
View file

@ -0,0 +1,20 @@
#! /bin/sh
#
# Copyright (C) 2009,2010 Free Software Foundation, Inc.
#
# This script is free software; the author
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# Read source code from stdin and detect command names.
module=$1
grep -v "^#" | sed -n \
-e "/grub_term_register_input *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $module/;p;}" \
-e "/grub_term_register_output *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $module/;p;}" \

View file

@ -148,14 +148,24 @@ grub_gettext_translate (const char *orig)
struct grub_gettext_msg *cur;
/* Make sure we can use grub_gettext_translate for error messages. Push
active error message to error stack and reset error message. */
grub_error_push ();
cur = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_gettext_msg_list),
orig);
if (cur)
{
grub_error_pop ();
return cur->translated;
}
if (fd_mo == 0)
{
grub_error_pop ();
return orig;
}
min = 0;
max = grub_gettext_max;
@ -205,6 +215,7 @@ grub_gettext_translate (const char *orig)
grub_errno = GRUB_ERR_NONE;
}
grub_error_pop ();
return ret;
}
@ -308,7 +319,7 @@ grub_gettext_delete_list (void)
char *original = (char *) ((struct grub_gettext_msg *) item)->name;
grub_free (original);
// Don't delete the translated message because could be in use.
/* Don't delete the translated message because could be in use. */
}
}
@ -347,8 +358,8 @@ GRUB_MOD_INIT (gettext)
grub_gettext_init_ext (lang);
grub_register_command_p1 ("gettext", grub_cmd_translate,
"STRING",
"Translates the string with the current settings.");
N_("STRING"),
N_("Translates the string with the current settings."));
/* Reload .mo file information if lang changes. */
grub_register_variable_hook ("lang", NULL, grub_gettext_env_write_lang);

View file

@ -109,4 +109,13 @@ grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src,
return dest;
}
/* Convert UCS-4 to UTF-8. */
char *grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size);
int
grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize);
int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
grub_uint32_t **last_position);
#endif

View file

@ -79,9 +79,9 @@ struct grub_e820_mmap
grub_uint32_t type;
} __attribute__((packed));
#define GRUB_VIDEO_TYPE_TEXT 0x01
#define GRUB_VIDEO_TYPE_VLFB 0x23 /* VESA VGA in graphic mode */
#define GRUB_VIDEO_TYPE_EFI 0x70
#define GRUB_VIDEO_LINUX_TYPE_TEXT 0x01
#define GRUB_VIDEO_LINUX_TYPE_VESA 0x23 /* VESA VGA in graphic mode. */
#define GRUB_VIDEO_LINUX_TYPE_SIMPLE 0x70 /* Linear framebuffer without any additional functions. */
/* For the Linux/i386 boot protocol version 2.03. */
struct linux_kernel_header

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2004,2007,2008,2009 Free Software Foundation, Inc.
* Copyright (C) 2002,2003,2004,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
@ -31,7 +31,7 @@ extern grub_uint32_t EXPORT_VAR(grub_linux_prot_size);
extern char *EXPORT_VAR(grub_linux_tmp_addr);
extern char *EXPORT_VAR(grub_linux_real_addr);
extern grub_int32_t EXPORT_VAR(grub_linux_is_bzimage);
grub_err_t EXPORT_FUNC(grub_linux16_boot) (void);
grub_err_t EXPORT_FUNC(grub_linux16_real_boot) (void);
#endif
#endif /* ! GRUB_LOADER_CPU_HEADER */

View file

@ -24,20 +24,25 @@
#include <grub/symbol.h>
#include <grub/types.h>
#include <grub/menu.h>
#include <grub/term.h>
struct grub_menu_viewer
{
/* The menu viewer name. */
const char *name;
grub_err_t (*show_menu) (grub_menu_t menu, int nested);
struct grub_menu_viewer *next;
void *data;
void (*set_chosen_entry) (int entry, void *data);
void (*print_timeout) (int timeout, void *data);
void (*clear_timeout) (void *data);
void (*fini) (void *fini);
};
typedef struct grub_menu_viewer *grub_menu_viewer_t;
void grub_menu_viewer_register (grub_menu_viewer_t viewer);
void grub_menu_register_viewer (struct grub_menu_viewer *viewer);
grub_err_t grub_menu_viewer_show_menu (grub_menu_t menu, int nested);
grub_err_t
grub_menu_try_text (struct grub_term_output *term,
int entry, grub_menu_t menu, int nested);
extern grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu,
int nested);
#endif /* GRUB_MENU_VIEWER_HEADER */

View file

@ -199,7 +199,7 @@ int EXPORT_FUNC(grub_sprintf) (char *str, const char *fmt, ...) __attribute__ ((
int EXPORT_FUNC(grub_vsprintf) (char *str, const char *fmt, va_list args);
void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn));
grub_ssize_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest,
grub_size_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest,
grub_size_t destsize,
const grub_uint8_t *src,
grub_size_t srcsize,

View file

@ -29,7 +29,22 @@
#include <multiboot.h>
#endif
#include <grub/types.h>
#include <grub/err.h>
void grub_multiboot (int argc, char *argv[]);
void grub_module (int argc, char *argv[]);
void grub_multiboot_set_accepts_video (int val);
grub_size_t grub_multiboot_get_mbi_size (void);
grub_err_t grub_multiboot_make_mbi (void *orig, grub_uint32_t dest,
grub_off_t buf_off, grub_size_t bufsize);
void grub_multiboot_free_mbi (void);
grub_err_t grub_multiboot_init_mbi (int argc, char *argv[]);
grub_err_t grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
int argc, char *argv[]);
void grub_multiboot_set_bootdev (void);
#endif /* ! GRUB_MULTIBOOT_HEADER */

View file

@ -20,6 +20,7 @@
#ifndef GRUB_NORMAL_HEADER
#define GRUB_NORMAL_HEADER 1
#include <grub/term.h>
#include <grub/symbol.h>
#include <grub/err.h>
#include <grub/env.h>
@ -45,21 +46,21 @@ enum grub_completion_type
typedef enum grub_completion_type grub_completion_type_t;
extern struct grub_menu_viewer grub_normal_text_menu_viewer;
extern int grub_normal_exit_level;
/* Defined in `main.c'. */
void grub_enter_normal_mode (const char *config);
void grub_normal_execute (const char *config, int nested, int batch);
void grub_normal_init_page (void);
void grub_menu_init_page (int nested, int edit);
void grub_menu_init_page (int nested, int edit,
struct grub_term_output *term);
void grub_normal_init_page (struct grub_term_output *term);
grub_err_t grub_normal_add_menu_entry (int argc, const char **args,
const char *sourcecode);
char *grub_file_getline (grub_file_t file);
void grub_cmdline_run (int nested);
/* Defined in `cmdline.c'. */
int grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
int echo_char, int readline, int history);
char *grub_cmdline_get (const char *prompt);
grub_err_t grub_set_history (int newsize);
/* Defined in `completion.c'. */
@ -76,14 +77,19 @@ void grub_parse_color_name_pair (grub_uint8_t *ret, const char *name);
/* Defined in `menu_text.c'. */
void grub_wait_after_message (void);
int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
grub_uint32_t **last_position);
void grub_print_ucs4 (const grub_uint32_t * str,
const grub_uint32_t * last_position);
const grub_uint32_t * last_position,
struct grub_term_output *term);
grub_ssize_t grub_getstringwidth (grub_uint32_t * str,
const grub_uint32_t * last_position);
const grub_uint32_t * last_position,
struct grub_term_output *term);
void grub_print_message_indented (const char *msg, int margin_left,
int margin_right);
int margin_right,
struct grub_term_output *term);
void
grub_menu_text_register_instances (int entry, grub_menu_t menu, int nested);
grub_err_t
grub_show_menu (grub_menu_t menu, int nested);
/* Defined in `handler.c'. */
void read_handler_list (void);
@ -97,6 +103,9 @@ void read_fs_list (void);
void read_crypto_list (void);
void read_terminal_list (void);
void grub_set_more (int onoff);
#ifdef GRUB_UTIL
void grub_normal_init (void);

View file

@ -22,6 +22,7 @@
#include <grub/types.h>
#include <grub/err.h>
#include <grub/handler.h>
#include <grub/reader.h>
/* All the states for the command line. */

View file

@ -20,60 +20,10 @@
#ifndef GRUB_READER_HEADER
#define GRUB_READER_HEADER 1
#include <grub/types.h>
#include <grub/err.h>
#include <grub/handler.h>
typedef grub_err_t (*grub_reader_getline_t) (char **, int);
struct grub_reader
{
/* The next reader. */
struct grub_parser *next;
/* The reader name. */
const char *name;
/* Initialize the reader. */
grub_err_t (*init) (void);
/* Clean up the reader. */
grub_err_t (*fini) (void);
grub_reader_getline_t read_line;
};
typedef struct grub_reader *grub_reader_t;
extern struct grub_handler_class EXPORT_VAR(grub_reader_class);
grub_err_t EXPORT_FUNC(grub_reader_loop) (grub_reader_getline_t getline);
static inline void
grub_reader_register (const char *name __attribute__ ((unused)),
grub_reader_t reader)
{
grub_handler_register (&grub_reader_class, GRUB_AS_HANDLER (reader));
}
static inline void
grub_reader_unregister (grub_reader_t reader)
{
grub_handler_unregister (&grub_reader_class, GRUB_AS_HANDLER (reader));
}
static inline grub_reader_t
grub_reader_get_current (void)
{
return (grub_reader_t) grub_reader_class.cur_handler;
}
static inline grub_err_t
grub_reader_set_current (grub_reader_t reader)
{
return grub_handler_set_current (&grub_reader_class,
GRUB_AS_HANDLER (reader));
}
void grub_register_rescue_reader (void);
void grub_rescue_run (void);
#endif /* ! GRUB_READER_HEADER */

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2003,2005,2007,2008,2009 Free Software Foundation, Inc.
* Copyright (C) 2002,2003,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
@ -68,8 +68,6 @@ grub_term_color_state;
#define GRUB_TERM_NO_EDIT (1 << 1)
/* Set when the terminal cannot do fancy things. */
#define GRUB_TERM_DUMB (1 << 2)
/* Set when the terminal needs to be initialized. */
#define GRUB_TERM_NEED_INIT (1 << 16)
/* Bitmasks for modifier keys returned by grub_getkeystatus. */
@ -93,10 +91,6 @@ grub_term_color_state;
/* Menu-related geometrical constants. */
/* FIXME: Ugly way to get them form terminal. */
#define GRUB_TERM_WIDTH ((grub_getwh()&0xFF00)>>8)
#define GRUB_TERM_HEIGHT (grub_getwh()&0xFF)
/* The number of lines of "GRUB version..." at the top. */
#define GRUB_TERM_INFO_HEIGHT 1
@ -113,37 +107,12 @@ grub_term_color_state;
/* The X position of the left border. */
#define GRUB_TERM_LEFT_BORDER_X GRUB_TERM_MARGIN
/* The width of the border. */
#define GRUB_TERM_BORDER_WIDTH (GRUB_TERM_WIDTH \
- GRUB_TERM_MARGIN * 3 \
- GRUB_TERM_SCROLL_WIDTH)
/* The number of lines of messages at the bottom. */
#define GRUB_TERM_MESSAGE_HEIGHT 8
/* The height of the border. */
#define GRUB_TERM_BORDER_HEIGHT (GRUB_TERM_HEIGHT \
- GRUB_TERM_TOP_BORDER_Y \
- GRUB_TERM_MESSAGE_HEIGHT)
/* The number of entries shown at a time. */
#define GRUB_TERM_NUM_ENTRIES (GRUB_TERM_BORDER_HEIGHT - 2)
/* The Y position of the first entry. */
#define GRUB_TERM_FIRST_ENTRY_Y (GRUB_TERM_TOP_BORDER_Y + 1)
/* The max column number of an entry. The last "-1" is for a
continuation marker. */
#define GRUB_TERM_ENTRY_WIDTH (GRUB_TERM_BORDER_WIDTH - 2 \
- GRUB_TERM_MARGIN * 2 - 1)
/* The standard X position of the cursor. */
#define GRUB_TERM_CURSOR_X (GRUB_TERM_LEFT_BORDER_X \
+ GRUB_TERM_BORDER_WIDTH \
- GRUB_TERM_MARGIN \
- 1)
struct grub_term_input
{
/* The next terminal. */
@ -224,86 +193,222 @@ struct grub_term_output
};
typedef struct grub_term_output *grub_term_output_t;
extern struct grub_handler_class EXPORT_VAR(grub_term_input_class);
extern struct grub_handler_class EXPORT_VAR(grub_term_output_class);
extern struct grub_term_output *EXPORT_VAR(grub_term_outputs_disabled);
extern struct grub_term_input *EXPORT_VAR(grub_term_inputs_disabled);
extern struct grub_term_output *EXPORT_VAR(grub_term_outputs);
extern struct grub_term_input *EXPORT_VAR(grub_term_inputs);
static inline void
grub_term_register_input (const char *name __attribute__ ((unused)),
grub_term_input_t term)
{
grub_handler_register (&grub_term_input_class, GRUB_AS_HANDLER (term));
if (grub_term_inputs)
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
GRUB_AS_LIST (term));
else
{
/* If this is the first terminal, enable automatically. */
if (term->init)
term->init ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term));
}
}
static inline void
grub_term_register_output (const char *name __attribute__ ((unused)),
grub_term_output_t term)
{
grub_handler_register (&grub_term_output_class, GRUB_AS_HANDLER (term));
if (grub_term_outputs)
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
GRUB_AS_LIST (term));
else
{
/* If this is the first terminal, enable automatically. */
if (term->init)
term->init ();
grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
GRUB_AS_LIST (term));
}
}
static inline void
grub_term_unregister_input (grub_term_input_t term)
{
grub_handler_unregister (&grub_term_input_class, GRUB_AS_HANDLER (term));
grub_list_remove (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term));
grub_list_remove (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
GRUB_AS_LIST (term));
}
static inline void
grub_term_unregister_output (grub_term_output_t term)
{
grub_handler_unregister (&grub_term_output_class, GRUB_AS_HANDLER (term));
grub_list_remove (GRUB_AS_LIST_P (&grub_term_outputs), GRUB_AS_LIST (term));
grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
GRUB_AS_LIST (term));
}
static inline grub_err_t
grub_term_set_current_input (grub_term_input_t term)
{
return grub_handler_set_current (&grub_term_input_class,
GRUB_AS_HANDLER (term));
}
static inline grub_err_t
grub_term_set_current_output (grub_term_output_t term)
{
return grub_handler_set_current (&grub_term_output_class,
GRUB_AS_HANDLER (term));
}
static inline grub_term_input_t
grub_term_get_current_input (void)
{
return (grub_term_input_t) grub_term_input_class.cur_handler;
}
static inline grub_term_output_t
grub_term_get_current_output (void)
{
return (grub_term_output_t) grub_term_output_class.cur_handler;
}
#define FOR_ACTIVE_TERM_INPUTS(var) for (var = grub_term_inputs; var; var = var->next)
#define FOR_DISABLED_TERM_INPUTS(var) for (var = grub_term_inputs_disabled; var; var = var->next)
#define FOR_ACTIVE_TERM_OUTPUTS(var) for (var = grub_term_outputs; var; var = var->next)
#define FOR_DISABLED_TERM_OUTPUTS(var) for (var = grub_term_outputs_disabled; var; var = var->next)
void EXPORT_FUNC(grub_putchar) (int c);
void EXPORT_FUNC(grub_putcode) (grub_uint32_t code);
grub_ssize_t EXPORT_FUNC(grub_getcharwidth) (grub_uint32_t code);
void EXPORT_FUNC(grub_putcode) (grub_uint32_t code,
struct grub_term_output *term);
int EXPORT_FUNC(grub_getkey) (void);
int EXPORT_FUNC(grub_checkkey) (void);
int EXPORT_FUNC(grub_getkeystatus) (void);
grub_uint16_t EXPORT_FUNC(grub_getwh) (void);
grub_uint16_t EXPORT_FUNC(grub_getxy) (void);
void EXPORT_FUNC(grub_gotoxy) (grub_uint8_t x, grub_uint8_t y);
void EXPORT_FUNC(grub_cls) (void);
void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state);
void EXPORT_FUNC(grub_setcolor) (grub_uint8_t normal_color,
grub_uint8_t highlight_color);
void EXPORT_FUNC(grub_getcolor) (grub_uint8_t *normal_color,
grub_uint8_t *highlight_color);
int EXPORT_FUNC(grub_setcursor) (int on);
int EXPORT_FUNC(grub_getcursor) (void);
void EXPORT_FUNC(grub_refresh) (void);
void EXPORT_FUNC(grub_set_more) (int onoff);
void grub_puts_terminal (const char *str, struct grub_term_output *term);
grub_uint16_t *grub_term_save_pos (void);
void grub_term_restore_pos (grub_uint16_t *pos);
static inline unsigned grub_term_width (struct grub_term_output *term)
{
return ((term->getwh()&0xFF00)>>8);
}
static inline unsigned grub_term_height (struct grub_term_output *term)
{
return (term->getwh()&0xFF);
}
/* The width of the border. */
static inline unsigned
grub_term_border_width (struct grub_term_output *term)
{
return grub_term_width (term) - GRUB_TERM_MARGIN * 3 - GRUB_TERM_SCROLL_WIDTH;
}
/* The max column number of an entry. The last "-1" is for a
continuation marker. */
static inline int
grub_term_entry_width (struct grub_term_output *term)
{
return grub_term_border_width (term) - 2 - GRUB_TERM_MARGIN * 2 - 1;
}
/* The height of the border. */
static inline unsigned
grub_term_border_height (struct grub_term_output *term)
{
return grub_term_height (term) - GRUB_TERM_TOP_BORDER_Y
- GRUB_TERM_MESSAGE_HEIGHT;
}
/* The number of entries shown at a time. */
static inline int
grub_term_num_entries (struct grub_term_output *term)
{
return grub_term_border_height (term) - 2;
}
static inline int
grub_term_cursor_x (struct grub_term_output *term)
{
return (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
- GRUB_TERM_MARGIN - 1);
}
static inline grub_uint16_t
grub_term_getxy (struct grub_term_output *term)
{
return term->getxy ();
}
static inline void
grub_print_spaces (int number_spaces)
grub_term_refresh (struct grub_term_output *term)
{
if (term->refresh)
term->refresh ();
}
static inline void
grub_term_gotoxy (struct grub_term_output *term, grub_uint8_t x, grub_uint8_t y)
{
term->gotoxy (x, y);
}
static inline void
grub_term_setcolorstate (struct grub_term_output *term,
grub_term_color_state state)
{
if (term->setcolorstate)
term->setcolorstate (state);
}
/* Set the normal color and the highlight color. The format of each
color is VGA's. */
static inline void
grub_term_setcolor (struct grub_term_output *term,
grub_uint8_t normal_color, grub_uint8_t highlight_color)
{
if (term->setcolor)
term->setcolor (normal_color, highlight_color);
}
/* Turn on/off the cursor. */
static inline void
grub_term_setcursor (struct grub_term_output *term, int on)
{
if (term->setcursor)
term->setcursor (on);
}
static inline void
grub_term_cls (struct grub_term_output *term)
{
if (term->cls)
(term->cls) ();
else
{
grub_putcode ('\n', term);
grub_term_refresh (term);
}
}
static inline grub_ssize_t
grub_term_getcharwidth (struct grub_term_output *term, grub_uint32_t c)
{
if (term->getcharwidth)
return term->getcharwidth (c);
else
return 1;
}
static inline void
grub_term_getcolor (struct grub_term_output *term,
grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
{
if (term->getcolor)
term->getcolor (normal_color, highlight_color);
else
{
*normal_color = 0x07;
*highlight_color = 0x07;
}
}
extern void (*EXPORT_VAR (grub_newline_hook)) (void);
struct grub_term_autoload
{
struct grub_term_autoload *next;
char *name;
char *modname;
};
extern struct grub_term_autoload *grub_term_input_autoload;
extern struct grub_term_autoload *grub_term_output_autoload;
static inline void
grub_print_spaces (struct grub_term_output *term, int number_spaces)
{
while (--number_spaces >= 0)
grub_putchar (' ');
grub_putcode (' ', term);
}

View file

@ -21,15 +21,17 @@
#include <grub/err.h>
#include <grub/types.h>
#include <grub/term.h>
char *grub_terminfo_get_current (void);
grub_err_t grub_terminfo_set_current (const char *);
void grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y);
void grub_terminfo_cls (void);
void grub_terminfo_reverse_video_on (void);
void grub_terminfo_reverse_video_off (void);
void grub_terminfo_cursor_on (void);
void grub_terminfo_cursor_off (void);
void grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y,
grub_term_output_t oterm);
void grub_terminfo_cls (grub_term_output_t oterm);
void grub_terminfo_reverse_video_on (grub_term_output_t oterm);
void grub_terminfo_reverse_video_off (grub_term_output_t oterm);
void grub_terminfo_cursor_on (grub_term_output_t oterm);
void grub_terminfo_cursor_off (grub_term_output_t oterm);
#endif /* ! GRUB_TERMINFO_HEADER */

85
include/grub/test.h Normal file
View file

@ -0,0 +1,85 @@
/*
* 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/>.
*/
#ifndef GRUB_TEST_HEADER
#define GRUB_TEST_HEADER
#include <grub/dl.h>
#include <grub/list.h>
#include <grub/misc.h>
#include <grub/types.h>
#include <grub/symbol.h>
struct grub_test
{
/* The next test. */
struct grub_test *next;
/* The test name. */
char *name;
/* The test main function. */
void (*main) (void);
};
typedef struct grub_test *grub_test_t;
extern grub_test_t grub_test_list;
void grub_test_register (const char *name, void (*test) (void));
void grub_test_unregister (const char *name);
/* Execute a test and print results. */
int grub_test_run (grub_test_t test);
/* Test `cond' for nonzero; log failure otherwise. */
void grub_test_nonzero (int cond, const char *file,
const char *func, grub_uint32_t line,
const char *fmt, ...)
__attribute__ ((format (printf, 5, 6)));
/* Macro to fill in location details and an optional error message. */
#define grub_test_assert(cond, ...) \
grub_test_nonzero(cond, __FILE__, __FUNCTION__, __LINE__, \
## __VA_ARGS__, \
"assert failed: %s", #cond)
/* Macro to define a unit test. */
#define GRUB_UNIT_TEST(name, funp) \
void grub_unit_test_init (void) \
{ \
grub_test_register (name, funp); \
} \
\
void grub_unit_test_fini (void) \
{ \
grub_test_unregister (name); \
}
/* Macro to define a functional test. */
#define GRUB_FUNCTIONAL_TEST(name, funp) \
GRUB_MOD_INIT(functional_test_##funp) \
{ \
grub_test_register (name, funp); \
} \
\
GRUB_MOD_FINI(functional_test_##funp) \
{ \
grub_test_unregister (name); \
}
#endif /* ! GRUB_TEST_HEADER */

View file

@ -159,10 +159,19 @@ struct grub_video_palette_data
grub_uint8_t a; /* Reserved bits value (0-255). */
};
typedef enum grub_video_driver_id
{
GRUB_VIDEO_DRIVER_NONE,
GRUB_VIDEO_DRIVER_VBE,
GRUB_VIDEO_DRIVER_EFI_UGA,
GRUB_VIDEO_DRIVER_EFI_GOP
} grub_video_driver_id_t;
struct grub_video_adapter
{
/* The video adapter name. */
const char *name;
grub_video_driver_id_t id;
/* Initialize the video adapter. */
grub_err_t (*init) (void);
@ -171,7 +180,7 @@ struct grub_video_adapter
grub_err_t (*fini) (void);
grub_err_t (*setup) (unsigned int width, unsigned int height,
unsigned int mode_type);
unsigned int mode_type, unsigned int mode_mask);
grub_err_t (*get_info) (struct grub_video_mode_info *mode_info);
@ -307,7 +316,17 @@ grub_err_t grub_video_set_active_render_target (struct grub_video_render_target
grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target);
grub_err_t grub_video_set_mode (const char *modestring,
int NESTED_FUNC_ATTR (*hook) (grub_video_adapter_t p,
struct grub_video_mode_info *mode_info));
unsigned int modemask,
unsigned int modevalue);
static inline int
grub_video_check_mode_flag (unsigned int flags, unsigned int mask,
unsigned int flag, int def)
{
return (flag & mask) ? !! (flags & flag) : def;
}
grub_video_driver_id_t
grub_video_get_driver_id (void);
#endif /* ! GRUB_VIDEO_HEADER */

View file

@ -0,0 +1 @@
#include <grub/i386/multiboot.h>

View file

@ -85,10 +85,12 @@
#define MULTIBOOT_INFO_APM_TABLE 0x00000400
/* Is there video information? */
#define MULTIBOOT_INFO_VIDEO_INFO 0x00000800
#define MULTIBOOT_INFO_VBE_INFO 0x00000800
#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000
#ifndef ASM_FILE
typedef unsigned char multiboot_uint8_t;
typedef unsigned short multiboot_uint16_t;
typedef unsigned int multiboot_uint32_t;
typedef unsigned long long multiboot_uint64_t;
@ -187,9 +189,43 @@ struct multiboot_info
multiboot_uint16_t vbe_interface_seg;
multiboot_uint16_t vbe_interface_off;
multiboot_uint16_t vbe_interface_len;
multiboot_uint64_t framebuffer_addr;
multiboot_uint32_t framebuffer_pitch;
multiboot_uint32_t framebuffer_width;
multiboot_uint32_t framebuffer_height;
multiboot_uint8_t framebuffer_bpp;
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
multiboot_uint8_t framebuffer_type;
union
{
struct
{
multiboot_uint32_t framebuffer_palette_addr;
multiboot_uint16_t framebuffer_palette_num_colors;
};
struct
{
multiboot_uint8_t framebuffer_red_field_position;
multiboot_uint8_t framebuffer_red_mask_size;
multiboot_uint8_t framebuffer_green_field_position;
multiboot_uint8_t framebuffer_green_mask_size;
multiboot_uint8_t framebuffer_blue_field_position;
multiboot_uint8_t framebuffer_blue_mask_size;
};
};
};
typedef struct multiboot_info multiboot_info_t;
struct multiboot_color
{
multiboot_uint8_t red;
multiboot_uint8_t green;
multiboot_uint8_t blue;
};
struct multiboot_mmap_entry
{
multiboot_uint32_t size;

View file

@ -85,10 +85,12 @@
#define MULTIBOOT_INFO_APM_TABLE 0x00000400
/* Is there video information? */
#define MULTIBOOT_INFO_VIDEO_INFO 0x00000800
#define MULTIBOOT_INFO_VBE_INFO 0x00000800
#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000
#ifndef ASM_FILE
typedef unsigned char multiboot_uint8_t;
typedef unsigned short multiboot_uint16_t;
typedef unsigned int multiboot_uint32_t;
typedef unsigned long long multiboot_uint64_t;
@ -187,9 +189,43 @@ struct multiboot_info
multiboot_uint16_t vbe_interface_seg;
multiboot_uint16_t vbe_interface_off;
multiboot_uint16_t vbe_interface_len;
multiboot_uint64_t framebuffer_addr;
multiboot_uint32_t framebuffer_pitch;
multiboot_uint32_t framebuffer_width;
multiboot_uint32_t framebuffer_height;
multiboot_uint8_t framebuffer_bpp;
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
multiboot_uint8_t framebuffer_type;
union
{
struct
{
multiboot_uint32_t framebuffer_palette_addr;
multiboot_uint16_t framebuffer_palette_num_colors;
};
struct
{
multiboot_uint8_t framebuffer_red_field_position;
multiboot_uint8_t framebuffer_red_mask_size;
multiboot_uint8_t framebuffer_green_field_position;
multiboot_uint8_t framebuffer_green_mask_size;
multiboot_uint8_t framebuffer_blue_field_position;
multiboot_uint8_t framebuffer_blue_mask_size;
};
};
};
typedef struct multiboot_info multiboot_info_t;
struct multiboot_color
{
multiboot_uint8_t red;
multiboot_uint8_t green;
multiboot_uint8_t blue;
};
struct multiboot_mmap_entry
{
multiboot_uint32_t size;

View file

@ -82,6 +82,5 @@ void
grub_efi_fini (void)
{
grub_efidisk_fini ();
grub_efi_mm_fini ();
grub_console_fini ();
}

View file

@ -45,7 +45,7 @@ grub_error (grub_err_t n, const char *fmt, ...)
grub_errno = n;
va_start (ap, fmt);
grub_vsprintf (grub_errmsg, fmt, ap);
grub_vsprintf (grub_errmsg, _(fmt), ap);
va_end (ap);
return n;
@ -57,7 +57,7 @@ grub_fatal (const char *fmt, ...)
va_list ap;
va_start (ap, fmt);
grub_vprintf (fmt, ap);
grub_vprintf (_(fmt), ap);
va_end (ap);
grub_abort ();

View file

@ -59,7 +59,7 @@ VARIABLE(grub_linux_real_addr)
VARIABLE(grub_linux_is_bzimage)
.long 0
FUNCTION(grub_linux16_boot)
FUNCTION(grub_linux16_real_boot)
/* Must be done before zImage copy. */
call EXT_C(grub_dl_unload_all)

View file

@ -169,9 +169,8 @@ grub_main (void)
grub_register_core_commands ();
grub_register_rescue_parser ();
grub_register_rescue_reader ();
grub_load_config ();
grub_load_normal_mode ();
grub_reader_loop (0);
grub_rescue_run ();
}

View file

@ -892,10 +892,10 @@ grub_sprintf (char *str, const char *fmt, ...)
/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string.
Return the number of characters converted. DEST must be able to hold
at least DESTSIZE characters. If an invalid sequence is found, return -1.
at least DESTSIZE characters.
If SRCEND is not NULL, then *SRCEND is set to the next byte after the
last byte used in SRC. */
grub_ssize_t
grub_size_t
grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
const grub_uint8_t *src, grub_size_t srcsize,
const grub_uint8_t **srcend)
@ -917,7 +917,8 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
if ((c & 0xc0) != 0x80)
{
/* invalid */
return -1;
code = '?';
count = 0;
}
else
{
@ -959,7 +960,11 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
code = c & 0x01;
}
else
return -1;
{
/* invalid */
code = '?';
count = 0;
}
}
if (count == 0)
@ -977,17 +982,16 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
/* Abort GRUB. This function does not return. */
void
grub_abort (void)
{
if (grub_term_get_current_output ())
{
grub_printf ("\nAborted.");
if (grub_term_get_current_input ())
#ifndef GRUB_UTIL
if (grub_term_inputs)
#endif
{
grub_printf (" Press any key to exit.");
grub_getkey ();
}
}
grub_exit ();
}

View file

@ -1,49 +0,0 @@
/* reader.c - reader support */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/types.h>
#include <grub/mm.h>
#include <grub/reader.h>
#include <grub/parser.h>
struct grub_handler_class grub_reader_class =
{
.name = "reader"
};
grub_err_t
grub_reader_loop (grub_reader_getline_t getline)
{
while (1)
{
char *line;
grub_reader_getline_t func;
/* Print an error, if any. */
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
func = (getline) ? : grub_reader_get_current ()->read_line;
if ((func (&line, 0)) || (! line))
return grub_errno;
grub_parser_get_current ()->parse_line (line, func);
grub_free (line);
}
}

View file

@ -19,20 +19,15 @@
#include <grub/types.h>
#include <grub/reader.h>
#include <grub/parser.h>
#include <grub/misc.h>
#include <grub/term.h>
#include <grub/mm.h>
#define GRUB_RESCUE_BUF_SIZE 256
static char linebuf[GRUB_RESCUE_BUF_SIZE];
static grub_err_t
grub_rescue_init (void)
{
grub_printf ("Entering rescue mode...\n");
return 0;
}
/* Prompt to input a command and read the line. */
static grub_err_t
grub_rescue_read_line (char **line, int cont)
@ -74,15 +69,24 @@ grub_rescue_read_line (char **line, int cont)
return 0;
}
static struct grub_reader grub_rescue_reader =
{
.name = "rescue",
.init = grub_rescue_init,
.read_line = grub_rescue_read_line
};
void
grub_register_rescue_reader (void)
grub_rescue_run (void)
{
grub_reader_register ("rescue", &grub_rescue_reader);
grub_printf ("Entering rescue mode...\n");
while (1)
{
char *line;
/* Print an error, if any. */
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
grub_rescue_read_line (&line, 0);
if (! line)
continue;
grub_parser_get_current ()->parse_line (line, grub_rescue_read_line);
grub_free (line);
}
}

View file

@ -21,79 +21,33 @@
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/env.h>
#include <grub/time.h>
/* The amount of lines counted by the pager. */
static int grub_more_lines;
struct grub_term_output *grub_term_outputs_disabled;
struct grub_term_input *grub_term_inputs_disabled;
struct grub_term_output *grub_term_outputs;
struct grub_term_input *grub_term_inputs;
/* If the more pager is active. */
static int grub_more;
/* The current cursor state. */
static int cursor_state = 1;
struct grub_handler_class grub_term_input_class =
{
.name = "terminal_input"
};
struct grub_handler_class grub_term_output_class =
{
.name = "terminal_output"
};
#define grub_cur_term_input grub_term_get_current_input ()
#define grub_cur_term_output grub_term_get_current_output ()
void (*grub_newline_hook) (void) = NULL;
/* Put a Unicode character. */
void
grub_putcode (grub_uint32_t code)
grub_putcode (grub_uint32_t code, struct grub_term_output *term)
{
int height = grub_getwh () & 255;
if (code == '\t' && grub_cur_term_output->getxy)
if (code == '\t' && term->getxy)
{
int n;
n = 8 - ((grub_getxy () >> 8) & 7);
n = 8 - ((term->getxy () >> 8) & 7);
while (n--)
grub_putcode (' ');
grub_putcode (' ', term);
return;
}
(grub_cur_term_output->putchar) (code);
(term->putchar) (code);
if (code == '\n')
{
grub_putcode ('\r');
grub_more_lines++;
if (grub_more && grub_more_lines == height - 1)
{
char key;
int pos = grub_getxy ();
/* Show --MORE-- on the lower left side of the screen. */
grub_gotoxy (1, height - 1);
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf ("--MORE--");
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
key = grub_getkey ();
/* Remove the message. */
grub_gotoxy (1, height - 1);
grub_printf (" ");
grub_gotoxy (pos >> 8, pos & 0xFF);
/* Scroll one lines or an entire page, depending on the key. */
if (key == '\r' || key =='\n')
grub_more_lines--;
else
grub_more_lines = 0;
}
}
(term->putchar) ('\r');
}
/* Put a character. C is one byte of a UTF-8 stream.
@ -104,136 +58,101 @@ grub_putchar (int c)
static grub_size_t size = 0;
static grub_uint8_t buf[6];
grub_uint32_t code;
grub_ssize_t ret;
grub_size_t ret;
buf[size++] = c;
ret = grub_utf8_to_ucs4 (&code, 1, buf, size, 0);
if (ret > 0)
if (ret != 0)
{
struct grub_term_output *term;
size = 0;
grub_putcode (code);
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_putcode (code, term);
if (code == '\n' && grub_newline_hook)
grub_newline_hook ();
}
else if (ret < 0)
{
size = 0;
grub_putcode ('?');
}
}
/* Return the number of columns occupied by the character code CODE. */
grub_ssize_t
grub_getcharwidth (grub_uint32_t code)
{
return (grub_cur_term_output->getcharwidth) (code);
}
int
grub_getkey (void)
{
return (grub_cur_term_input->getkey) ();
grub_term_input_t term;
while (1)
{
FOR_ACTIVE_TERM_INPUTS(term)
{
int key = term->checkkey ();
if (key != -1)
return term->getkey ();
}
grub_cpu_idle ();
}
}
int
grub_checkkey (void)
{
return (grub_cur_term_input->checkkey) ();
grub_term_input_t term;
FOR_ACTIVE_TERM_INPUTS(term)
{
int key = term->checkkey ();
if (key != -1)
return key;
}
return -1;
}
int
grub_getkeystatus (void)
{
if (grub_cur_term_input->getkeystatus)
return (grub_cur_term_input->getkeystatus) ();
else
return 0;
int status = 0;
grub_term_input_t term;
FOR_ACTIVE_TERM_INPUTS(term)
{
if (term->getkeystatus)
status |= term->getkeystatus ();
}
grub_uint16_t
grub_getxy (void)
{
return (grub_cur_term_output->getxy) ();
}
grub_uint16_t
grub_getwh (void)
{
return (grub_cur_term_output->getwh) ();
}
void
grub_gotoxy (grub_uint8_t x, grub_uint8_t y)
{
(grub_cur_term_output->gotoxy) (x, y);
return status;
}
void
grub_cls (void)
{
if ((grub_cur_term_output->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
struct grub_term_output *term;
FOR_ACTIVE_TERM_OUTPUTS(term)
{
grub_putchar ('\n');
grub_refresh ();
if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
{
grub_putcode ('\n', term);
grub_term_refresh (term);
}
else
(grub_cur_term_output->cls) ();
(term->cls) ();
}
}
void
grub_setcolorstate (grub_term_color_state state)
{
if (grub_cur_term_output->setcolorstate)
(grub_cur_term_output->setcolorstate) (state);
}
struct grub_term_output *term;
void
grub_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
{
if (grub_cur_term_output->setcolor)
(grub_cur_term_output->setcolor) (normal_color, highlight_color);
}
void
grub_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
{
if (grub_cur_term_output->getcolor)
(grub_cur_term_output->getcolor) (normal_color, highlight_color);
}
int
grub_setcursor (int on)
{
int ret = cursor_state;
if (grub_cur_term_output->setcursor)
{
(grub_cur_term_output->setcursor) (on);
cursor_state = on;
}
return ret;
}
int
grub_getcursor (void)
{
return cursor_state;
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_term_setcolorstate (term, state);
}
void
grub_refresh (void)
{
if (grub_cur_term_output->refresh)
(grub_cur_term_output->refresh) ();
}
struct grub_term_output *term;
void
grub_set_more (int onoff)
{
if (onoff == 1)
grub_more++;
else
grub_more--;
grub_more_lines = 0;
FOR_ACTIVE_TERM_OUTPUTS(term)
grub_term_refresh (term);
}

View file

@ -24,6 +24,8 @@
last byte used in SRC. */
#include <grub/charset.h>
#include <grub/mm.h>
#include <grub/misc.h>
grub_ssize_t
grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
@ -114,3 +116,154 @@ grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
*srcend = src;
return p - dest;
}
/* Convert UCS-4 to UTF-8. */
char *
grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size)
{
grub_size_t remaining;
grub_uint32_t *ptr;
grub_size_t cnt = 0;
grub_uint8_t *ret, *dest;
remaining = size;
ptr = src;
while (remaining--)
{
grub_uint32_t code = *ptr++;
if (code <= 0x007F)
cnt++;
else if (code <= 0x07FF)
cnt += 2;
else if ((code >= 0xDC00 && code <= 0xDFFF)
|| (code >= 0xD800 && code <= 0xDBFF))
/* No surrogates in UCS-4... */
cnt++;
else
cnt += 3;
}
cnt++;
ret = grub_malloc (cnt);
if (!ret)
return 0;
dest = ret;
remaining = size;
ptr = src;
while (remaining--)
{
grub_uint32_t code = *ptr++;
if (code <= 0x007F)
*dest++ = code;
else if (code <= 0x07FF)
{
*dest++ = (code >> 6) | 0xC0;
*dest++ = (code & 0x3F) | 0x80;
}
else if ((code >= 0xDC00 && code <= 0xDFFF)
|| (code >= 0xD800 && code <= 0xDBFF))
{
/* No surrogates in UCS-4... */
*dest++ = '?';
}
else
{
*dest++ = (code >> 12) | 0xE0;
*dest++ = ((code >> 6) & 0x3F) | 0x80;
*dest++ = (code & 0x3F) | 0x80;
}
}
*dest = 0;
return (char *) ret;
}
int
grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize)
{
grub_uint32_t code = 0;
int count = 0;
while (srcsize)
{
grub_uint32_t c = *src++;
if (srcsize != (grub_size_t)-1)
srcsize--;
if (count)
{
if ((c & 0xc0) != 0x80)
{
/* invalid */
return 0;
}
else
{
code <<= 6;
code |= (c & 0x3f);
count--;
}
}
else
{
if (c == 0)
break;
if ((c & 0x80) == 0x00)
code = c;
else if ((c & 0xe0) == 0xc0)
{
count = 1;
code = c & 0x1f;
}
else if ((c & 0xf0) == 0xe0)
{
count = 2;
code = c & 0x0f;
}
else if ((c & 0xf8) == 0xf0)
{
count = 3;
code = c & 0x07;
}
else if ((c & 0xfc) == 0xf8)
{
count = 4;
code = c & 0x03;
}
else if ((c & 0xfe) == 0xfc)
{
count = 5;
code = c & 0x01;
}
else
return 0;
}
}
return 1;
}
int
grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
grub_uint32_t **last_position)
{
grub_size_t msg_len = grub_strlen (msg);
*unicode_msg = grub_malloc (grub_strlen (msg) * sizeof (grub_uint32_t));
if (!*unicode_msg)
{
grub_printf ("utf8_to_ucs4 ERROR1: %s", msg);
return -1;
}
msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len,
(grub_uint8_t *) msg, -1, 0);
*last_position = *unicode_msg + msg_len;
return msg_len;
}

View file

@ -25,6 +25,7 @@
#include <grub/efi/api.h>
#include <grub/efi/efi.h>
#include <grub/command.h>
#include <grub/i18n.h>
static grub_dl_t my_mod;
@ -321,7 +322,7 @@ static grub_command_t cmd;
GRUB_MOD_INIT(appleloader)
{
cmd = grub_register_command ("appleloader", grub_cmd_appleloader,
"[OPTS]", "Boot legacy system.");
"[OPTS]", N_("Boot legacy system."));
my_mod = mod;
}

View file

@ -33,6 +33,7 @@
#include <grub/efi/efi.h>
#include <grub/efi/disk.h>
#include <grub/command.h>
#include <grub/i18n.h>
static grub_dl_t my_mod;
@ -336,7 +337,7 @@ static grub_command_t cmd;
GRUB_MOD_INIT(chainloader)
{
cmd = grub_register_command ("chainloader", grub_cmd_chainloader,
0, "Load another boot loader.");
0, N_("Load another boot loader."));
my_mod = mod;
}

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2008, 2009 Free Software Foundation, Inc.
* Copyright (C) 2008,2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -35,7 +35,7 @@
#include <grub/command.h>
#include <grub/extcmd.h>
#include <grub/i18n.h>
#include <grub/video.h>
#ifdef GRUB_MACHINE_PCBIOS
#include <grub/machine/biosnum.h>
#endif
@ -509,6 +509,8 @@ grub_freebsd_boot (void)
bi.bi_kernend = kern_end;
grub_video_set_mode ("text", 0, 0);
if (is_64bit)
{
grub_uint32_t *gdt;
@ -617,6 +619,8 @@ grub_openbsd_boot (void)
pa->ba_type = OPENBSD_BOOTARG_END;
pa++;
grub_video_set_mode ("text", 0, 0);
grub_unix_real_boot (entry, bootflags, openbsd_root, OPENBSD_BOOTARG_APIVER,
0, (grub_uint32_t) (grub_mmap_get_upper () >> 10),
(grub_uint32_t) (grub_mmap_get_lower () >> 10),
@ -713,6 +717,8 @@ grub_netbsd_boot (void)
bootinfo->bi_data[0] = mmap;
}
grub_video_set_mode ("text", 0, 0);
grub_unix_real_boot (entry, bootflags, 0, bootinfo,
0, (grub_uint32_t) (grub_mmap_get_upper () >> 10),
(grub_uint32_t) (grub_mmap_get_lower () >> 10));

View file

@ -33,6 +33,7 @@
#include <grub/pci.h>
#include <grub/command.h>
#include <grub/memory.h>
#include <grub/i18n.h>
#define GRUB_LINUX_CL_OFFSET 0x1000
#define GRUB_LINUX_CL_END_OFFSET 0x2000
@ -586,7 +587,7 @@ grub_linux_setup_video (struct linux_kernel_params *params)
params->reserved_mask_size = 8;
params->reserved_field_pos = 24;
params->have_vga = GRUB_VIDEO_TYPE_VLFB;
params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA;
params->vid_mode = 0x338; /* 1024x768x32 */
return 0;
@ -619,7 +620,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
{
grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux header");
grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
goto fail;
}
@ -693,13 +694,32 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
params->ext_mem = ((32 * 0x100000) >> 10);
params->alt_mem = ((32 * 0x100000) >> 10);
params->video_cursor_x = grub_getxy () >> 8;
params->video_cursor_y = grub_getxy () & 0xff;
{
grub_term_output_t term;
int found = 0;
FOR_ACTIVE_TERM_OUTPUTS(term)
if (grub_strcmp (term->name, "vga_text") == 0
|| grub_strcmp (term->name, "console") == 0)
{
grub_uint16_t pos = grub_term_getxy (term);
params->video_cursor_x = pos >> 8;
params->video_cursor_y = pos & 0xff;
params->video_width = grub_term_width (term);
params->video_height = grub_term_height (term);
found = 1;
break;
}
if (!found)
{
params->video_cursor_x = 0;
params->video_cursor_y = 0;
params->video_width = 80;
params->video_height = 25;
}
}
params->video_page = 0; /* ??? */
params->video_mode = grub_efi_system_table->con_out->mode->mode;
params->video_width = (grub_getwh () >> 8);
params->video_ega_bx = 0;
params->video_height = (grub_getwh () & 0xff);
params->have_vga = 0;
params->font_size = 16; /* XXX */
@ -832,7 +852,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
else if (grub_memcmp (argv[i], "video=efifb", 11) == 0)
{
if (params->have_vga)
params->have_vga = GRUB_VIDEO_TYPE_EFI;
params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
}
/* Specify the boot file. */
@ -989,9 +1009,9 @@ static grub_command_t cmd_linux, cmd_initrd;
GRUB_MOD_INIT(linux)
{
cmd_linux = grub_register_command ("linux", grub_cmd_linux,
0, "Load Linux.");
0, N_("Load Linux."));
cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
0, "Load initrd.");
0, N_("Load initrd."));
my_mod = mod;
}

View file

@ -1,7 +1,7 @@
/* linux.c - boot Linux zImage or bzImage */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
* Copyright (C) 1999,2000,2001,2002,2003,2004,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
@ -32,6 +32,7 @@
#include <grub/cpu/linux.h>
#include <grub/ieee1275/ieee1275.h>
#include <grub/command.h>
#include <grub/i18n.h>
#define GRUB_OFW_LINUX_PARAMS_ADDR 0x90000
#define GRUB_OFW_LINUX_KERNEL_ADDR 0x100000
@ -109,8 +110,29 @@ grub_linux_boot (void)
params->cl_magic = GRUB_LINUX_CL_MAGIC;
params->cl_offset = GRUB_OFW_LINUX_CL_OFFSET;
params->video_width = (grub_getwh () >> 8);
params->video_height = (grub_getwh () & 0xff);
{
grub_term_output_t term;
int found = 0;
FOR_ACTIVE_TERM_OUTPUTS(term)
if (grub_strcmp (term->name, "ofconsole") == 0)
{
grub_uint16_t pos = grub_term_getxy (term);
params->video_cursor_x = pos >> 8;
params->video_cursor_y = pos & 0xff;
params->video_width = grub_term_width (term);
params->video_height = grub_term_height (term);
found = 1;
break;
}
if (!found)
{
params->video_cursor_x = 0;
params->video_cursor_y = 0;
params->video_width = 80;
params->video_height = 25;
}
}
params->font_size = 16;
params->ofw_signature = GRUB_LINUX_OFW_SIGNATURE;
@ -165,7 +187,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
{
grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux header");
grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
goto fail;
}
@ -276,9 +298,9 @@ static grub_command_t cmd_linux, cmd_initrd;
GRUB_MOD_INIT(linux)
{
cmd_linux = grub_register_command ("linux", grub_cmd_linux,
0, "Load Linux.");
0, N_("Load Linux."));
cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
0, "Load initrd.");
0, N_("Load initrd."));
my_mod = mod;
}

View file

@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
* Copyright (C) 2006,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
@ -33,6 +33,8 @@
#include <grub/video_fb.h>
#include <grub/command.h>
#include <grub/i386/pc/vbe.h>
#include <grub/i386/pc/console.h>
#include <grub/i18n.h>
#define GRUB_LINUX_CL_OFFSET 0x1000
#define GRUB_LINUX_CL_END_OFFSET 0x2000
@ -522,11 +524,11 @@ grub_linux_boot (void)
if (! tmp)
return grub_errno;
grub_sprintf (tmp, "%s;text", modevar);
err = grub_video_set_mode (tmp, 0);
err = grub_video_set_mode (tmp, 0, 0);
grub_free (tmp);
}
else
err = grub_video_set_mode ("text", 0);
err = grub_video_set_mode ("text", 0, 0);
if (err)
{
@ -536,19 +538,34 @@ grub_linux_boot (void)
}
if (! grub_linux_setup_video (params))
params->have_vga = GRUB_VIDEO_TYPE_VLFB;
params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA;
else
{
params->have_vga = GRUB_VIDEO_TYPE_TEXT;
params->have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT;
params->video_width = 80;
params->video_height = 25;
}
/* Initialize these last, because terminal position could be affected by printfs above. */
if (params->have_vga == GRUB_VIDEO_TYPE_TEXT)
if (params->have_vga == GRUB_VIDEO_LINUX_TYPE_TEXT)
{
params->video_cursor_x = grub_getxy () >> 8;
params->video_cursor_y = grub_getxy () & 0xff;
grub_term_output_t term;
int found = 0;
FOR_ACTIVE_TERM_OUTPUTS(term)
if (grub_strcmp (term->name, "vga_text") == 0
|| grub_strcmp (term->name, "console") == 0)
{
grub_uint16_t pos = grub_term_getxy (term);
params->video_cursor_x = pos >> 8;
params->video_cursor_y = pos & 0xff;
found = 1;
break;
}
if (!found)
{
params->video_cursor_x = 0;
params->video_cursor_y = 0;
}
}
#ifdef __x86_64__
@ -613,7 +630,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
{
grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux header");
grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
goto fail;
}
@ -712,7 +729,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
grub_printf (" [Linux-bzImage, setup=0x%x, size=0x%x]\n",
grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n",
(unsigned) real_size, (unsigned) prot_size);
/* Look for memory size and video mode specified on the command line. */
@ -963,7 +980,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
grub_printf (" [Initrd, addr=0x%x, size=0x%x]\n",
grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n",
(unsigned) addr, (unsigned) size);
lh->ramdisk_image = addr;
@ -982,9 +999,9 @@ static grub_command_t cmd_linux, cmd_initrd;
GRUB_MOD_INIT(linux)
{
cmd_linux = grub_register_command ("linux", grub_cmd_linux,
0, "Load Linux.");
0, N_("Load Linux."));
cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
0, "Load initrd.");
0, N_("Load initrd."));
my_mod = mod;
}

View file

@ -1,7 +1,7 @@
/* multiboot.c - boot a multiboot OS image. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
* Copyright (C) 1999,2000,2001,2002,2003,2004,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
@ -28,13 +28,11 @@
*/
/* The bits in the required part of flags field we don't support. */
#define UNSUPPORTED_FLAGS 0x0000fffc
#define UNSUPPORTED_FLAGS 0x0000fff8
#include <grub/loader.h>
#include <grub/machine/loader.h>
#include <grub/multiboot.h>
#include <grub/machine/init.h>
#include <grub/machine/memory.h>
#include <grub/cpu/multiboot.h>
#include <grub/elf.h>
#include <grub/aout.h>
@ -45,31 +43,29 @@
#include <grub/misc.h>
#include <grub/gzio.h>
#include <grub/env.h>
#ifdef GRUB_MACHINE_PCBIOS
#include <grub/machine/biosnum.h>
#include <grub/disk.h>
#include <grub/device.h>
#include <grub/partition.h>
#endif
#include <grub/i386/relocator.h>
#include <grub/video.h>
#ifdef GRUB_MACHINE_EFI
#include <grub/efi/efi.h>
#endif
extern grub_dl_t my_mod;
static struct multiboot_info *mbi, *mbi_dest;
static grub_size_t code_size;
static grub_size_t code_size, alloc_mbi;
char *grub_multiboot_payload_orig;
grub_addr_t grub_multiboot_payload_dest;
grub_size_t grub_multiboot_payload_size;
grub_size_t grub_multiboot_pure_size;
grub_uint32_t grub_multiboot_payload_eip;
static grub_err_t
grub_multiboot_boot (void)
{
grub_size_t mbi_size;
grub_err_t err;
struct grub_relocator32_state state =
{
.eax = MULTIBOOT_BOOTLOADER_MAGIC,
.ebx = PTR_TO_UINT32 (mbi_dest),
.ecx = 0,
.edx = 0,
.eip = grub_multiboot_payload_eip,
@ -78,6 +74,29 @@ grub_multiboot_boot (void)
.esp = 0x7ff00
};
mbi_size = grub_multiboot_get_mbi_size ();
if (alloc_mbi < mbi_size)
{
grub_multiboot_payload_orig
= grub_relocator32_realloc (grub_multiboot_payload_orig,
grub_multiboot_pure_size + mbi_size);
if (!grub_multiboot_payload_orig)
return grub_errno;
alloc_mbi = mbi_size;
}
state.ebx = grub_multiboot_payload_dest + grub_multiboot_pure_size;
err = grub_multiboot_make_mbi (grub_multiboot_payload_orig,
grub_multiboot_payload_dest,
grub_multiboot_pure_size, mbi_size);
if (err)
return err;
#ifdef GRUB_MACHINE_EFI
if (! grub_efi_finish_boot_services ())
grub_fatal ("cannot exit boot services");
#endif
grub_relocator32_boot (grub_multiboot_payload_orig,
grub_multiboot_payload_dest,
state);
@ -89,69 +108,18 @@ grub_multiboot_boot (void)
static grub_err_t
grub_multiboot_unload (void)
{
if (mbi)
{
unsigned int i;
for (i = 0; i < mbi->mods_count; i++)
{
grub_free ((void *)
((struct multiboot_mod_list *) mbi->mods_addr)[i].mod_start);
grub_free ((void *)
((struct multiboot_mod_list *) mbi->mods_addr)[i].cmdline);
}
grub_free ((void *) mbi->mods_addr);
}
grub_multiboot_free_mbi ();
grub_relocator32_free (grub_multiboot_payload_orig);
mbi = NULL;
alloc_mbi = 0;
grub_multiboot_payload_orig = NULL;
grub_dl_unref (my_mod);
return GRUB_ERR_NONE;
}
/* Return the length of the Multiboot mmap that will be needed to allocate
our platform's map. */
static grub_uint32_t
grub_get_multiboot_mmap_len (void)
{
grub_size_t count = 0;
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
grub_uint64_t size __attribute__ ((unused)),
grub_uint32_t type __attribute__ ((unused)))
{
count++;
return 0;
}
grub_mmap_iterate (hook);
return count * sizeof (struct multiboot_mmap_entry);
}
/* Fill previously allocated Multiboot mmap. */
static void
grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry)
{
struct multiboot_mmap_entry *mmap_entry = (struct multiboot_mmap_entry *) first_entry;
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)
{
mmap_entry->addr = addr;
mmap_entry->len = size;
mmap_entry->type = type;
mmap_entry->size = sizeof (struct multiboot_mmap_entry) - sizeof (mmap_entry->size);
mmap_entry++;
return 0;
}
grub_mmap_iterate (hook);
}
#define MULTIBOOT_LOAD_ELF64
#include "multiboot_elfxx.c"
#undef MULTIBOOT_LOAD_ELF64
@ -172,58 +140,13 @@ grub_multiboot_load_elf (grub_file_t file, void *buffer)
return grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class");
}
static int
grub_multiboot_get_bootdev (grub_uint32_t *bootdev)
{
#ifdef GRUB_MACHINE_PCBIOS
char *p;
grub_uint32_t biosdev, slice = ~0, part = ~0;
grub_device_t dev;
biosdev = grub_get_root_biosnumber ();
dev = grub_device_open (0);
if (dev && dev->disk && dev->disk->partition)
{
p = dev->disk->partition->partmap->get_name (dev->disk->partition);
if (p)
{
if ((p[0] >= '0') && (p[0] <= '9'))
{
slice = grub_strtoul (p, &p, 0) - 1;
if ((p) && (p[0] == ','))
p++;
}
if ((p[0] >= 'a') && (p[0] <= 'z'))
part = p[0] - 'a';
}
}
if (dev)
grub_device_close (dev);
*bootdev = ((biosdev & 0xff) << 24) | ((slice & 0xff) << 16)
| ((part & 0xff) << 8) | 0xff;
return (biosdev != ~0UL);
#else
*bootdev = 0xffffffff;
return 0;
#endif
}
void
grub_multiboot (int argc, char *argv[])
{
grub_file_t file = 0;
char buffer[MULTIBOOT_SEARCH], *cmdline = 0, *p;
char buffer[MULTIBOOT_SEARCH];
struct multiboot_header *header;
grub_ssize_t len, cmdline_length, boot_loader_name_length;
grub_uint32_t mmap_length;
int i;
int cmdline_argc;
char **cmdline_argv;
grub_ssize_t len;
grub_loader_unset ();
@ -274,31 +197,8 @@ grub_multiboot (int argc, char *argv[])
grub_relocator32_free (grub_multiboot_payload_orig);
grub_multiboot_payload_orig = NULL;
mmap_length = grub_get_multiboot_mmap_len ();
/* Figure out cmdline length. */
/* Skip filename. */
cmdline_argc = argc - 1;
cmdline_argv = argv + 1;
for (i = 0, cmdline_length = 0; i < cmdline_argc; i++)
cmdline_length += grub_strlen (cmdline_argv[i]) + 1;
if (cmdline_length == 0)
cmdline_length = 1;
boot_loader_name_length = sizeof(PACKAGE_STRING);
#define cmdline_addr(x) ((void *) ((x) + code_size))
#define boot_loader_name_addr(x) \
((void *) ((x) + code_size + cmdline_length))
#define mbi_addr(x) ((void *) ((x) + code_size + cmdline_length + boot_loader_name_length))
#define mmap_addr(x) ((void *) ((x) + code_size + cmdline_length + boot_loader_name_length + sizeof (struct multiboot_info)))
grub_multiboot_payload_size = cmdline_length
/* boot_loader_name_length might need to grow for mbi,etc to be aligned (see below) */
+ boot_loader_name_length + 3
+ sizeof (struct multiboot_info) + mmap_length;
grub_multiboot_init_mbi (argc - 1, argv + 1);
if (header->flags & MULTIBOOT_AOUT_KLUDGE)
{
@ -313,10 +213,12 @@ grub_multiboot (int argc, char *argv[])
code_size = load_size;
grub_multiboot_payload_dest = header->load_addr;
grub_multiboot_payload_size += code_size;
grub_multiboot_pure_size += code_size;
/* Allocate a bit more to avoid relocations in most cases. */
alloc_mbi = grub_multiboot_get_mbi_size () + 65536;
grub_multiboot_payload_orig
= grub_relocator32_alloc (grub_multiboot_payload_size);
= grub_relocator32_alloc (grub_multiboot_pure_size + alloc_mbi);
if (! grub_multiboot_payload_orig)
goto fail;
@ -338,53 +240,37 @@ grub_multiboot (int argc, char *argv[])
else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE)
goto fail;
/* This provides alignment for the MBI, the memory map and the backward relocator. */
boot_loader_name_length += (0x04 - ((unsigned long) mbi_addr (grub_multiboot_payload_dest) & 0x03));
mbi = mbi_addr (grub_multiboot_payload_orig);
mbi_dest = mbi_addr (grub_multiboot_payload_dest);
grub_memset (mbi, 0, sizeof (struct multiboot_info));
mbi->mmap_length = mmap_length;
grub_fill_multiboot_mmap (mmap_addr (grub_multiboot_payload_orig));
/* FIXME: grub_uint32_t will break for addresses above 4 GiB, but is mandated
by the spec. Is there something we can do about it? */
mbi->mmap_addr = (grub_uint32_t) mmap_addr (grub_multiboot_payload_dest);
mbi->flags |= MULTIBOOT_INFO_MEM_MAP;
/* Convert from bytes to kilobytes. */
mbi->mem_lower = grub_mmap_get_lower () / 1024;
mbi->mem_upper = grub_mmap_get_upper () / 1024;
mbi->flags |= MULTIBOOT_INFO_MEMORY;
cmdline = p = cmdline_addr (grub_multiboot_payload_orig);
if (! cmdline)
goto fail;
for (i = 0; i < cmdline_argc; i++)
if (header->flags & MULTIBOOT_VIDEO_MODE)
{
p = grub_stpcpy (p, cmdline_argv[i]);
*(p++) = ' ';
switch (header->mode_type)
{
case 1:
grub_env_set ("gfxpayload", "text");
break;
case 0:
{
char buf[sizeof ("XXXXXXXXXXxXXXXXXXXXXxXXXXXXXXXX,XXXXXXXXXXxXXXXXXXXXX,auto")];
if (header->depth && header->width && header->height)
grub_sprintf (buf, "%dx%dx%d,%dx%d,auto", header->width,
header->height, header->depth, header->width,
header->height);
else if (header->width && header->height)
grub_sprintf (buf, "%dx%d,auto", header->width, header->height);
else
grub_sprintf (buf, "auto");
grub_env_set ("gfxpayload", buf);
break;
}
}
}
/* Remove the space after the last word. */
if (p != cmdline)
p--;
*p = 0;
grub_multiboot_set_accepts_video (!!(header->flags & MULTIBOOT_VIDEO_MODE));
mbi->flags |= MULTIBOOT_INFO_CMDLINE;
mbi->cmdline = (grub_uint32_t) cmdline_addr (grub_multiboot_payload_dest);
grub_multiboot_set_bootdev ();
grub_strcpy (boot_loader_name_addr (grub_multiboot_payload_orig), PACKAGE_STRING);
mbi->flags |= MULTIBOOT_INFO_BOOT_LOADER_NAME;
mbi->boot_loader_name = (grub_uint32_t) boot_loader_name_addr (grub_multiboot_payload_dest);
if (grub_multiboot_get_bootdev (&mbi->boot_device))
mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1);
grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0);
fail:
if (file)
@ -392,22 +278,18 @@ grub_multiboot (int argc, char *argv[])
if (grub_errno != GRUB_ERR_NONE)
{
grub_free (cmdline);
grub_free (mbi);
grub_relocator32_free (grub_multiboot_payload_orig);
grub_dl_unref (my_mod);
}
}
void
grub_module (int argc, char *argv[])
{
grub_file_t file = 0;
grub_ssize_t size, len = 0;
char *module = 0, *cmdline = 0, *p;
int i;
int cmdline_argc;
char **cmdline_argv;
grub_ssize_t size;
char *module = 0;
grub_err_t err;
if (argc == 0)
{
@ -415,7 +297,7 @@ grub_module (int argc, char *argv[])
goto fail;
}
if (!mbi)
if (!grub_multiboot_payload_orig)
{
grub_error (GRUB_ERR_BAD_ARGUMENT,
"you need to load the multiboot kernel first");
@ -431,73 +313,19 @@ grub_module (int argc, char *argv[])
if (! module)
goto fail;
err = grub_multiboot_add_module ((grub_addr_t) module, size,
argc - 1, argv + 1);
if (err)
goto fail;
if (grub_file_read (file, module, size) != size)
{
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
goto fail;
}
/* Skip module name. */
cmdline_argc = argc - 1;
cmdline_argv = argv + 1;
for (i = 0; i < cmdline_argc; i++)
len += grub_strlen (cmdline_argv[i]) + 1;
if (len == 0)
len = 1;
cmdline = p = grub_malloc (len);
if (! cmdline)
goto fail;
for (i = 0; i < cmdline_argc; i++)
{
p = grub_stpcpy (p, cmdline_argv[i]);
*(p++) = ' ';
}
/* Remove the space after the last word. */
if (p != cmdline)
p--;
*p = '\0';
if (mbi->flags & MULTIBOOT_INFO_MODS)
{
struct multiboot_mod_list *modlist = (struct multiboot_mod_list *) mbi->mods_addr;
modlist = grub_realloc (modlist, (mbi->mods_count + 1)
* sizeof (struct multiboot_mod_list));
if (! modlist)
goto fail;
mbi->mods_addr = (grub_uint32_t) modlist;
modlist += mbi->mods_count;
modlist->mod_start = (grub_uint32_t) module;
modlist->mod_end = (grub_uint32_t) module + size;
modlist->cmdline = (grub_uint32_t) cmdline;
modlist->pad = 0;
mbi->mods_count++;
}
else
{
struct multiboot_mod_list *modlist = grub_zalloc (sizeof (struct multiboot_mod_list));
if (! modlist)
goto fail;
modlist->mod_start = (grub_uint32_t) module;
modlist->mod_end = (grub_uint32_t) module + size;
modlist->cmdline = (grub_uint32_t) cmdline;
mbi->mods_count = 1;
mbi->mods_addr = (grub_uint32_t) modlist;
mbi->flags |= MULTIBOOT_INFO_MODS;
}
fail:
if (file)
grub_file_close (file);
}
if (grub_errno != GRUB_ERR_NONE)
{
grub_free (module);
grub_free (cmdline);
}
}

View file

@ -100,10 +100,11 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
code_size = (phdr(highest_segment)->p_paddr + phdr(highest_segment)->p_memsz) - phdr(lowest_segment)->p_paddr;
grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr;
grub_multiboot_payload_size += code_size;
grub_multiboot_pure_size += code_size;
alloc_mbi = grub_multiboot_get_mbi_size ();
grub_multiboot_payload_orig
= grub_relocator32_alloc (grub_multiboot_payload_size);
= grub_relocator32_alloc (grub_multiboot_pure_size + alloc_mbi + 65536);
if (!grub_multiboot_payload_orig)
return grub_errno;

463
loader/i386/multiboot_mbi.c Normal file
View file

@ -0,0 +1,463 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,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/machine/memory.h>
#include <grub/memory.h>
#ifdef GRUB_MACHINE_PCBIOS
#include <grub/machine/biosnum.h>
#endif
#include <grub/multiboot.h>
#include <grub/cpu/multiboot.h>
#include <grub/disk.h>
#include <grub/device.h>
#include <grub/partition.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/env.h>
#include <grub/video.h>
#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
#include <grub/i386/pc/vbe.h>
#define DEFAULT_VIDEO_MODE "text"
#define HAS_VGA_TEXT 1
#else
#define DEFAULT_VIDEO_MODE "auto"
#define HAS_VGA_TEXT 0
#endif
struct module
{
struct module *next;
grub_addr_t start;
grub_size_t size;
char *cmdline;
int cmdline_size;
};
struct module *modules, *modules_last;
static grub_size_t cmdline_size;
static grub_size_t total_modcmd;
static unsigned modcnt;
static char *cmdline = NULL;
static grub_uint32_t bootdev;
static int bootdev_set;
static int accepts_video;
void
grub_multiboot_set_accepts_video (int val)
{
accepts_video = val;
}
/* Return the length of the Multiboot mmap that will be needed to allocate
our platform's map. */
static grub_uint32_t
grub_get_multiboot_mmap_len (void)
{
grub_size_t count = 0;
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
grub_uint64_t size __attribute__ ((unused)),
grub_uint32_t type __attribute__ ((unused)))
{
count++;
return 0;
}
grub_mmap_iterate (hook);
return count * sizeof (struct multiboot_mmap_entry);
}
grub_size_t
grub_multiboot_get_mbi_size (void)
{
return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4)
+ modcnt * sizeof (struct multiboot_mod_list) + total_modcmd
+ ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_len ()
+ 256 * sizeof (struct multiboot_color);
}
/* Fill previously allocated Multiboot mmap. */
static void
grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry)
{
struct multiboot_mmap_entry *mmap_entry = (struct multiboot_mmap_entry *) first_entry;
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)
{
mmap_entry->addr = addr;
mmap_entry->len = size;
switch (type)
{
case GRUB_MACHINE_MEMORY_AVAILABLE:
mmap_entry->type = MULTIBOOT_MEMORY_AVAILABLE;
break;
default:
mmap_entry->type = MULTIBOOT_MEMORY_RESERVED;
break;
}
mmap_entry->size = sizeof (struct multiboot_mmap_entry) - sizeof (mmap_entry->size);
mmap_entry++;
return 0;
}
grub_mmap_iterate (hook);
}
static grub_err_t
set_video_mode (void)
{
grub_err_t err;
const char *modevar;
if (accepts_video || !HAS_VGA_TEXT)
{
modevar = grub_env_get ("gfxpayload");
if (! modevar || *modevar == 0)
err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0);
else
{
char *tmp;
tmp = grub_malloc (grub_strlen (modevar)
+ sizeof (DEFAULT_VIDEO_MODE) + 1);
if (! tmp)
return grub_errno;
grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
err = grub_video_set_mode (tmp, 0, 0);
grub_free (tmp);
}
}
else
err = grub_video_set_mode ("text", 0, 0);
return err;
}
static grub_err_t
retrieve_video_parameters (struct multiboot_info *mbi,
grub_uint8_t *ptrorig, grub_uint32_t ptrdest)
{
grub_err_t err;
struct grub_video_mode_info mode_info;
void *framebuffer;
grub_video_driver_id_t driv_id;
struct grub_video_palette_data palette[256];
err = set_video_mode ();
if (err)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
}
grub_video_get_palette (0, ARRAY_SIZE (palette), palette);
driv_id = grub_video_get_driver_id ();
if (driv_id == GRUB_VIDEO_DRIVER_NONE)
return GRUB_ERR_NONE;
err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
if (err)
return err;
mbi->framebuffer_addr = (grub_addr_t) framebuffer;
mbi->framebuffer_pitch = mode_info.pitch;
mbi->framebuffer_width = mode_info.width;
mbi->framebuffer_height = mode_info.height;
mbi->framebuffer_bpp = mode_info.bpp;
if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
{
struct multiboot_color *mb_palette;
unsigned i;
mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED;
mbi->framebuffer_palette_addr = ptrdest;
mbi->framebuffer_palette_num_colors = mode_info.number_of_colors;
if (mbi->framebuffer_palette_num_colors > ARRAY_SIZE (palette))
mbi->framebuffer_palette_num_colors = ARRAY_SIZE (palette);
mb_palette = (struct multiboot_color *) ptrorig;
for (i = 0; i < mbi->framebuffer_palette_num_colors; i++)
{
mb_palette[i].red = palette[i].r;
mb_palette[i].green = palette[i].g;
mb_palette[i].blue = palette[i].b;
}
ptrorig += mbi->framebuffer_palette_num_colors
* sizeof (struct multiboot_color);
ptrdest += mbi->framebuffer_palette_num_colors
* sizeof (struct multiboot_color);
}
else
{
mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_RGB;
mbi->framebuffer_red_field_position = mode_info.green_field_pos;
mbi->framebuffer_red_mask_size = mode_info.green_mask_size;
mbi->framebuffer_green_field_position = mode_info.green_field_pos;
mbi->framebuffer_green_mask_size = mode_info.green_mask_size;
mbi->framebuffer_blue_field_position = mode_info.blue_field_pos;
mbi->framebuffer_blue_mask_size = mode_info.blue_mask_size;
}
mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO;
return GRUB_ERR_NONE;
}
grub_err_t
grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
grub_size_t bufsize)
{
grub_uint8_t *ptrorig = (grub_uint8_t *) orig + buf_off;
grub_uint32_t ptrdest = dest + buf_off;
struct multiboot_info *mbi;
struct multiboot_mod_list *modlist;
unsigned i;
struct module *cur;
grub_size_t mmap_size;
grub_err_t err;
if (bufsize < grub_multiboot_get_mbi_size ())
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small");
mbi = (struct multiboot_info *) ptrorig;
ptrorig += sizeof (*mbi);
ptrdest += sizeof (*mbi);
grub_memset (mbi, 0, sizeof (*mbi));
grub_memcpy (ptrorig, cmdline, cmdline_size);
mbi->flags |= MULTIBOOT_INFO_CMDLINE;
mbi->cmdline = ptrdest;
ptrorig += ALIGN_UP (cmdline_size, 4);
ptrdest += ALIGN_UP (cmdline_size, 4);
grub_memcpy (ptrorig, PACKAGE_STRING, sizeof(PACKAGE_STRING));
mbi->flags |= MULTIBOOT_INFO_BOOT_LOADER_NAME;
mbi->boot_loader_name = ptrdest;
ptrorig += ALIGN_UP (sizeof(PACKAGE_STRING), 4);
ptrdest += ALIGN_UP (sizeof(PACKAGE_STRING), 4);
if (modcnt)
{
mbi->flags |= MULTIBOOT_INFO_MODS;
mbi->mods_addr = ptrdest;
mbi->mods_count = modcnt;
modlist = (struct multiboot_mod_list *) ptrorig;
ptrorig += modcnt * sizeof (struct multiboot_mod_list);
ptrdest += modcnt * sizeof (struct multiboot_mod_list);
for (i = 0, cur = modules; i < modcnt; i++, cur = cur->next)
{
modlist[i].mod_start = cur->start;
modlist[i].mod_end = modlist[i].mod_start + cur->size;
modlist[i].cmdline = ptrdest;
grub_memcpy (ptrorig, cur->cmdline, cur->cmdline_size);
ptrorig += ALIGN_UP (cur->cmdline_size, 4);
ptrdest += ALIGN_UP (cur->cmdline_size, 4);
}
}
else
{
mbi->mods_addr = 0;
mbi->mods_count = 0;
}
mmap_size = grub_get_multiboot_mmap_len ();
grub_fill_multiboot_mmap ((struct multiboot_mmap_entry *) ptrorig);
mbi->mmap_length = mmap_size;
mbi->mmap_addr = ptrdest;
mbi->flags |= MULTIBOOT_INFO_MEM_MAP;
ptrorig += mmap_size;
ptrdest += mmap_size;
/* Convert from bytes to kilobytes. */
mbi->mem_lower = grub_mmap_get_lower () / 1024;
mbi->mem_upper = grub_mmap_get_upper () / 1024;
mbi->flags |= MULTIBOOT_INFO_MEMORY;
if (bootdev_set)
{
mbi->boot_device = bootdev;
mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
}
err = retrieve_video_parameters (mbi, ptrorig, ptrdest);
if (err)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
}
return GRUB_ERR_NONE;
}
void
grub_multiboot_free_mbi (void)
{
struct module *cur, *next;
cmdline_size = 0;
total_modcmd = 0;
modcnt = 0;
grub_free (cmdline);
cmdline = NULL;
bootdev_set = 0;
for (cur = modules; cur; cur = next)
{
next = cur->next;
grub_free (cur->cmdline);
grub_free (cur);
}
modules = NULL;
modules_last = NULL;
}
grub_err_t
grub_multiboot_init_mbi (int argc, char *argv[])
{
grub_ssize_t len = 0;
char *p;
int i;
grub_multiboot_free_mbi ();
for (i = 0; i < argc; i++)
len += grub_strlen (argv[i]) + 1;
if (len == 0)
len = 1;
cmdline = p = grub_malloc (len);
if (! cmdline)
return grub_errno;
cmdline_size = len;
for (i = 0; i < argc; i++)
{
p = grub_stpcpy (p, argv[i]);
*(p++) = ' ';
}
/* Remove the space after the last word. */
if (p != cmdline)
p--;
*p = '\0';
return GRUB_ERR_NONE;
}
grub_err_t
grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
int argc, char *argv[])
{
struct module *newmod;
char *p;
grub_ssize_t len = 0;
int i;
newmod = grub_malloc (sizeof (*newmod));
if (!newmod)
return grub_errno;
newmod->start = start;
newmod->size = size;
for (i = 0; i < argc; i++)
len += grub_strlen (argv[i]) + 1;
if (len == 0)
len = 1;
newmod->cmdline = p = grub_malloc (len);
if (! newmod->cmdline)
{
grub_free (newmod);
return grub_errno;
}
newmod->cmdline_size = len;
total_modcmd += ALIGN_UP (len, 4);
for (i = 0; i < argc; i++)
{
p = grub_stpcpy (p, argv[i]);
*(p++) = ' ';
}
/* Remove the space after the last word. */
if (p != newmod->cmdline)
p--;
*p = '\0';
if (modules_last)
modules_last->next = newmod;
else
{
modules = newmod;
modules_last->next = NULL;
}
modules_last = newmod;
modcnt++;
return GRUB_ERR_NONE;
}
void
grub_multiboot_set_bootdev (void)
{
char *p;
grub_uint32_t biosdev, slice = ~0, part = ~0;
grub_device_t dev;
#ifdef GRUB_MACHINE_PCBIOS
biosdev = grub_get_root_biosnumber ();
#else
biosdev = 0xffffffff;
#endif
dev = grub_device_open (0);
if (dev && dev->disk && dev->disk->partition)
{
p = dev->disk->partition->partmap->get_name (dev->disk->partition);
if (p)
{
if ((p[0] >= '0') && (p[0] <= '9'))
{
slice = grub_strtoul (p, &p, 0) - 1;
if ((p) && (p[0] == ','))
p++;
}
if ((p[0] >= 'a') && (p[0] <= 'z'))
part = p[0] - 'a';
}
}
if (dev)
grub_device_close (dev);
bootdev = ((biosdev & 0xff) << 24) | ((slice & 0xff) << 16)
| ((part & 0xff) << 8) | 0xff;
bootdev_set = 1;
}

View file

@ -1,7 +1,7 @@
/* chainloader.c - boot another boot loader */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2002,2004,2007,2009 Free Software Foundation, Inc.
* Copyright (C) 2002,2004,2007,2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -32,6 +32,9 @@
#include <grub/dl.h>
#include <grub/command.h>
#include <grub/machine/biosnum.h>
#include <grub/i18n.h>
#include <grub/video.h>
#include <grub/mm.h>
static grub_dl_t my_mod;
static int boot_drive;
@ -40,6 +43,7 @@ static void *boot_part_addr;
static grub_err_t
grub_chainloader_boot (void)
{
grub_video_set_mode ("text", 0, 0);
grub_chainloader_real_boot (boot_drive, boot_part_addr);
/* Never reach here. */
@ -146,7 +150,7 @@ static grub_command_t cmd;
GRUB_MOD_INIT(chainloader)
{
cmd = grub_register_command ("chainloader", grub_cmd_chainloader,
0, "Load another boot loader.");
0, N_("Load another boot loader."));
my_mod = mod;
}

View file

@ -1,7 +1,7 @@
/* linux.c - boot Linux zImage or bzImage */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
* Copyright (C) 1999,2000,2001,2002,2003,2004,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
@ -30,6 +30,9 @@
#include <grub/dl.h>
#include <grub/cpu/linux.h>
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/mm.h>
#include <grub/video.h>
#define GRUB_LINUX_CL_OFFSET 0x9000
#define GRUB_LINUX_CL_END_OFFSET 0x90FF
@ -47,6 +50,16 @@ grub_linux_unload (void)
return GRUB_ERR_NONE;
}
static grub_err_t
grub_linux16_boot (void)
{
grub_video_set_mode ("text", 0, 0);
grub_linux16_real_boot ();
/* Not reached. */
return GRUB_ERR_NONE;
}
static grub_err_t
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
@ -81,7 +94,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
{
grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux header");
grub_error (GRUB_ERR_READ_ERROR, "cannot read the Linux header");
goto fail;
}
@ -383,10 +396,10 @@ GRUB_MOD_INIT(linux16)
{
cmd_linux =
grub_register_command ("linux16", grub_cmd_linux,
0, "Load Linux.");
0, N_("Load Linux."));
cmd_initrd =
grub_register_command ("initrd16", grub_cmd_initrd,
0, "Load initrd.");
0, N_("Load initrd."));
my_mod = mod;
}

View file

@ -1,122 +0,0 @@
/* multiboot2.c - boot a multiboot 2 OS image. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/multiboot2.h>
#include <multiboot2.h>
#include <grub/elf.h>
#include <grub/err.h>
#include <grub/machine/loader.h>
#include <grub/mm.h>
#include <grub/multiboot.h>
#include <grub/cpu/multiboot.h>
grub_err_t
grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr,
grub_addr_t *addr __attribute__ ((unused)),
int *do_load)
{
Elf32_Addr paddr = phdr->p_paddr;
if (phdr->p_type != PT_LOAD)
{
*do_load = 0;
return 0;
}
*do_load = 1;
if ((paddr < grub_os_area_addr)
|| (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
return grub_error(GRUB_ERR_OUT_OF_RANGE,"address 0x%x is out of range",
paddr);
return GRUB_ERR_NONE;
}
grub_err_t
grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr,
grub_addr_t *addr __attribute__ ((unused)),
int *do_load)
{
Elf64_Addr paddr = phdr->p_paddr;
if (phdr->p_type != PT_LOAD)
{
*do_load = 0;
return 0;
}
*do_load = 1;
if ((paddr < grub_os_area_addr)
|| (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
return grub_error (GRUB_ERR_OUT_OF_RANGE, "address 0x%x is out of range",
paddr);
return GRUB_ERR_NONE;
}
grub_err_t
grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
{
grub_addr_t modaddr;
modaddr = (grub_addr_t) grub_memalign (MULTIBOOT2_MOD_ALIGN, size);
if (! modaddr)
return grub_errno;
*addr = modaddr;
return GRUB_ERR_NONE;
}
grub_err_t
grub_mb2_arch_module_free (grub_addr_t addr,
grub_size_t size __attribute__ ((unused)))
{
grub_free((void *) addr);
return GRUB_ERR_NONE;
}
void
grub_mb2_arch_boot (grub_addr_t entry, void *tags)
{
grub_multiboot2_real_boot (entry, tags);
}
void
grub_mb2_arch_unload (struct multiboot2_tag_header *tags)
{
struct multiboot2_tag_header *tag;
/* Free all module memory in the tag list. */
for_each_tag (tag, tags)
{
if (tag->key == MULTIBOOT2_TAG_MODULE)
{
struct multiboot2_tag_module *module =
(struct multiboot2_tag_module *) tag;
grub_free((void *) module->addr);
}
}
}
grub_err_t
grub_mb2_tags_arch_create (void)
{
/* XXX Create boot device et al. */
return GRUB_ERR_NONE;
}

View file

@ -26,16 +26,7 @@
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define DEFAULT_VIDEO_MODE "1024x768x32,800x600x32,640x480x32"
static int NESTED_FUNC_ATTR video_hook (grub_video_adapter_t p __attribute__ ((unused)),
struct grub_video_mode_info *info)
{
if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT)
return 0;
return 1;
}
#define DEFAULT_VIDEO_MODE "auto"
/* Setup video for xnu. */
grub_err_t
@ -48,8 +39,12 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
grub_err_t err;
modevar = grub_env_get ("gfxpayload");
/* Consider only graphical 32-bit deep modes. */
if (! modevar || *modevar == 0)
err = grub_video_set_mode (DEFAULT_VIDEO_MODE, video_hook);
err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
GRUB_VIDEO_MODE_TYPE_PURE_TEXT
| GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
else
{
tmp = grub_malloc (grub_strlen (modevar)
@ -58,7 +53,10 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't allocate temporary storag");
grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
err = grub_video_set_mode (tmp, video_hook);
err = grub_video_set_mode (tmp,
GRUB_VIDEO_MODE_TYPE_PURE_TEXT
| GRUB_VIDEO_MODE_TYPE_DEPTH_MASK,
32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS);
grub_free (tmp);
}

View file

@ -32,6 +32,7 @@
#include <grub/term.h>
#include <grub/command.h>
#include <grub/gzio.h>
#include <grub/i18n.h>
char grub_xnu_cmdline[1024];
grub_uint32_t grub_xnu_heap_will_be_at;
@ -1026,7 +1027,7 @@ grub_cpu_xnu_init (void)
{
cmd_devprop_load = grub_register_command ("xnu_devprop_load",
grub_cmd_devprop_load,
0, "Load device-properties dump.");
0, N_("Load device-properties dump."));
}
void

View file

@ -26,6 +26,7 @@
#include <grub/misc.h>
#include <grub/gzio.h>
#include <grub/command.h>
#include <grub/i18n.h>
grub_dl_t my_mod;
@ -129,15 +130,15 @@ GRUB_MOD_INIT(multiboot)
cmd_multiboot =
#ifdef GRUB_USE_MULTIBOOT2
grub_register_command ("multiboot2", grub_cmd_multiboot_loader,
0, "Load a multiboot 2 kernel.");
0, N_("Load a multiboot 2 kernel."));
#else
grub_register_command ("multiboot", grub_cmd_multiboot_loader,
0, "Load a multiboot kernel.");
0, N_("Load a multiboot kernel."));
#endif
cmd_module =
grub_register_command ("module", grub_cmd_module_loader,
0, "Load a multiboot module.");
0, N_("Load a multiboot module."));
my_mod = mod;
}

View file

@ -26,6 +26,7 @@
#include <grub/ieee1275/ieee1275.h>
#include <grub/machine/loader.h>
#include <grub/command.h>
#include <grub/i18n.h>
#define ELF32_LOADMASK (0xc0000000UL)
#define ELF64_LOADMASK (0xc000000000000000ULL)
@ -349,9 +350,9 @@ static grub_command_t cmd_linux, cmd_initrd;
GRUB_MOD_INIT(linux)
{
cmd_linux = grub_register_command ("linux", grub_cmd_linux,
0, "Load Linux.");
0, N_("Load Linux."));
cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
0, "Load initrd.");
0, N_("Load initrd."));
my_mod = mod;
}

View file

@ -27,6 +27,7 @@
#include <grub/machine/loader.h>
#include <grub/gzio.h>
#include <grub/command.h>
#include <grub/i18n.h>
static grub_dl_t my_mod;
@ -263,7 +264,7 @@ grub_linux_load64 (grub_elf_t elf)
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't map physical memory");
grub_dprintf ("loader", "Loading linux at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n",
grub_dprintf ("loader", "Loading Linux at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n",
linux_addr, paddr, linux_size);
linux_paddr = paddr;
@ -516,9 +517,9 @@ GRUB_MOD_INIT(linux)
fetch_translations ();
cmd_linux = grub_register_command ("linux", grub_cmd_linux,
0, "Load Linux.");
0, N_("Load Linux."));
cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
0, "Load initrd.");
0, N_("Load initrd."));
my_mod = mod;
}

View file

@ -32,6 +32,7 @@
#include <grub/command.h>
#include <grub/misc.h>
#include <grub/env.h>
#include <grub/i18n.h>
struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0;
static int driverspackagenum = 0;
@ -1404,25 +1405,25 @@ static grub_command_t cmd_kextdir, cmd_ramdisk, cmd_resume, cmd_splash;
GRUB_MOD_INIT(xnu)
{
cmd_kernel = grub_register_command ("xnu_kernel", grub_cmd_xnu_kernel, 0,
"Load XNU image.");
N_("Load XNU image."));
cmd_kernel64 = grub_register_command ("xnu_kernel64", grub_cmd_xnu_kernel64,
0, "Load 64-bit XNU image.");
0, N_("Load 64-bit XNU image."));
cmd_mkext = grub_register_command ("xnu_mkext", grub_cmd_xnu_mkext, 0,
"Load XNU extension package.");
N_("Load XNU extension package."));
cmd_kext = grub_register_command ("xnu_kext", grub_cmd_xnu_kext, 0,
"Load XNU extension.");
N_("Load XNU extension."));
cmd_kextdir = grub_register_command ("xnu_kextdir", grub_cmd_xnu_kextdir,
"DIRECTORY [OSBundleRequired]",
"Load XNU extension directory.");
N_("DIRECTORY [OSBundleRequired]"),
N_("Load XNU extension directory."));
cmd_ramdisk = grub_register_command ("xnu_ramdisk", grub_cmd_xnu_ramdisk, 0,
"Load XNU ramdisk. "
"It will be seen as md0.");
N_("Load XNU ramdisk. "
"It will be seen as md0."));
cmd_splash = grub_register_command ("xnu_splash", grub_cmd_xnu_splash, 0,
"Load a splash image for XNU.");
N_("Load a splash image for XNU."));
#ifndef GRUB_UTIL
cmd_resume = grub_register_command ("xnu_resume", grub_cmd_xnu_resume,
0, "Load XNU hibernate image.");
0, N_("Load XNU hibernate image."));
#endif
grub_cpu_xnu_init ();

View file

@ -154,6 +154,49 @@ is_authenticated (const char *userlist)
return grub_list_iterate (GRUB_AS_LIST (users), hook);
}
static int
grub_username_get (char buf[], unsigned buf_size)
{
unsigned cur_len = 0;
int key;
while (1)
{
key = GRUB_TERM_ASCII_CHAR (grub_getkey ());
if (key == '\n' || key == '\r')
break;
if (key == '\e')
{
cur_len = 0;
break;
}
if (key == '\b')
{
cur_len--;
grub_printf ("\b");
continue;
}
if (!grub_isprint (key))
continue;
if (cur_len + 2 < buf_size)
{
buf[cur_len++] = key;
grub_putchar (key);
}
}
grub_memset (buf + cur_len, 0, buf_size - cur_len);
grub_putchar ('\n');
grub_refresh ();
return (key != '\e');
}
grub_err_t
grub_auth_check_authentication (const char *userlist)
{
@ -187,11 +230,12 @@ grub_auth_check_authentication (const char *userlist)
return GRUB_ERR_NONE;
}
if (!grub_cmdline_get (N_("Enter username:"), login, sizeof (login) - 1,
0, 0, 0))
grub_puts_ (N_("Enter username: "));
if (!grub_username_get (login, sizeof (login) - 1))
goto access_denied;
grub_printf ("Enter password: ");
grub_puts_ (N_("Enter password: "));
if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
goto access_denied;

View file

@ -27,11 +27,12 @@
#include <grub/file.h>
#include <grub/env.h>
#include <grub/i18n.h>
#include <grub/charset.h>
static char *kill_buf;
static grub_uint32_t *kill_buf;
static int hist_size;
static char **hist_lines = 0;
static grub_uint32_t **hist_lines = 0;
static int hist_pos = 0;
static int hist_end = 0;
static int hist_used = 0;
@ -39,8 +40,8 @@ static int hist_used = 0;
grub_err_t
grub_set_history (int newsize)
{
char **old_hist_lines = hist_lines;
hist_lines = grub_malloc (sizeof (char *) * newsize);
grub_uint32_t **old_hist_lines = hist_lines;
hist_lines = grub_malloc (sizeof (grub_uint32_t *) * newsize);
/* Copy the old lines into the new buffer. */
if (old_hist_lines)
@ -67,16 +68,16 @@ grub_set_history (int newsize)
if (hist_pos < hist_end)
grub_memmove (hist_lines, old_hist_lines + hist_pos,
(hist_end - hist_pos) * sizeof (char *));
(hist_end - hist_pos) * sizeof (grub_uint32_t *));
else if (hist_used)
{
/* Copy the older part. */
grub_memmove (hist_lines, old_hist_lines + hist_pos,
(hist_size - hist_pos) * sizeof (char *));
(hist_size - hist_pos) * sizeof (grub_uint32_t *));
/* Copy the newer part. */
grub_memmove (hist_lines + hist_size - hist_pos, old_hist_lines,
hist_end * sizeof (char *));
hist_end * sizeof (grub_uint32_t *));
}
}
@ -90,17 +91,43 @@ grub_set_history (int newsize)
/* Get the entry POS from the history where `0' is the newest
entry. */
static char *
static grub_uint32_t *
grub_history_get (int pos)
{
pos = (hist_pos + pos) % hist_size;
return hist_lines[pos];
}
static grub_size_t
strlen_ucs4 (const grub_uint32_t *s)
{
const grub_uint32_t *p = s;
while (*p)
p++;
return p - s;
}
/* Replace the history entry on position POS with the string S. */
static void
grub_history_set (int pos, grub_uint32_t *s, grub_size_t len)
{
grub_free (hist_lines[pos]);
hist_lines[pos] = grub_malloc ((len + 1) * sizeof (grub_uint32_t));
if (!hist_lines[pos])
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
return ;
}
grub_memcpy (hist_lines[pos], s, len * sizeof (grub_uint32_t));
hist_lines[pos][len] = 0;
}
/* Insert a new history line S on the top of the history. */
static void
grub_history_add (char *s)
grub_history_add (grub_uint32_t *s, grub_size_t len)
{
/* Remove the oldest entry in the history to make room for a new
entry. */
@ -121,16 +148,15 @@ grub_history_add (char *s)
hist_pos = hist_size + hist_pos;
/* Insert into history. */
hist_lines[hist_pos] = grub_strdup (s);
hist_lines[hist_pos] = NULL;
grub_history_set (hist_pos, s, len);
}
/* Replace the history entry on position POS with the string S. */
static void
grub_history_replace (int pos, char *s)
grub_history_replace (int pos, grub_uint32_t *s, grub_size_t len)
{
pos = (hist_pos + pos) % hist_size;
grub_free (hist_lines[pos]);
hist_lines[pos] = grub_strdup (s);
grub_history_set ((hist_pos + pos) % hist_size, s, len);
}
/* A completion hook to print items. */
@ -140,31 +166,30 @@ print_completion (const char *item, grub_completion_type_t type, int count)
if (count == 0)
{
/* If this is the first time, print a label. */
const char *what;
grub_puts ("");
switch (type)
{
case GRUB_COMPLETION_TYPE_COMMAND:
what = "commands";
grub_puts_ (N_("Possible commands are:"));
break;
case GRUB_COMPLETION_TYPE_DEVICE:
what = "devices";
grub_puts_ (N_("Possible devices are:"));
break;
case GRUB_COMPLETION_TYPE_FILE:
what = "files";
grub_puts_ (N_("Possible files are:"));
break;
case GRUB_COMPLETION_TYPE_PARTITION:
what = "partitions";
grub_puts_ (N_("Possible partitions are:"));
break;
case GRUB_COMPLETION_TYPE_ARGUMENT:
what = "arguments";
grub_puts_ (N_("Possible arguments are:"));
break;
default:
what = "things";
grub_puts_ (N_("Possible things are:"));
break;
}
grub_printf ("\nPossible %s are:\n", what);
grub_puts ("");
}
if (type == GRUB_COMPLETION_TYPE_PARTITION)
@ -176,75 +201,112 @@ print_completion (const char *item, grub_completion_type_t type, int count)
grub_printf (" %s", item);
}
/* Get a command-line. If ECHO_CHAR is not zero, echo it instead of input
characters. If READLINE is non-zero, readline-like key bindings are
available. If ESC is pushed, return zero, otherwise return non-zero. */
/* FIXME: The dumb interface is not supported yet. */
int
grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
int echo_char, int readline, int history)
struct cmdline_term
{
unsigned xpos, ypos, ystart, width, height;
struct grub_term_output *term;
};
/* Get a command-line. If ESC is pushed, return zero,
otherwise return command line. */
/* FIXME: The dumb interface is not supported yet. */
char *
grub_cmdline_get (const char *prompt)
{
unsigned xpos, ypos, ystart;
grub_size_t lpos, llen;
grub_size_t plen;
char buf[max_len];
grub_uint32_t *buf;
grub_size_t max_len = 256;
int key;
int histpos = 0;
auto void cl_insert (const char *str);
auto void cl_insert (const grub_uint32_t *str);
auto void cl_delete (unsigned len);
auto void cl_print (int pos, int c);
auto void cl_set_pos (void);
auto inline void __attribute__ ((always_inline)) cl_print (struct cmdline_term *cl_term, int pos,
grub_uint32_t c);
auto void cl_set_pos (struct cmdline_term *cl_term);
auto void cl_print_all (int pos, grub_uint32_t c);
auto void cl_set_pos_all (void);
auto void init_clterm (struct cmdline_term *cl_term_cur);
auto void init_clterm_all (void);
const char *prompt_translated = _(prompt);
struct cmdline_term *cl_terms;
char *ret;
unsigned nterms;
void cl_set_pos (void)
void cl_set_pos (struct cmdline_term *cl_term)
{
xpos = (plen + lpos) % 79;
ypos = ystart + (plen + lpos) / 79;
grub_gotoxy (xpos, ypos);
grub_refresh ();
cl_term->xpos = (plen + lpos) % (cl_term->width - 1);
cl_term->ypos = cl_term->ystart + (plen + lpos) / (cl_term->width - 1);
grub_term_gotoxy (cl_term->term, cl_term->xpos, cl_term->ypos);
}
void cl_print (int pos, int c)
void cl_set_pos_all ()
{
char *p;
for (p = buf + pos; *p; p++)
{
if (xpos++ > 78)
{
grub_putchar ('\n');
xpos = 1;
if (ypos == (unsigned) (grub_getxy () & 0xFF))
ystart--;
else
ypos++;
unsigned i;
for (i = 0; i < nterms; i++)
cl_set_pos (&cl_terms[i]);
}
inline void __attribute__ ((always_inline)) cl_print (struct cmdline_term *cl_term, int pos, grub_uint32_t c)
{
grub_uint32_t *p;
for (p = buf + pos; p < buf + llen; p++)
{
if (c)
grub_putchar (c);
grub_putcode (c, cl_term->term);
else
grub_putchar (*p);
grub_putcode (*p, cl_term->term);
cl_term->xpos++;
if (cl_term->xpos >= cl_term->width - 1)
{
cl_term->xpos = 0;
if (cl_term->ypos >= (unsigned) (cl_term->height - 1))
cl_term->ystart--;
else
cl_term->ypos++;
grub_putcode ('\n', cl_term->term);
}
}
}
void cl_insert (const char *str)
void cl_print_all (int pos, grub_uint32_t c)
{
grub_size_t len = grub_strlen (str);
unsigned i;
for (i = 0; i < nterms; i++)
cl_print (&cl_terms[i], pos, c);
}
void cl_insert (const grub_uint32_t *str)
{
grub_size_t len = strlen_ucs4 (str);
if (len + llen >= max_len)
{
grub_uint32_t *nbuf;
max_len *= 2;
nbuf = grub_realloc (buf, sizeof (grub_uint32_t) * max_len);
if (nbuf)
buf = nbuf;
else
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
max_len /= 2;
}
}
if (len + llen < max_len)
{
grub_memmove (buf + lpos + len, buf + lpos, llen - lpos + 1);
grub_memmove (buf + lpos, str, len);
grub_memmove (buf + lpos + len, buf + lpos,
(llen - lpos + 1) * sizeof (grub_uint32_t));
grub_memmove (buf + lpos, str, len * sizeof (grub_uint32_t));
llen += len;
lpos += len;
cl_print (lpos - len, echo_char);
cl_set_pos ();
cl_print_all (lpos - len, 0);
cl_set_pos_all ();
}
grub_refresh ();
}
void cl_delete (unsigned len)
@ -254,96 +316,157 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
grub_size_t saved_lpos = lpos;
lpos = llen - len;
cl_set_pos ();
cl_print (lpos, ' ');
cl_set_pos_all ();
cl_print_all (lpos, ' ');
lpos = saved_lpos;
cl_set_pos ();
cl_set_pos_all ();
grub_memmove (buf + lpos, buf + lpos + len, llen - lpos + 1);
grub_memmove (buf + lpos, buf + lpos + len,
sizeof (grub_uint32_t) * (llen - lpos + 1));
llen -= len;
cl_print (lpos, echo_char);
cl_set_pos ();
cl_print_all (lpos, 0);
cl_set_pos_all ();
}
}
grub_refresh ();
void init_clterm (struct cmdline_term *cl_term_cur)
{
cl_term_cur->xpos = plen;
cl_term_cur->ypos = (grub_term_getxy (cl_term_cur->term) & 0xFF);
cl_term_cur->ystart = cl_term_cur->ypos;
cl_term_cur->width = grub_term_width (cl_term_cur->term);
cl_term_cur->height = grub_term_height (cl_term_cur->term);
}
void init_clterm_all (void)
{
unsigned i;
for (i = 0; i < nterms; i++)
init_clterm (&cl_terms[i]);
}
buf = grub_malloc (max_len * sizeof (grub_uint32_t));
if (!buf)
return 0;
plen = grub_strlen (prompt_translated) + sizeof (" ") - 1;
lpos = llen = 0;
buf[0] = '\0';
if ((grub_getxy () >> 8) != 0)
grub_putchar ('\n');
{
grub_term_output_t term;
FOR_ACTIVE_TERM_OUTPUTS(term)
if ((grub_term_getxy (term) >> 8) != 0)
grub_putcode ('\n', term);
}
grub_printf ("%s ", prompt_translated);
xpos = plen;
ystart = ypos = (grub_getxy () & 0xFF);
{
struct cmdline_term *cl_term_cur;
struct grub_term_output *cur;
nterms = 0;
FOR_ACTIVE_TERM_OUTPUTS(cur)
nterms++;
cl_insert (cmdline);
cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms);
if (!cl_terms)
return 0;
cl_term_cur = cl_terms;
FOR_ACTIVE_TERM_OUTPUTS(cur)
{
cl_term_cur->term = cur;
init_clterm (cl_term_cur);
cl_term_cur++;
}
}
if (history && hist_used == 0)
grub_history_add (buf);
if (hist_used == 0)
grub_history_add (buf, llen);
while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r')
{
if (readline)
{
switch (key)
{
case 1: /* Ctrl-a */
lpos = 0;
cl_set_pos ();
cl_set_pos_all ();
break;
case 2: /* Ctrl-b */
if (lpos > 0)
{
lpos--;
cl_set_pos ();
cl_set_pos_all ();
}
break;
case 5: /* Ctrl-e */
lpos = llen;
cl_set_pos ();
cl_set_pos_all ();
break;
case 6: /* Ctrl-f */
if (lpos < llen)
{
lpos++;
cl_set_pos ();
cl_set_pos_all ();
}
break;
case 9: /* Ctrl-i or TAB */
{
char *insert;
int restore;
char *insertu8;
char *bufu8;
/* Backup the next character and make it 0 so it will
be easy to use string functions. */
char backup = buf[lpos];
buf[lpos] = '\0';
bufu8 = grub_ucs4_to_utf8_alloc (buf, lpos);
if (!bufu8)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
break;
}
insert = grub_normal_do_completion (buf, &restore,
insertu8 = grub_normal_do_completion (bufu8, &restore,
print_completion);
/* Restore the original string. */
buf[lpos] = backup;
grub_free (bufu8);
if (restore)
{
/* Restore the prompt. */
grub_printf ("\n%s %s", prompt_translated, buf);
xpos = plen;
ystart = ypos = (grub_getxy () & 0xFF);
grub_printf ("\n%s ", prompt_translated);
init_clterm_all ();
cl_print_all (0, 0);
}
if (insert)
if (insertu8)
{
grub_size_t insertlen;
grub_ssize_t t;
grub_uint32_t *insert;
insertlen = grub_strlen (insertu8);
insert = grub_malloc ((insertlen + 1) * sizeof (grub_uint32_t));
if (!insert)
{
grub_free (insertu8);
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
break;
}
t = grub_utf8_to_ucs4 (insert, insertlen,
(grub_uint8_t *) insertu8,
insertlen, 0);
if (t > 0)
{
insert[t] = 0;
cl_insert (insert);
}
grub_free (insertu8);
grub_free (insert);
}
}
@ -355,8 +478,19 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
if (kill_buf)
grub_free (kill_buf);
kill_buf = grub_strdup (buf + lpos);
kill_buf = grub_malloc ((llen - lpos + 1)
* sizeof (grub_uint32_t));
if (grub_errno)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
}
else
{
grub_memcpy (kill_buf, buf + lpos,
(llen - lpos + 1) * sizeof (grub_uint32_t));
kill_buf[llen - lpos] = 0;
}
cl_delete (llen - lpos);
}
@ -364,13 +498,13 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
case 14: /* Ctrl-n */
{
char *hist;
grub_uint32_t *hist;
lpos = 0;
if (histpos > 0)
{
grub_history_replace (histpos, buf);
grub_history_replace (histpos, buf, llen);
histpos--;
}
@ -382,13 +516,13 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
}
case 16: /* Ctrl-p */
{
char *hist;
grub_uint32_t *hist;
lpos = 0;
if (histpos < hist_used - 1)
{
grub_history_replace (histpos, buf);
grub_history_replace (histpos, buf, llen);
histpos++;
}
@ -408,7 +542,11 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
grub_free (kill_buf);
kill_buf = grub_malloc (n + 1);
if (grub_errno)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
}
if (kill_buf)
{
grub_memcpy (kill_buf, buf, n);
@ -416,7 +554,7 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
}
lpos = 0;
cl_set_pos ();
cl_set_pos_all ();
cl_delete (n);
}
break;
@ -425,11 +563,7 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
if (kill_buf)
cl_insert (kill_buf);
break;
}
}
switch (key)
{
case '\e':
return 0;
@ -437,7 +571,7 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
if (lpos > 0)
{
lpos--;
cl_set_pos ();
cl_set_pos_all ();
}
else
break;
@ -451,7 +585,7 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
default:
if (grub_isprint (key))
{
char str[2];
grub_uint32_t str[2];
str[0] = key;
str[1] = '\0';
@ -459,28 +593,26 @@ grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len,
}
break;
}
grub_refresh ();
}
grub_putchar ('\n');
grub_refresh ();
/* If ECHO_CHAR is NUL, remove leading spaces. */
/* Remove leading spaces. */
lpos = 0;
if (! echo_char)
while (buf[lpos] == ' ')
lpos++;
if (history)
{
histpos = 0;
if (grub_strlen (buf) > 0)
if (strlen_ucs4 (buf) > 0)
{
grub_history_replace (histpos, buf);
grub_history_add ("");
}
grub_uint32_t empty[] = { 0 };
grub_history_replace (histpos, buf, llen);
grub_history_add (empty, 0);
}
grub_memcpy (cmdline, buf + lpos, llen - lpos + 1);
return 1;
ret = grub_ucs4_to_utf8_alloc (buf + lpos, llen - lpos + 1);
grub_free (buf);
return ret;
}

View file

@ -103,23 +103,31 @@ free_and_return:
grub_free (fg_name);
}
static grub_uint8_t color_normal, color_highlight;
static void
set_colors (void)
{
struct grub_term_output *term;
FOR_ACTIVE_TERM_OUTPUTS(term)
{
/* Reloads terminal `normal' and `highlight' colors. */
grub_term_setcolor (term, color_normal, color_highlight);
/* Propagates `normal' color to terminal current color. */
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
}
}
/* Replace default `normal' colors with the ones specified by user (if any). */
char *
grub_env_write_color_normal (struct grub_env_var *var __attribute__ ((unused)),
const char *val)
{
grub_uint8_t color_normal, color_highlight;
/* Use old settings in case grub_parse_color_name_pair() has no effect. */
grub_getcolor (&color_normal, &color_highlight);
grub_parse_color_name_pair (&color_normal, val);
/* Reloads terminal `normal' and `highlight' colors. */
grub_setcolor (color_normal, color_highlight);
/* Propagates `normal' color to terminal current color. */
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
set_colors ();
return grub_strdup (val);
}
@ -129,21 +137,9 @@ char *
grub_env_write_color_highlight (struct grub_env_var *var __attribute__ ((unused)),
const char *val)
{
grub_uint8_t color_normal, color_highlight;
/* Use old settings in case grub_parse_color_name_pair() has no effect. */
grub_getcolor (&color_normal, &color_highlight);
grub_parse_color_name_pair (&color_highlight, val);
/* Reloads terminal `normal' and `highlight' colors. */
grub_setcolor (color_normal, color_highlight);
/* Propagates `normal' color to terminal current color.
Note: Using GRUB_TERM_COLOR_NORMAL here rather than
GRUB_TERM_COLOR_HIGHLIGHT is intentional. We don't want to switch
to highlight state just because color was reloaded. */
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
set_colors ();
return grub_strdup (val);
}

View file

@ -30,9 +30,13 @@
#include <grub/menu_viewer.h>
#include <grub/auth.h>
#include <grub/i18n.h>
#include <grub/charset.h>
#define GRUB_DEFAULT_HISTORY_SIZE 50
static int nested_level = 0;
int grub_normal_exit_level = 0;
/* Read a line from the file FILE. */
char *
grub_file_getline (grub_file_t file)
@ -372,7 +376,21 @@ read_config_file (const char *config)
if (! file)
return 0;
grub_reader_loop (getline);
while (1)
{
char *line;
/* Print an error, if any. */
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
if ((getline (&line, 0)) || (! line))
break;
grub_parser_get_current ()->parse_line (line, getline);
grub_free (line);
}
grub_file_close (file);
if (old_parser)
@ -383,7 +401,7 @@ read_config_file (const char *config)
/* Initialize the screen. */
void
grub_normal_init_page (void)
grub_normal_init_page (struct grub_term_output *term)
{
int msg_len;
int posx;
@ -391,14 +409,13 @@ grub_normal_init_page (void)
char *msg_formatted = grub_malloc (grub_strlen(msg) +
grub_strlen(PACKAGE_VERSION));
grub_cls ();
grub_sprintf (msg_formatted, msg, PACKAGE_VERSION);
grub_uint32_t *unicode_msg;
grub_uint32_t *last_position;
grub_term_cls (term);
grub_sprintf (msg_formatted, msg, PACKAGE_VERSION);
msg_len = grub_utf8_to_ucs4_alloc (msg_formatted,
&unicode_msg, &last_position);
@ -407,17 +424,15 @@ grub_normal_init_page (void)
return;
}
posx = grub_getstringwidth (unicode_msg, last_position);
posx = (GRUB_TERM_WIDTH - posx) / 2;
grub_gotoxy (posx, 1);
posx = grub_getstringwidth (unicode_msg, last_position, term);
posx = (grub_term_width (term) - posx) / 2;
grub_term_gotoxy (term, posx, 1);
grub_print_ucs4 (unicode_msg, last_position);
grub_print_ucs4 (unicode_msg, last_position, term);
grub_printf("\n\n");
grub_free (unicode_msg);
}
static int reader_nested;
static char *
read_lists (struct grub_env_var *var __attribute__ ((unused)),
const char *val)
@ -425,6 +440,7 @@ read_lists (struct grub_env_var *var __attribute__ ((unused)),
read_command_list ();
read_fs_list ();
read_crypto_list ();
read_terminal_list ();
return val ? grub_strdup (val) : NULL;
}
@ -440,8 +456,6 @@ grub_normal_execute (const char *config, int nested, int batch)
grub_register_variable_hook ("prefix", NULL, read_lists);
grub_command_execute ("parser.grub", 0, 0);
reader_nested = nested;
if (config)
{
menu = read_config_file (config);
@ -454,7 +468,7 @@ grub_normal_execute (const char *config, int nested, int batch)
{
if (menu && menu->size)
{
grub_menu_viewer_show_menu (menu, nested);
grub_show_menu (menu, nested);
if (nested)
free_menu (menu);
}
@ -465,21 +479,24 @@ grub_normal_execute (const char *config, int nested, int batch)
void
grub_enter_normal_mode (const char *config)
{
nested_level++;
grub_normal_execute (config, 0, 0);
grub_cmdline_run (0);
nested_level--;
if (grub_normal_exit_level)
grub_normal_exit_level--;
}
/* Enter normal mode from rescue mode. */
static grub_err_t
grub_cmd_normal (struct grub_command *cmd,
grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[])
{
grub_unregister_command (cmd);
if (argc == 0)
{
/* Guess the config filename. It is necessary to make CONFIG static,
so that it won't get broken by longjmp. */
static char *config;
char *config;
const char *prefix;
prefix = grub_env_get ("prefix");
@ -503,10 +520,82 @@ quit:
return 0;
}
/* Exit from normal mode to rescue mode. */
static grub_err_t
grub_cmd_normal_exit (struct grub_command *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
if (nested_level <= grub_normal_exit_level)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "not in normal environment");
grub_normal_exit_level++;
return GRUB_ERR_NONE;
}
static grub_err_t
grub_normal_reader_init (int nested)
{
struct grub_term_output *term;
const char *msg = _("Minimal BASH-like line editing is supported. For "
"the first word, TAB lists possible command completions. Anywhere "
"else TAB lists possible device or file completions. %s");
const char *msg_esc = _("ESC at any time exits.");
char *msg_formatted = grub_malloc (sizeof (char) * (grub_strlen (msg) +
grub_strlen(msg_esc) + 1));
grub_sprintf (msg_formatted, msg, nested ? msg_esc : "");
FOR_ACTIVE_TERM_OUTPUTS(term)
{
grub_normal_init_page (term);
grub_term_setcursor (term, 1);
grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN, term);
grub_puts ("\n");
}
grub_free (msg_formatted);
return 0;
}
static grub_err_t
grub_normal_read_line_real (char **line, int cont, int nested)
{
grub_parser_t parser = grub_parser_get_current ();
char prompt[sizeof(">") + grub_strlen (parser->name)];
if (cont)
grub_sprintf (prompt, ">");
else
grub_sprintf (prompt, "%s>", parser->name);
while (1)
{
*line = grub_cmdline_get (prompt);
if (*line)
break;
if (cont || nested)
{
grub_free (*line);
*line = 0;
return grub_errno;
}
}
return 0;
}
static grub_err_t
grub_normal_read_line (char **line, int cont)
{
return grub_normal_read_line_real (line, cont, 0);
}
void
grub_cmdline_run (int nested)
{
grub_reader_t reader;
grub_err_t err = GRUB_ERR_NONE;
err = grub_auth_check_authentication (NULL);
@ -518,71 +607,27 @@ grub_cmdline_run (int nested)
return;
}
reader = grub_reader_get_current ();
reader_nested = nested;
if (reader->init)
reader->init ();
grub_reader_loop (0);
}
static grub_err_t
grub_normal_reader_init (void)
{
grub_normal_init_page ();
grub_setcursor (1);
const char *msg = _("Minimal BASH-like line editing is supported. For "
"the first word, TAB lists possible command completions. Anywhere "
"else TAB lists possible device or file completions. %s");
const char *msg_esc = _("ESC at any time exits.");
char *msg_formatted = grub_malloc (sizeof (char) * (grub_strlen (msg) +
grub_strlen(msg_esc) + 1));
grub_sprintf (msg_formatted, msg, reader_nested ? msg_esc : "");
grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN);
grub_puts ("\n");
grub_free (msg_formatted);
return 0;
}
static char cmdline[GRUB_MAX_CMDLINE];
static grub_err_t
grub_normal_read_line (char **line, int cont)
{
grub_parser_t parser = grub_parser_get_current ();
char prompt[sizeof(">") + grub_strlen (parser->name)];
grub_sprintf (prompt, "%s>", parser->name);
grub_normal_reader_init (nested);
while (1)
{
cmdline[0] = 0;
if (grub_cmdline_get (prompt, cmdline, sizeof (cmdline), 0, 1, 1))
char *line;
if (grub_normal_exit_level)
break;
if ((reader_nested) || (cont))
{
*line = 0;
return grub_errno;
}
}
/* Print an error, if any. */
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
*line = grub_strdup (cmdline);
return 0;
}
grub_normal_read_line_real (&line, 0, nested);
if (! line)
break;
static struct grub_reader grub_normal_reader =
{
.name = "normal",
.init = grub_normal_reader_init,
.read_line = grub_normal_read_line
};
grub_parser_get_current ()->parse_line (line, grub_normal_read_line);
grub_free (line);
}
}
static char *
grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)),
@ -598,17 +643,15 @@ GRUB_MOD_INIT(normal)
if (mod)
grub_dl_ref (mod);
grub_menu_viewer_register (&grub_normal_text_menu_viewer);
grub_set_history (GRUB_DEFAULT_HISTORY_SIZE);
grub_reader_register ("normal", &grub_normal_reader);
grub_reader_set_current (&grub_normal_reader);
grub_register_variable_hook ("pager", 0, grub_env_write_pager);
/* Register a command "normal" for the rescue mode. */
grub_register_command_prio ("normal", grub_cmd_normal,
0, "Enter normal mode.", 0);
grub_register_command ("normal", grub_cmd_normal,
0, "Enter normal mode.");
grub_register_command ("normal_exit", grub_cmd_normal_exit,
0, "Exit from normal mode.");
/* Reload terminal colors when these variables are written to. */
grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal);
@ -622,7 +665,6 @@ GRUB_MOD_INIT(normal)
GRUB_MOD_FINI(normal)
{
grub_set_history (0);
grub_reader_unregister (&grub_normal_reader);
grub_register_variable_hook ("pager", 0, 0);
grub_fs_autoload_hook = 0;
free_handler_list ();

View file

@ -27,6 +27,26 @@
#include <grub/command.h>
#include <grub/parser.h>
#include <grub/auth.h>
#include <grub/i18n.h>
#include <grub/term.h>
/* Time to delay after displaying an error message about a default/fallback
entry failing to boot. */
#define DEFAULT_ENTRY_ERROR_DELAY_MS 2500
grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu,
int nested) = NULL;
/* Wait until the user pushes any key so that the user
can see what happened. */
void
grub_wait_after_message (void)
{
grub_putchar ('\n');
grub_printf_ (N_("Press any key to continue..."));
(void) grub_getkey ();
grub_putchar ('\n');
}
/* Get a menu entry by its index in the entry list. */
grub_menu_entry_t
@ -137,6 +157,8 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
return;
}
grub_env_set ("chosen", entry->title);
grub_parser_execute ((char *) entry->sourcecode);
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
@ -178,3 +200,400 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
callback->notify_failure (callback_data);
}
static struct grub_menu_viewer *viewers;
static void
menu_set_chosen_entry (int entry)
{
struct grub_menu_viewer *cur;
for (cur = viewers; cur; cur = cur->next)
cur->set_chosen_entry (entry, cur->data);
}
static void
menu_print_timeout (int timeout)
{
struct grub_menu_viewer *cur;
for (cur = viewers; cur; cur = cur->next)
cur->print_timeout (timeout, cur->data);
}
static void
menu_fini (void)
{
struct grub_menu_viewer *cur, *next;
for (cur = viewers; cur; cur = next)
{
next = cur->next;
cur->fini (cur->data);
grub_free (cur);
}
viewers = NULL;
}
static void
menu_init (int entry, grub_menu_t menu, int nested)
{
struct grub_term_output *term;
FOR_ACTIVE_TERM_OUTPUTS(term)
{
grub_err_t err;
if (grub_gfxmenu_try_hook && grub_strcmp (term->name, "gfxterm") == 0)
{
err = grub_gfxmenu_try_hook (entry, menu, nested);
if(!err)
continue;
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
}
err = grub_menu_try_text (term, entry, menu, nested);
if(!err)
continue;
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
}
}
static void
clear_timeout (void)
{
struct grub_menu_viewer *cur;
for (cur = viewers; cur; cur = cur->next)
cur->clear_timeout (cur->data);
}
void
grub_menu_register_viewer (struct grub_menu_viewer *viewer)
{
viewer->next = viewers;
viewers = viewer;
}
/* Get the entry number from the variable NAME. */
static int
get_entry_number (grub_menu_t menu, const char *name)
{
char *val;
int entry;
val = grub_env_get (name);
if (! val)
return -1;
grub_error_push ();
entry = (int) grub_strtoul (val, 0, 0);
if (grub_errno == GRUB_ERR_BAD_NUMBER)
{
/* See if the variable matches the title of a menu entry. */
grub_menu_entry_t e = menu->entry_list;
int i;
grub_errno = GRUB_ERR_NONE;
for (i = 0; e; i++)
{
if (grub_strcmp (e->title, val) == 0)
{
entry = i;
break;
}
e = e->next;
}
if (! e)
entry = -1;
}
if (grub_errno != GRUB_ERR_NONE)
{
grub_errno = GRUB_ERR_NONE;
entry = -1;
}
grub_error_pop ();
return entry;
}
#define GRUB_MENU_PAGE_SIZE 10
/* Show the menu and handle menu entry selection. Returns the menu entry
index that should be executed or -1 if no entry should be executed (e.g.,
Esc pressed to exit a sub-menu or switching menu viewers).
If the return value is not -1, then *AUTO_BOOT is nonzero iff the menu
entry to be executed is a result of an automatic default selection because
of the timeout. */
static int
run_menu (grub_menu_t menu, int nested, int *auto_boot)
{
grub_uint64_t saved_time;
int default_entry, current_entry;
int timeout;
default_entry = get_entry_number (menu, "default");
/* If DEFAULT_ENTRY is not within the menu entries, fall back to
the first entry. */
if (default_entry < 0 || default_entry >= menu->size)
default_entry = 0;
/* If timeout is 0, drawing is pointless (and ugly). */
if (grub_menu_get_timeout () == 0)
{
*auto_boot = 1;
return default_entry;
}
current_entry = default_entry;
/* Initialize the time. */
saved_time = grub_get_time_ms ();
refresh:
menu_init (current_entry, menu, nested);
timeout = grub_menu_get_timeout ();
if (timeout > 0)
menu_print_timeout (timeout);
while (1)
{
int c;
timeout = grub_menu_get_timeout ();
if (grub_normal_exit_level)
return -1;
if (timeout > 0)
{
grub_uint64_t current_time;
current_time = grub_get_time_ms ();
if (current_time - saved_time >= 1000)
{
timeout--;
grub_menu_set_timeout (timeout);
saved_time = current_time;
menu_print_timeout (timeout);
}
}
if (timeout == 0)
{
grub_env_unset ("timeout");
*auto_boot = 1;
menu_fini ();
return default_entry;
}
if (grub_checkkey () >= 0 || timeout < 0)
{
c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
if (timeout >= 0)
{
grub_env_unset ("timeout");
grub_env_unset ("fallback");
clear_timeout ();
}
switch (c)
{
case GRUB_TERM_HOME:
current_entry = 0;
menu_set_chosen_entry (current_entry);
break;
case GRUB_TERM_END:
current_entry = menu->size - 1;
menu_set_chosen_entry (current_entry);
break;
case GRUB_TERM_UP:
case '^':
if (current_entry > 0)
current_entry--;
menu_set_chosen_entry (current_entry);
break;
case GRUB_TERM_DOWN:
case 'v':
if (current_entry < menu->size - 1)
current_entry++;
menu_set_chosen_entry (current_entry);
break;
case GRUB_TERM_PPAGE:
if (current_entry < GRUB_MENU_PAGE_SIZE)
current_entry = 0;
else
current_entry -= GRUB_MENU_PAGE_SIZE;
menu_set_chosen_entry (current_entry);
break;
case GRUB_TERM_NPAGE:
if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size)
current_entry += GRUB_MENU_PAGE_SIZE;
else
current_entry = menu->size - 1;
menu_set_chosen_entry (current_entry);
break;
case '\n':
case '\r':
case 6:
menu_fini ();
*auto_boot = 0;
return current_entry;
case '\e':
if (nested)
{
menu_fini ();
return -1;
}
break;
case 'c':
menu_fini ();
grub_cmdline_run (1);
goto refresh;
case 'e':
menu_fini ();
{
grub_menu_entry_t e = grub_menu_get_entry (menu, current_entry);
if (e)
grub_menu_entry_run (e);
}
goto refresh;
default:
break;
}
}
}
/* Never reach here. */
return -1;
}
/* Callback invoked immediately before a menu entry is executed. */
static void
notify_booting (grub_menu_entry_t entry,
void *userdata __attribute__((unused)))
{
grub_printf (" ");
grub_printf_ (N_("Booting \'%s\'"), entry->title);
grub_printf ("\n\n");
}
/* Callback invoked when a default menu entry executed because of a timeout
has failed and an attempt will be made to execute the next fallback
entry, ENTRY. */
static void
notify_fallback (grub_menu_entry_t entry,
void *userdata __attribute__((unused)))
{
grub_printf ("\n ");
grub_printf_ (N_("Falling back to \'%s\'"), entry->title);
grub_printf ("\n\n");
grub_millisleep (DEFAULT_ENTRY_ERROR_DELAY_MS);
}
/* Callback invoked when a menu entry has failed and there is no remaining
fallback entry to attempt. */
static void
notify_execution_failure (void *userdata __attribute__((unused)))
{
if (grub_errno != GRUB_ERR_NONE)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
}
grub_printf ("\n ");
grub_printf_ (N_("Failed to boot default entries.\n"));
grub_wait_after_message ();
}
/* Callbacks used by the text menu to provide user feedback when menu entries
are executed. */
static struct grub_menu_execute_callback execution_callback =
{
.notify_booting = notify_booting,
.notify_fallback = notify_fallback,
.notify_failure = notify_execution_failure
};
static grub_err_t
show_menu (grub_menu_t menu, int nested)
{
while (1)
{
int boot_entry;
grub_menu_entry_t e;
int auto_boot;
boot_entry = run_menu (menu, nested, &auto_boot);
if (boot_entry < 0)
break;
e = grub_menu_get_entry (menu, boot_entry);
if (! e)
continue; /* Menu is empty. */
grub_cls ();
if (auto_boot)
{
grub_menu_execute_with_fallback (menu, e, &execution_callback, 0);
}
else
{
grub_errno = GRUB_ERR_NONE;
grub_menu_execute_entry (e);
if (grub_errno != GRUB_ERR_NONE)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
grub_wait_after_message ();
}
}
}
return GRUB_ERR_NONE;
}
grub_err_t
grub_show_menu (grub_menu_t menu, int nested)
{
grub_err_t err1, err2;
while (1)
{
err1 = show_menu (menu, nested);
grub_print_error ();
if (grub_normal_exit_level)
break;
err2 = grub_auth_check_authentication (NULL);
if (err2)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
continue;
}
break;
}
return err1;
}

File diff suppressed because it is too large Load diff

View file

@ -26,88 +26,66 @@
#include <grub/env.h>
#include <grub/menu_viewer.h>
#include <grub/i18n.h>
/* Time to delay after displaying an error message about a default/fallback
entry failing to boot. */
#define DEFAULT_ENTRY_ERROR_DELAY_MS 2500
#include <grub/charset.h>
static grub_uint8_t grub_color_menu_normal;
static grub_uint8_t grub_color_menu_highlight;
/* Wait until the user pushes any key so that the user
can see what happened. */
void
grub_wait_after_message (void)
struct menu_viewer_data
{
grub_putchar ('\n');
grub_printf_ (N_("Press any key to continue..."));
(void) grub_getkey ();
grub_putchar ('\n');
int first, offset;
grub_menu_t menu;
struct grub_term_output *term;
};
static void
print_spaces (int number_spaces, struct grub_term_output *term)
{
int i;
for (i = 0; i < number_spaces; i++)
grub_putcode (' ', term);
}
void
grub_print_ucs4 (const grub_uint32_t * str,
const grub_uint32_t * last_position)
const grub_uint32_t * last_position,
struct grub_term_output *term)
{
while (str < last_position)
{
grub_putcode (*str);
grub_putcode (*str, term);
str++;
}
}
int
grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
grub_uint32_t **last_position)
{
grub_ssize_t msg_len = grub_strlen (msg);
*unicode_msg = grub_malloc (grub_strlen (msg) * sizeof (grub_uint32_t));
if (!*unicode_msg)
{
grub_printf ("utf8_to_ucs4 ERROR1: %s", msg);
return -1;
}
msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len,
(grub_uint8_t *) msg, -1, 0);
*last_position = *unicode_msg + msg_len;
if (msg_len < 0)
{
grub_printf ("utf8_to_ucs4 ERROR2: %s", msg);
grub_free (*unicode_msg);
}
return msg_len;
}
grub_ssize_t
grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position)
grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
struct grub_term_output *term)
{
grub_ssize_t width = 0;
while (str < last_position)
{
width += grub_getcharwidth (*str);
width += grub_term_getcharwidth (term, *str);
str++;
}
return width;
}
void
grub_print_message_indented (const char *msg, int margin_left, int margin_right)
grub_print_message_indented (const char *msg, int margin_left, int margin_right,
struct grub_term_output *term)
{
int line_len;
line_len = GRUB_TERM_WIDTH - grub_getcharwidth ('m') *
(margin_left + margin_right);
grub_uint32_t *unicode_msg;
grub_uint32_t *last_position;
int msg_len;
line_len = grub_term_width (term) - grub_term_getcharwidth (term, 'm') *
(margin_left + margin_right);
msg_len = grub_utf8_to_ucs4_alloc (msg, &unicode_msg, &last_position);
if (msg_len < 0)
@ -124,11 +102,12 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right)
while (current_position < last_position)
{
if (! first_loop)
grub_putchar ('\n');
grub_putcode ('\n', term);
next_new_line = (grub_uint32_t *) last_position;
while (grub_getstringwidth (current_position, next_new_line) > line_len
while (grub_getstringwidth (current_position, next_new_line,term)
> line_len
|| (next_new_line != last_position && *next_new_line != ' '
&& next_new_line > current_position))
{
@ -141,8 +120,8 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right)
(grub_uint32_t *) last_position : next_new_line + line_len;
}
grub_print_spaces (margin_left);
grub_print_ucs4 (current_position, next_new_line);
print_spaces (margin_left, term);
grub_print_ucs4 (current_position, next_new_line, term);
next_new_line++;
current_position = next_new_line;
@ -153,52 +132,54 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right)
static void
draw_border (void)
draw_border (struct grub_term_output *term)
{
unsigned i;
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y);
grub_putcode (GRUB_TERM_DISP_UL);
for (i = 0; i < (unsigned) GRUB_TERM_BORDER_WIDTH - 2; i++)
grub_putcode (GRUB_TERM_DISP_HLINE);
grub_putcode (GRUB_TERM_DISP_UR);
grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y);
grub_putcode (GRUB_TERM_DISP_UL, term);
for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
grub_putcode (GRUB_TERM_DISP_HLINE, term);
grub_putcode (GRUB_TERM_DISP_UR, term);
for (i = 0; i < (unsigned) GRUB_TERM_NUM_ENTRIES; i++)
for (i = 0; i < (unsigned) grub_term_num_entries (term); i++)
{
grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1);
grub_putcode (GRUB_TERM_DISP_VLINE);
grub_gotoxy (GRUB_TERM_MARGIN + GRUB_TERM_BORDER_WIDTH - 1,
grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1);
grub_putcode (GRUB_TERM_DISP_VLINE, term);
grub_term_gotoxy (term, GRUB_TERM_MARGIN + grub_term_border_width (term)
- 1,
GRUB_TERM_TOP_BORDER_Y + i + 1);
grub_putcode (GRUB_TERM_DISP_VLINE);
grub_putcode (GRUB_TERM_DISP_VLINE, term);
}
grub_gotoxy (GRUB_TERM_MARGIN,
GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES + 1);
grub_putcode (GRUB_TERM_DISP_LL);
for (i = 0; i < (unsigned) GRUB_TERM_BORDER_WIDTH - 2; i++)
grub_putcode (GRUB_TERM_DISP_HLINE);
grub_putcode (GRUB_TERM_DISP_LR);
grub_term_gotoxy (term, GRUB_TERM_MARGIN,
GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term) + 1);
grub_putcode (GRUB_TERM_DISP_LL, term);
for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
grub_putcode (GRUB_TERM_DISP_HLINE, term);
grub_putcode (GRUB_TERM_DISP_LR, term);
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
grub_gotoxy (GRUB_TERM_MARGIN,
(GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES
grub_term_gotoxy (term, GRUB_TERM_MARGIN,
(GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term)
+ GRUB_TERM_MARGIN + 1));
}
static void
print_message (int nested, int edit)
print_message (int nested, int edit, struct grub_term_output *term)
{
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
if (edit)
{
grub_putchar ('\n');
grub_putcode ('\n', term);
grub_print_message_indented (_("Minimum Emacs-like screen editing is \
supported. TAB lists completions. Press Ctrl-x to boot, Ctrl-c for a \
command-line or ESC to return menu."), STANDARD_MARGIN, STANDARD_MARGIN);
command-line or ESC to return menu."), STANDARD_MARGIN, STANDARD_MARGIN,
term);
}
else
{
@ -210,23 +191,33 @@ entry is highlighted.\n");
grub_sprintf (msg_translated, msg, (grub_uint32_t) GRUB_TERM_DISP_UP,
(grub_uint32_t) GRUB_TERM_DISP_DOWN);
grub_putchar ('\n');
grub_print_message_indented (msg_translated, STANDARD_MARGIN, STANDARD_MARGIN);
grub_print_message_indented (msg_translated, STANDARD_MARGIN,
STANDARD_MARGIN, term);
grub_free (msg_translated);
grub_print_message_indented (_("Press enter to execute the selected \
entry, \'e\' to edit the commands before booting or \'c\' for a command-line.\n"), STANDARD_MARGIN, STANDARD_MARGIN);
if (nested)
{
grub_printf ("\n ");
grub_printf_ (N_("ESC to return previous menu."));
grub_print_message_indented
(_("Press enter to boot the selected OS, "
"\'e\' to edit the commands before booting "
"or \'c\' for a command-line. ESC to return previous menu.\n"),
STANDARD_MARGIN, STANDARD_MARGIN, term);
}
else
{
grub_print_message_indented
(_("Press enter to boot the selected OS, "
"\'e\' to edit the commands before booting "
"or \'c\' for a command-line.\n"),
STANDARD_MARGIN, STANDARD_MARGIN, term);
}
}
}
static void
print_entry (int y, int highlight, grub_menu_entry_t entry)
print_entry (int y, int highlight, grub_menu_entry_t entry,
struct grub_term_output *term)
{
int x;
const char *title;
@ -252,482 +243,245 @@ print_entry (int y, int highlight, grub_menu_entry_t entry)
return;
}
grub_getcolor (&old_color_normal, &old_color_highlight);
grub_setcolor (grub_color_menu_normal, grub_color_menu_highlight);
grub_setcolorstate (highlight
grub_term_getcolor (term, &old_color_normal, &old_color_highlight);
grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
grub_term_setcolorstate (term, highlight
? GRUB_TERM_COLOR_HIGHLIGHT
: GRUB_TERM_COLOR_NORMAL);
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y);
grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y);
for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, i = 0;
x < GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH - GRUB_TERM_MARGIN;
x < (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
- GRUB_TERM_MARGIN);
i++)
{
if (i < len
&& x <= (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH
&& x <= (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
- GRUB_TERM_MARGIN - 1))
{
grub_ssize_t width;
width = grub_getcharwidth (unicode_title[i]);
width = grub_term_getcharwidth (term, unicode_title[i]);
if (x + width > (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH
if (x + width > (int) (GRUB_TERM_LEFT_BORDER_X
+ grub_term_border_width (term)
- GRUB_TERM_MARGIN - 1))
grub_putcode (GRUB_TERM_DISP_RIGHT);
grub_putcode (GRUB_TERM_DISP_RIGHT, term);
else
grub_putcode (unicode_title[i]);
grub_putcode (unicode_title[i], term);
x += width;
}
else
{
grub_putchar (' ');
grub_putcode (' ', term);
x++;
}
}
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
grub_putchar (' ');
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
grub_putcode (' ', term);
grub_gotoxy (GRUB_TERM_CURSOR_X, y);
grub_term_gotoxy (term, grub_term_cursor_x (term), y);
grub_setcolor (old_color_normal, old_color_highlight);
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
grub_term_setcolor (term, old_color_normal, old_color_highlight);
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
grub_free (unicode_title);
}
static void
print_entries (grub_menu_t menu, int first, int offset)
print_entries (grub_menu_t menu, int first, int offset,
struct grub_term_output *term)
{
grub_menu_entry_t e;
int i;
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
grub_term_gotoxy (term,
GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term),
GRUB_TERM_FIRST_ENTRY_Y);
if (first)
grub_putcode (GRUB_TERM_DISP_UP);
grub_putcode (GRUB_TERM_DISP_UP, term);
else
grub_putchar (' ');
grub_putcode (' ', term);
e = grub_menu_get_entry (menu, first);
for (i = 0; i < GRUB_TERM_NUM_ENTRIES; i++)
for (i = 0; i < grub_term_num_entries (term); i++)
{
print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, offset == i, e);
print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, offset == i, e, term);
if (e)
e = e->next;
}
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES);
grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X
+ grub_term_border_width (term),
GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term));
if (e)
grub_putcode (GRUB_TERM_DISP_DOWN);
grub_putcode (GRUB_TERM_DISP_DOWN, term);
else
grub_putchar (' ');
grub_putcode (' ', term);
grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
grub_term_gotoxy (term, grub_term_cursor_x (term),
GRUB_TERM_FIRST_ENTRY_Y + offset);
}
/* Initialize the screen. If NESTED is non-zero, assume that this menu
is run from another menu or a command-line. If EDIT is non-zero, show
a message for the menu entry editor. */
void
grub_menu_init_page (int nested, int edit)
grub_menu_init_page (int nested, int edit,
struct grub_term_output *term)
{
grub_uint8_t old_color_normal, old_color_highlight;
grub_getcolor (&old_color_normal, &old_color_highlight);
grub_term_getcolor (term, &old_color_normal, &old_color_highlight);
/* By default, use the same colors for the menu. */
grub_color_menu_normal = old_color_normal;
grub_color_menu_highlight = old_color_highlight;
/* Then give user a chance to replace them. */
grub_parse_color_name_pair (&grub_color_menu_normal, grub_env_get ("menu_color_normal"));
grub_parse_color_name_pair (&grub_color_menu_highlight, grub_env_get ("menu_color_highlight"));
grub_parse_color_name_pair (&grub_color_menu_normal,
grub_env_get ("menu_color_normal"));
grub_parse_color_name_pair (&grub_color_menu_highlight,
grub_env_get ("menu_color_highlight"));
grub_normal_init_page ();
grub_setcolor (grub_color_menu_normal, grub_color_menu_highlight);
draw_border ();
grub_setcolor (old_color_normal, old_color_highlight);
print_message (nested, edit);
}
/* Get the entry number from the variable NAME. */
static int
get_entry_number (const char *name)
{
char *val;
int entry;
val = grub_env_get (name);
if (! val)
return -1;
grub_error_push ();
entry = (int) grub_strtoul (val, 0, 0);
if (grub_errno != GRUB_ERR_NONE)
{
grub_errno = GRUB_ERR_NONE;
entry = -1;
}
grub_error_pop ();
return entry;
grub_normal_init_page (term);
grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
draw_border (term);
grub_term_setcolor (term, old_color_normal, old_color_highlight);
print_message (nested, edit, term);
}
static void
print_timeout (int timeout, int offset)
menu_text_print_timeout (int timeout, void *dataptr)
{
const char *msg =
_("The highlighted entry will be executed automatically in %ds.");
struct menu_viewer_data *data = dataptr;
char *msg_translated;
int posx;
grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
char *msg_translated =
grub_malloc (sizeof (char) * grub_strlen (msg) + 5);
msg_translated = grub_malloc (sizeof (char) * grub_strlen (msg) + 5);
if (!msg_translated)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
return;
}
grub_sprintf (msg_translated, msg, timeout);
grub_print_message_indented (msg_translated, 3, 0);
grub_print_message_indented (msg_translated, 3, 0, data->term);
int posx;
posx = grub_getxy() >> 8;
grub_print_spaces (GRUB_TERM_WIDTH - posx - 1);
posx = grub_term_getxy (data->term) >> 8;
print_spaces (grub_term_width (data->term) - posx - 1, data->term);
grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
grub_refresh ();
grub_term_gotoxy (data->term,
grub_term_cursor_x (data->term),
GRUB_TERM_FIRST_ENTRY_Y + data->offset);
grub_term_refresh (data->term);
}
/* Show the menu and handle menu entry selection. Returns the menu entry
index that should be executed or -1 if no entry should be executed (e.g.,
Esc pressed to exit a sub-menu or switching menu viewers).
If the return value is not -1, then *AUTO_BOOT is nonzero iff the menu
entry to be executed is a result of an automatic default selection because
of the timeout. */
static int
run_menu (grub_menu_t menu, int nested, int *auto_boot)
{
int first, offset;
grub_uint64_t saved_time;
int default_entry;
int timeout;
first = 0;
default_entry = get_entry_number ("default");
/* If DEFAULT_ENTRY is not within the menu entries, fall back to
the first entry. */
if (default_entry < 0 || default_entry >= menu->size)
default_entry = 0;
/* If timeout is 0, drawing is pointless (and ugly). */
if (grub_menu_get_timeout () == 0)
{
*auto_boot = 1;
return default_entry;
}
offset = default_entry;
if (offset > GRUB_TERM_NUM_ENTRIES - 1)
{
first = offset - (GRUB_TERM_NUM_ENTRIES - 1);
offset = GRUB_TERM_NUM_ENTRIES - 1;
}
/* Initialize the time. */
saved_time = grub_get_time_ms ();
refresh:
grub_setcursor (0);
grub_menu_init_page (nested, 0);
print_entries (menu, first, offset);
grub_refresh ();
timeout = grub_menu_get_timeout ();
if (timeout > 0)
print_timeout (timeout, offset);
while (1)
{
int c;
timeout = grub_menu_get_timeout ();
if (timeout > 0)
{
grub_uint64_t current_time;
current_time = grub_get_time_ms ();
if (current_time - saved_time >= 1000)
{
timeout--;
grub_menu_set_timeout (timeout);
saved_time = current_time;
print_timeout (timeout, offset);
}
}
if (timeout == 0)
{
grub_env_unset ("timeout");
*auto_boot = 1;
return default_entry;
}
if (grub_checkkey () >= 0 || timeout < 0)
{
c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
if (timeout >= 0)
{
grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
grub_print_spaces (GRUB_TERM_WIDTH - 1);
grub_env_unset ("timeout");
grub_env_unset ("fallback");
grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
}
switch (c)
{
case GRUB_TERM_HOME:
first = 0;
offset = 0;
print_entries (menu, first, offset);
break;
case GRUB_TERM_END:
offset = menu->size - 1;
if (offset > GRUB_TERM_NUM_ENTRIES - 1)
{
first = offset - (GRUB_TERM_NUM_ENTRIES - 1);
offset = GRUB_TERM_NUM_ENTRIES - 1;
}
print_entries (menu, first, offset);
break;
case GRUB_TERM_UP:
case '^':
if (offset > 0)
{
print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 0,
grub_menu_get_entry (menu, first + offset));
offset--;
print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 1,
grub_menu_get_entry (menu, first + offset));
}
else if (first > 0)
{
first--;
print_entries (menu, first, offset);
}
break;
case GRUB_TERM_DOWN:
case 'v':
if (menu->size > first + offset + 1)
{
if (offset < GRUB_TERM_NUM_ENTRIES - 1)
{
print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 0,
grub_menu_get_entry (menu, first + offset));
offset++;
print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 1,
grub_menu_get_entry (menu, first + offset));
}
else
{
first++;
print_entries (menu, first, offset);
}
}
break;
case GRUB_TERM_PPAGE:
if (first == 0)
{
offset = 0;
}
else
{
first -= GRUB_TERM_NUM_ENTRIES;
if (first < 0)
{
offset += first;
first = 0;
}
}
print_entries (menu, first, offset);
break;
case GRUB_TERM_NPAGE:
if (offset == 0)
{
offset += GRUB_TERM_NUM_ENTRIES - 1;
if (first + offset >= menu->size)
{
offset = menu->size - first - 1;
}
}
else
{
first += GRUB_TERM_NUM_ENTRIES;
if (first + offset >= menu->size)
{
first -= GRUB_TERM_NUM_ENTRIES;
offset += GRUB_TERM_NUM_ENTRIES;
if (offset > menu->size - 1 ||
offset > GRUB_TERM_NUM_ENTRIES - 1)
{
offset = menu->size - first - 1;
}
if (offset > GRUB_TERM_NUM_ENTRIES)
{
first += offset - GRUB_TERM_NUM_ENTRIES + 1;
offset = GRUB_TERM_NUM_ENTRIES - 1;
}
}
}
print_entries (menu, first, offset);
break;
case '\n':
case '\r':
case 6:
grub_setcursor (1);
*auto_boot = 0;
return first + offset;
case '\e':
if (nested)
{
grub_setcursor (1);
return -1;
}
break;
case 'c':
grub_cmdline_run (1);
goto refresh;
case 'e':
{
grub_menu_entry_t e = grub_menu_get_entry (menu, first + offset);
if (e)
grub_menu_entry_run (e);
}
goto refresh;
default:
break;
}
grub_refresh ();
}
}
/* Never reach here. */
return -1;
}
/* Callback invoked immediately before a menu entry is executed. */
static void
notify_booting (grub_menu_entry_t entry,
void *userdata __attribute__((unused)))
menu_text_set_chosen_entry (int entry, void *dataptr)
{
grub_printf (" ");
grub_printf_ (N_("Booting \'%s\'"), entry->title);
grub_printf ("\n\n");
struct menu_viewer_data *data = dataptr;
int oldoffset = data->offset;
int complete_redraw = 0;
data->offset = entry - data->first;
if (data->offset > grub_term_num_entries (data->term) - 1)
{
data->first = entry - (grub_term_num_entries (data->term) - 1);
data->offset = grub_term_num_entries (data->term) - 1;
complete_redraw = 1;
}
/* Callback invoked when a default menu entry executed because of a timeout
has failed and an attempt will be made to execute the next fallback
entry, ENTRY. */
static void
notify_fallback (grub_menu_entry_t entry,
void *userdata __attribute__((unused)))
if (data->offset < 0)
{
grub_printf ("\n ");
grub_printf_ (N_("Falling back to \'%s\'"), entry->title);
grub_printf ("\n\n");
grub_millisleep (DEFAULT_ENTRY_ERROR_DELAY_MS);
}
/* Callback invoked when a menu entry has failed and there is no remaining
fallback entry to attempt. */
static void
notify_execution_failure (void *userdata __attribute__((unused)))
{
if (grub_errno != GRUB_ERR_NONE)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
}
grub_printf ("\n ");
grub_printf_ (N_("Failed to boot default entries.\n"));
grub_wait_after_message ();
}
/* Callbacks used by the text menu to provide user feedback when menu entries
are executed. */
static struct grub_menu_execute_callback execution_callback =
{
.notify_booting = notify_booting,
.notify_fallback = notify_fallback,
.notify_failure = notify_execution_failure
};
static grub_err_t
show_text_menu (grub_menu_t menu, int nested)
{
while (1)
{
int boot_entry;
grub_menu_entry_t e;
int auto_boot;
boot_entry = run_menu (menu, nested, &auto_boot);
if (boot_entry < 0)
break;
e = grub_menu_get_entry (menu, boot_entry);
if (! e)
continue; /* Menu is empty. */
grub_cls ();
grub_setcursor (1);
if (auto_boot)
{
grub_menu_execute_with_fallback (menu, e, &execution_callback, 0);
data->offset = 0;
data->first = entry;
complete_redraw = 1;
}
if (complete_redraw)
print_entries (data->menu, data->first, data->offset, data->term);
else
{
grub_errno = GRUB_ERR_NONE;
grub_menu_execute_entry (e);
if (grub_errno != GRUB_ERR_NONE)
print_entry (GRUB_TERM_FIRST_ENTRY_Y + oldoffset, 0,
grub_menu_get_entry (data->menu, data->first + oldoffset),
data->term);
print_entry (GRUB_TERM_FIRST_ENTRY_Y + data->offset, 1,
grub_menu_get_entry (data->menu, data->first + data->offset),
data->term);
}
grub_term_refresh (data->term);
}
static void
menu_text_fini (void *dataptr)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
grub_wait_after_message ();
struct menu_viewer_data *data = dataptr;
grub_term_setcursor (data->term, 1);
grub_term_cls (data->term);
}
static void
menu_text_clear_timeout (void *dataptr)
{
struct menu_viewer_data *data = dataptr;
grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
print_spaces (grub_term_width (data->term) - 1, data->term);
grub_term_gotoxy (data->term, grub_term_cursor_x (data->term),
GRUB_TERM_FIRST_ENTRY_Y + data->offset);
grub_term_refresh (data->term);
}
grub_err_t
grub_menu_try_text (struct grub_term_output *term,
int entry, grub_menu_t menu, int nested)
{
struct menu_viewer_data *data;
struct grub_menu_viewer *instance;
instance = grub_zalloc (sizeof (*instance));
if (!instance)
return grub_errno;
data = grub_zalloc (sizeof (*data));
if (!data)
{
grub_free (instance);
return grub_errno;
}
data->term = term;
instance->data = data;
instance->set_chosen_entry = menu_text_set_chosen_entry;
instance->print_timeout = menu_text_print_timeout;
instance->clear_timeout = menu_text_clear_timeout;
instance->fini = menu_text_fini;
data->menu = menu;
data->offset = entry;
data->first = 0;
if (data->offset > grub_term_num_entries (data->term) - 1)
{
data->first = data->offset - (grub_term_num_entries (data->term) - 1);
data->offset = grub_term_num_entries (data->term) - 1;
}
grub_term_setcursor (data->term, 0);
grub_menu_init_page (nested, 0, data->term);
print_entries (menu, data->first, data->offset, data->term);
grub_term_refresh (data->term);
grub_menu_register_viewer (instance);
return GRUB_ERR_NONE;
}
struct grub_menu_viewer grub_normal_text_menu_viewer =
{
.name = "text",
.show_menu = show_text_menu
};

View file

@ -1,81 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/mm.h>
#include <grub/misc.h>
#include <grub/env.h>
#include <grub/menu_viewer.h>
#include <grub/menu.h>
#include <grub/auth.h>
/* The list of menu viewers. */
static grub_menu_viewer_t menu_viewer_list;
void
grub_menu_viewer_register (grub_menu_viewer_t viewer)
{
viewer->next = menu_viewer_list;
menu_viewer_list = viewer;
}
static grub_menu_viewer_t get_current_menu_viewer (void)
{
const char *selected_name = grub_env_get ("menuviewer");
/* If none selected, pick the last registered one. */
if (selected_name == 0)
return menu_viewer_list;
grub_menu_viewer_t cur;
for (cur = menu_viewer_list; cur; cur = cur->next)
{
if (grub_strcmp (cur->name, selected_name) == 0)
return cur;
}
/* Fall back to the first entry (or null). */
return menu_viewer_list;
}
grub_err_t
grub_menu_viewer_show_menu (grub_menu_t menu, int nested)
{
grub_menu_viewer_t cur = get_current_menu_viewer ();
grub_err_t err1, err2;
if (!cur)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menu viewer available");
while (1)
{
err1 = cur->show_menu (menu, nested);
grub_print_error ();
err2 = grub_auth_check_authentication (NULL);
if (err2)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
continue;
}
break;
}
return err1;
}

252
normal/term.c Normal file
View file

@ -0,0 +1,252 @@
/*
* 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/misc.h>
#include <grub/mm.h>
#include <grub/file.h>
#include <grub/dl.h>
#include <grub/env.h>
#include <grub/normal.h>
/* The amount of lines counted by the pager. */
static unsigned grub_more_lines;
/* If the more pager is active. */
static int grub_more;
static void
process_newline (void)
{
struct grub_term_output *cur;
unsigned height = -1;
FOR_ACTIVE_TERM_OUTPUTS(cur)
if (grub_term_height (cur) < height)
height = grub_term_height (cur);
grub_more_lines++;
if (grub_more && grub_more_lines >= height - 1)
{
char key;
grub_uint16_t *pos;
pos = grub_term_save_pos ();
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf ("--MORE--");
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
key = grub_getkey ();
/* Remove the message. */
grub_term_restore_pos (pos);
grub_printf (" ");
grub_term_restore_pos (pos);
/* Scroll one lines or an entire page, depending on the key. */
if (key == '\r' || key =='\n')
grub_more_lines = height - 2;
else
grub_more_lines = 0;
}
}
void
grub_set_more (int onoff)
{
if (onoff == 1)
grub_more++;
else
grub_more--;
grub_more_lines = 0;
grub_newline_hook = process_newline;
}
void
grub_puts_terminal (const char *str, struct grub_term_output *term)
{
grub_uint32_t code;
grub_ssize_t ret;
const grub_uint8_t *ptr = (const grub_uint8_t *) str;
const grub_uint8_t *end;
end = (const grub_uint8_t *) (str + grub_strlen (str));
while (*ptr)
{
ret = grub_utf8_to_ucs4 (&code, 1, ptr, end - ptr, &ptr);
grub_putcode (code, term);
}
}
grub_uint16_t *
grub_term_save_pos (void)
{
struct grub_term_output *cur;
unsigned cnt = 0;
grub_uint16_t *ret, *ptr;
FOR_ACTIVE_TERM_OUTPUTS(cur)
cnt++;
ret = grub_malloc (cnt * sizeof (ret[0]));
if (!ret)
return NULL;
ptr = ret;
FOR_ACTIVE_TERM_OUTPUTS(cur)
*ptr++ = grub_term_getxy (cur);
return ret;
}
void
grub_term_restore_pos (grub_uint16_t *pos)
{
struct grub_term_output *cur;
grub_uint16_t *ptr = pos;
if (!pos)
return;
FOR_ACTIVE_TERM_OUTPUTS(cur)
{
grub_term_gotoxy (cur, (*ptr & 0xff00) >> 8, *ptr & 0xff);
ptr++;
}
}
static void
grub_terminal_autoload_free (void)
{
struct grub_term_autoload *cur, *next;
unsigned i;
for (i = 0; i < 2; i++)
for (cur = i ? grub_term_input_autoload : grub_term_output_autoload;
cur; cur = next)
{
next = cur->next;
grub_free (cur->name);
grub_free (cur->modname);
grub_free (cur);
}
grub_term_input_autoload = NULL;
grub_term_output_autoload = NULL;
}
/* Read the file terminal.lst for auto-loading. */
void
read_terminal_list (void)
{
const char *prefix;
char *filename;
grub_file_t file;
char *buf = NULL;
prefix = grub_env_get ("prefix");
if (!prefix)
{
grub_errno = GRUB_ERR_NONE;
return;
}
filename = grub_malloc (grub_strlen (prefix) + sizeof ("/terminal.lst"));
if (!filename)
{
grub_errno = GRUB_ERR_NONE;
return;
}
grub_sprintf (filename, "%s/terminal.lst", prefix);
file = grub_file_open (filename);
if (!file)
{
grub_errno = GRUB_ERR_NONE;
return;
}
/* Override previous terminal.lst. */
grub_terminal_autoload_free ();
for (;; grub_free (buf))
{
char *p, *name;
struct grub_term_autoload *cur;
struct grub_term_autoload **target = NULL;
buf = grub_file_getline (file);
if (! buf)
break;
switch (buf[0])
{
case 'i':
target = &grub_term_input_autoload;
break;
case 'o':
target = &grub_term_output_autoload;
break;
}
if (!target)
continue;
name = buf + 1;
p = grub_strchr (name, ':');
if (! p)
continue;
*p = '\0';
while (*++p == ' ')
;
cur = grub_malloc (sizeof (*cur));
if (!cur)
{
grub_errno = GRUB_ERR_NONE;
continue;
}
cur->name = grub_strdup (name);
if (! name)
{
grub_errno = GRUB_ERR_NONE;
grub_free (cur);
continue;
}
cur->modname = grub_strdup (p);
if (! cur->modname)
{
grub_errno = GRUB_ERR_NONE;
grub_free (cur);
grub_free (cur->name);
continue;
}
cur->next = *target;
*target = cur;
}
grub_file_close (file);
grub_errno = GRUB_ERR_NONE;
}

View file

@ -53,7 +53,19 @@ hello/hello.c
lib/arg.c
loader/efi/appleloader.c
loader/efi/chainloader.c
loader/i386/bsd.c
loader/i386/efi/linux.c
loader/i386/ieee1275/linux.c
loader/i386/linux.c
loader/i386/pc/chainloader.c
loader/i386/pc/linux.c
loader/i386/xnu.c
loader/multiboot_loader.c
loader/powerpc/ieee1275/linux.c
loader/sparc64/ieee1275/linux.c
loader/xnu.c
normal/auth.c
normal/color.c

View file

@ -351,8 +351,7 @@ static struct grub_term_output grub_console_term_output =
.setcolorstate = grub_console_setcolorstate,
.setcolor = grub_console_setcolor,
.getcolor = grub_console_getcolor,
.setcursor = grub_console_setcursor,
.flags = 0,
.setcursor = grub_console_setcursor
};
void

View file

@ -27,7 +27,7 @@
#include <grub/bitmap.h>
#include <grub/command.h>
#define DEFAULT_VIDEO_MODE "1024x768,800x600,640x480"
#define DEFAULT_VIDEO_MODE "auto"
#define DEFAULT_BORDER_WIDTH 10
#define DEFAULT_STANDARD_COLOR 0x07
@ -244,12 +244,6 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
return grub_errno;
}
static int NESTED_FUNC_ATTR video_hook (grub_video_adapter_t p __attribute__ ((unused)),
struct grub_video_mode_info *info)
{
return ! (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT);
}
static grub_err_t
grub_gfxterm_init (void)
{
@ -269,13 +263,15 @@ grub_gfxterm_init (void)
/* Parse gfxmode environment variable if set. */
modevar = grub_env_get ("gfxmode");
if (! modevar || *modevar == 0)
err = grub_video_set_mode (DEFAULT_VIDEO_MODE, video_hook);
err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
else
{
tmp = grub_malloc (grub_strlen (modevar)
+ sizeof (DEFAULT_VIDEO_MODE) + 1);
grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
err = grub_video_set_mode (tmp, video_hook);
err = grub_video_set_mode (tmp,
GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
grub_free (tmp);
}

View file

@ -65,8 +65,7 @@ static struct grub_term_output grub_console_term_output =
.setcolorstate = grub_console_setcolorstate,
.setcolor = grub_console_setcolor,
.getcolor = grub_console_getcolor,
.setcursor = grub_console_setcursor,
.flags = 0,
.setcursor = grub_console_setcursor
};
void
@ -79,10 +78,6 @@ grub_console_init (void)
void
grub_console_fini (void)
{
/* This is to make sure the console is restored to text mode before
we boot. */
grub_term_set_current_output (&grub_console_term_output);
grub_term_unregister_input (&grub_console_term_input);
grub_term_unregister_output (&grub_console_term_output);
}

View file

@ -31,6 +31,7 @@
#define TEXT_WIDTH 80
#define TEXT_HEIGHT 25
static struct grub_term_output grub_serial_term_output;
static unsigned int xpos, ypos;
static unsigned int keep_track = 1;
static unsigned int registered = 0;
@ -414,7 +415,7 @@ grub_serial_gotoxy (grub_uint8_t x, grub_uint8_t y)
else
{
keep_track = 0;
grub_terminfo_gotoxy (x, y);
grub_terminfo_gotoxy (x, y, &grub_serial_term_output);
keep_track = 1;
xpos = x;
@ -426,7 +427,7 @@ static void
grub_serial_cls (void)
{
keep_track = 0;
grub_terminfo_cls ();
grub_terminfo_cls (&grub_serial_term_output);
keep_track = 1;
xpos = ypos = 0;
@ -440,10 +441,10 @@ grub_serial_setcolorstate (const grub_term_color_state state)
{
case GRUB_TERM_COLOR_STANDARD:
case GRUB_TERM_COLOR_NORMAL:
grub_terminfo_reverse_video_off ();
grub_terminfo_reverse_video_off (&grub_serial_term_output);
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
grub_terminfo_reverse_video_on ();
grub_terminfo_reverse_video_on (&grub_serial_term_output);
break;
default:
break;
@ -455,9 +456,9 @@ static void
grub_serial_setcursor (const int on)
{
if (on)
grub_terminfo_cursor_on ();
grub_terminfo_cursor_on (&grub_serial_term_output);
else
grub_terminfo_cursor_off ();
grub_terminfo_cursor_off (&grub_serial_term_output);
}
static struct grub_term_input grub_serial_term_input =

View file

@ -77,7 +77,7 @@ inc_y (void)
static void
inc_x (void)
{
if (grub_curr_x >= COLS - 2)
if (grub_curr_x >= COLS - 1)
inc_y ();
else
grub_curr_x++;

View file

@ -83,12 +83,17 @@ grub_ofconsole_putchar (grub_uint32_t c)
grub_curr_y++;
grub_curr_x = 0;
}
else if (c == '\r')
{
grub_curr_x = 0;
}
else
{
grub_curr_x++;
if (grub_curr_x > grub_ofconsole_width)
if (grub_curr_x >= grub_ofconsole_width)
{
grub_putcode ('\n');
grub_ofconsole_putchar ('\n');
grub_ofconsole_putchar ('\r');
grub_curr_x++;
}
}
@ -234,16 +239,13 @@ grub_ofconsole_getxy (void)
return ((grub_curr_x - 1) << 8) | grub_curr_y;
}
static grub_uint16_t
grub_ofconsole_getwh (void)
static void
grub_ofconsole_dimensions (void)
{
grub_ieee1275_ihandle_t options;
char *val;
grub_ssize_t lval;
if (grub_ofconsole_width && grub_ofconsole_height)
return (grub_ofconsole_width << 8) | grub_ofconsole_height;
if (! grub_ieee1275_finddevice ("/options", &options)
&& options != (grub_ieee1275_ihandle_t) -1)
{
@ -280,7 +282,11 @@ grub_ofconsole_getwh (void)
grub_ofconsole_width = 80;
if (! grub_ofconsole_height)
grub_ofconsole_height = 24;
}
static grub_uint16_t
grub_ofconsole_getwh (void)
{
return (grub_ofconsole_width << 8) | grub_ofconsole_height;
}
@ -319,7 +325,7 @@ grub_ofconsole_cls (void)
* ANSI escape sequence. Using video console, Apple Open Firmware (version
* 3.1.1) only recognizes the literal ^L. So use both. */
grub_ofconsole_writeesc (" \e[2J");
grub_gotoxy (0, 0);
grub_ofconsole_gotoxy (0, 0);
}
static void
@ -379,6 +385,8 @@ grub_ofconsole_init_output (void)
grub_ofconsole_setcolorstate (GRUB_TERM_COLOR_NORMAL);
}
grub_ofconsole_dimensions ();
return 0;
}
@ -414,8 +422,7 @@ static struct grub_term_output grub_ofconsole_term_output =
.setcolor = grub_ofconsole_setcolor,
.getcolor = grub_ofconsole_getcolor,
.setcursor = grub_ofconsole_setcursor,
.refresh = grub_ofconsole_refresh,
.flags = 0,
.refresh = grub_ofconsole_refresh
};
void

View file

@ -108,52 +108,52 @@ grub_terminfo_set_current (const char *str)
/* Wrapper for grub_putchar to write strings. */
static void
putstr (const char *str)
putstr (const char *str, grub_term_output_t oterm)
{
while (*str)
grub_putchar (*str++);
grub_putcode (*str++, oterm);
}
/* Move the cursor to the given position starting with "0". */
void
grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y)
grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y, grub_term_output_t oterm)
{
putstr (grub_terminfo_tparm (term.gotoxy, y, x));
putstr (grub_terminfo_tparm (term.gotoxy, y, x), oterm);
}
/* Clear the screen. */
void
grub_terminfo_cls (void)
grub_terminfo_cls (grub_term_output_t oterm)
{
putstr (grub_terminfo_tparm (term.cls));
putstr (grub_terminfo_tparm (term.cls), oterm);
}
/* Set reverse video mode on. */
void
grub_terminfo_reverse_video_on (void)
grub_terminfo_reverse_video_on (grub_term_output_t oterm)
{
putstr (grub_terminfo_tparm (term.reverse_video_on));
putstr (grub_terminfo_tparm (term.reverse_video_on), oterm);
}
/* Set reverse video mode off. */
void
grub_terminfo_reverse_video_off (void)
grub_terminfo_reverse_video_off (grub_term_output_t oterm)
{
putstr (grub_terminfo_tparm (term.reverse_video_off));
putstr (grub_terminfo_tparm (term.reverse_video_off), oterm);
}
/* Show cursor. */
void
grub_terminfo_cursor_on (void)
grub_terminfo_cursor_on (grub_term_output_t oterm)
{
putstr (grub_terminfo_tparm (term.cursor_on));
putstr (grub_terminfo_tparm (term.cursor_on), oterm);
}
/* Hide cursor. */
void
grub_terminfo_cursor_off (void)
grub_terminfo_cursor_off (grub_term_output_t oterm)
{
putstr (grub_terminfo_tparm (term.cursor_off));
putstr (grub_terminfo_tparm (term.cursor_off), oterm);
}
/* GRUB Command. */

View file

@ -0,0 +1,35 @@
/*
* 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/>.
*/
/* All tests need to include test.h for GRUB testing framework. */
#include <grub/test.h>
/* Functional test main method. */
static void
example_test (void)
{
/* Check if 1st argument is true and report with default error message. */
grub_test_assert (1 == 1);
/* Check if 1st argument is true and report with custom error message. */
grub_test_assert (2 == 2, "2 equal 2 expected");
grub_test_assert (2 == 3, "2 is not equal to %d", 3);
}
/* Register example_test method as a functional test. */
GRUB_FUNCTIONAL_TEST ("example_functional_test", example_test);

View file

@ -0,0 +1,3 @@
#! @builddir@/grub-shell-tester --modules=echo
echo "hello world"

View file

@ -0,0 +1,3 @@
#!/bin/sh -e
true

38
tests/example_unit_test.c Normal file
View file

@ -0,0 +1,38 @@
/*
* 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/>.
*/
/* Unit tests are normal programs, so they can include C library. */
#include <string.h>
/* All tests need to include test.h for GRUB testing framework. */
#include <grub/test.h>
/* Unit test main method. */
static void
example_test (void)
{
/* Check if 1st argument is true and report with default error message. */
grub_test_assert (1 == 1);
/* Check if 1st argument is true and report with custom error message. */
grub_test_assert (2 == 2, "2 equal 2 expected");
grub_test_assert (2 == 3, "2 is not equal to %d", 3);
}
/* Register example_test method as a unit test. */
GRUB_UNIT_TEST ("example_unit_test", example_test);

View file

@ -0,0 +1,53 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/extcmd.h>
#include <grub/test.h>
static grub_err_t
grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)),
int argc __attribute__ ((unused)),
char **args __attribute__ ((unused)))
{
auto int run_test (grub_test_t test);
int run_test (grub_test_t test)
{
grub_test_run (test);
return 0;
}
grub_list_iterate (GRUB_AS_LIST (grub_test_list),
(grub_list_hook_t) run_test);
return GRUB_ERR_NONE;
}
static grub_extcmd_t cmd;
GRUB_MOD_INIT (functional_test)
{
cmd = grub_register_extcmd ("functional_test", grub_functional_test,
GRUB_COMMAND_FLAG_CMDLINE, 0,
"Run all functional tests.", 0);
}
GRUB_MOD_FINI (functional_test)
{
grub_unregister_extcmd (cmd);
}

164
tests/lib/test.c Normal file
View file

@ -0,0 +1,164 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/test.h>
struct grub_test_failure
{
/* The next failure. */
struct grub_test_failure *next;
/* The test source file name. */
char *file;
/* The test function name. */
char *funp;
/* The test call line number. */
grub_uint32_t line;
/* The test failure message. */
char *message;
};
typedef struct grub_test_failure *grub_test_failure_t;
grub_test_t grub_test_list;
static grub_test_failure_t failure_list;
static void
add_failure (const char *file,
const char *funp,
grub_uint32_t line, const char *fmt, va_list args)
{
char buf[1024];
grub_test_failure_t failure;
failure = (grub_test_failure_t) grub_malloc (sizeof (*failure));
if (!failure)
return;
grub_vsprintf (buf, fmt, args);
failure->file = grub_strdup (file ? : "<unknown_file>");
failure->funp = grub_strdup (funp ? : "<unknown_function>");
failure->line = line;
failure->message = grub_strdup (buf);
grub_list_push (GRUB_AS_LIST_P (&failure_list), GRUB_AS_LIST (failure));
}
static void
free_failures (void)
{
grub_test_failure_t item;
while ((item = grub_list_pop (GRUB_AS_LIST_P (&failure_list))) != 0)
{
if (item->message)
grub_free (item->message);
if (item->funp)
grub_free (item->funp);
if (item->file)
grub_free (item->file);
grub_free (item);
}
failure_list = 0;
}
void
grub_test_nonzero (int cond,
const char *file,
const char *funp, grub_uint32_t line, const char *fmt, ...)
{
va_list ap;
if (cond)
return;
va_start (ap, fmt);
add_failure (file, funp, line, fmt, ap);
va_end (ap);
}
void
grub_test_register (const char *name, void (*test_main) (void))
{
grub_test_t test;
test = (grub_test_t) grub_malloc (sizeof (*test));
if (!test)
return;
test->name = grub_strdup (name);
test->main = test_main;
grub_list_push (GRUB_AS_LIST_P (&grub_test_list), GRUB_AS_LIST (test));
}
void
grub_test_unregister (const char *name)
{
grub_test_t test;
test = (grub_test_t) grub_named_list_find
(GRUB_AS_NAMED_LIST (grub_test_list), name);
if (test)
{
grub_list_remove (GRUB_AS_LIST_P (&grub_test_list), GRUB_AS_LIST (test));
if (test->name)
grub_free (test->name);
grub_free (test);
}
}
int
grub_test_run (grub_test_t test)
{
auto int print_failure (grub_test_failure_t item);
int print_failure (grub_test_failure_t item)
{
grub_test_failure_t failure = (grub_test_failure_t) item;
grub_printf (" %s:%s:%u: %s\n",
(failure->file ? : "<unknown_file>"),
(failure->funp ? : "<unknown_function>"),
failure->line, (failure->message ? : "<no message>"));
return 0;
}
test->main ();
grub_printf ("%s:\n", test->name);
grub_list_iterate (GRUB_AS_LIST (failure_list),
(grub_list_hook_t) print_failure);
if (!failure_list)
grub_printf ("%s: PASS\n", test->name);
else
grub_printf ("%s: FAIL\n", test->name);
free_failures ();
return GRUB_ERR_NONE;
}

109
tests/lib/unit_test.c Normal file
View file

@ -0,0 +1,109 @@
/*
* 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 <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <grub/list.h>
#include <grub/test.h>
#include <grub/handler.h>
int
main (int argc __attribute__ ((unused)),
char *argv[] __attribute__ ((unused)))
{
int status = 0;
extern void grub_unit_test_init (void);
extern void grub_unit_test_fini (void);
auto int run_test (grub_test_t test);
int run_test (grub_test_t test)
{
status = grub_test_run (test) ? : status;
return 0;
}
grub_unit_test_init ();
grub_list_iterate (GRUB_AS_LIST (grub_test_list),
(grub_list_hook_t) run_test);
grub_unit_test_fini ();
exit (status);
}
/* Other misc. functions necessary for successful linking. */
void
grub_free (void *ptr)
{
free (ptr);
}
char *
grub_env_get (const char *name __attribute__ ((unused)))
{
return NULL;
}
grub_err_t
grub_error (grub_err_t n, const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
vfprintf (stderr, fmt, ap);
va_end (ap);
return n;
}
void *
grub_malloc (grub_size_t size)
{
return malloc (size);
}
void
grub_refresh (void)
{
fflush (stdout);
}
void
grub_putchar (int c)
{
putchar (c);
}
int
grub_getkey (void)
{
return -1;
}
void
grub_exit (void)
{
exit (1);
}
struct grub_handler_class grub_term_input_class;
struct grub_handler_class grub_term_output_class;

View file

@ -0,0 +1,109 @@
#! /bin/bash -e
# Compares GRUB script output with BASH output.
# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# Initialize some variables.
transform="@program_transform_name@"
prefix=@prefix@
exec_prefix=@exec_prefix@
bindir=@bindir@
libdir=@libdir@
builddir=@builddir@
PACKAGE_NAME=@PACKAGE_NAME@
PACKAGE_TARNAME=@PACKAGE_TARNAME@
PACKAGE_VERSION=@PACKAGE_VERSION@
target_cpu=@target_cpu@
# Force build directory components
PATH=${builddir}:$PATH
export PATH
# Usage: usage
# Print the usage.
usage () {
cat <<EOF
Usage: $0 [OPTION] [SOURCE]
Compares GRUB script output with BASH shell output.
-h, --help print this message and exit
-v, --version print the version information and exit
--modules=MODULES pre-load specified modules MODULES
--qemu-opts=OPTIONS extra options to pass to Qemu instance
$0 compares GRUB script output with BASH shell output and prints their
differences.
Report bugs to <bug-grub@gnu.org>.
EOF
}
# Check the arguments.
for option in "$@"; do
case "$option" in
-h | --help)
usage
exit 0 ;;
-v | --version)
echo "$0 (GNU GRUB ${PACKAGE_VERSION})"
exit 0 ;;
--modules=*)
ms=`echo "$option" | sed -e 's/--modules=//'`
modules="$modules,$ms" ;;
--qemu-opts=*)
qs=`echo "$option" | sed -e 's/--qemu-opts=//'`
qemuopts="$qemuopts $qs" ;;
-*)
echo "Unrecognized option \`$option'" 1>&2
usage
exit 1
;;
*)
if [ "x${source}" != x ] ; then
echo "too many parameters at the end" 1>&2
usage
exit 1
fi
source="${option}" ;;
esac
done
if [ "x${source}" = x ] ; then
tmpfile=`mktemp`
while read; do
echo $REPLY >> ${tmpfile}
done
source=${tmpfile}
fi
outfile1=`mktemp`
@builddir@/grub-shell --qemu-opts="${qemuopts}" --modules=${modules} ${source} >${outfile1}
outfile2=`mktemp`
bash ${source} >${outfile2}
if ! diff -q ${outfile1} ${outfile2} >/dev/null
then
echo "${source}: GRUB and BASH outputs did not match (see diff -u ${outfile1} ${outfile2})"
status=1
else
rm -f ${outfile1} ${outfile2}
fi
exit $status

145
tests/util/grub-shell.in Normal file
View file

@ -0,0 +1,145 @@
#! /bin/bash -e
# Run GRUB script in a Qemu instance
# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
#
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB. If not, see <http://www.gnu.org/licenses/>.
# Initialize some variables.
transform="@program_transform_name@"
prefix=@prefix@
exec_prefix=@exec_prefix@
bindir=@bindir@
libdir=@libdir@
builddir=@builddir@
PACKAGE_NAME=@PACKAGE_NAME@
PACKAGE_TARNAME=@PACKAGE_TARNAME@
PACKAGE_VERSION=@PACKAGE_VERSION@
target_cpu=@target_cpu@
# Force build directory components
PATH=${builddir}:$PATH
export PATH
# Usage: usage
# Print the usage.
usage () {
cat <<EOF
Usage: $0 [OPTION] [SOURCE]
Run GRUB script in a Qemu instance.
-h, --help print this message and exit
-v, --version print the version information and exit
--boot=[fd|hd|cd] boot method for Qemu instance
--modules=MODULES pre-load specified modules MODULES
--qemu-opts=OPTIONS extra options to pass to Qemu instance
$0 runs input GRUB script or SOURCE file in a Qemu instance and prints
its output.
Report bugs to <bug-grub@gnu.org>.
EOF
}
# Check the arguments.
for option in "$@"; do
case "$option" in
-h | --help)
usage
exit 0 ;;
-v | --version)
echo "$0 (GNU GRUB ${PACKAGE_VERSION})"
exit 0 ;;
--modules=*)
ms=`echo "$option" | sed -e 's/--modules=//' -e 's/,/ /g'`
modules="$modules $ms" ;;
--qemu-opts=*)
qs=`echo "$option" | sed -e 's/--qemu-opts=//'`
qemuopts="$qemuopts $qs" ;;
--boot=*)
dev=`echo "$option" | sed -e 's/--boot=//'`
if [ "$dev" = "fd" ] ; then bootdev=a;
elif [ "$dev" = "hd" ] ; then bootdev=c;
elif [ "$dev" = "cd" ] ; then bootdev=d;
else
echo "Unrecognized boot method \`$dev'" 1>&2
usage
exit 1
fi ;;
-*)
echo "Unrecognized option \`$option'" 1>&2
usage
exit 1 ;;
*)
if [ "x${source}" != x ] ; then
echo "too many parameters at the end" 1>&2
usage
exit 1
fi
source="${option}" ;;
esac
done
if [ "x${source}" = x ] ; then
tmpfile=`mktemp`
while read; do
echo $REPLY >> ${tmpfile}
done
source=${tmpfile}
fi
if [ "x${bootdev}" = x ] ; then
bootdev=c # default is boot as disk image
fi
cfgfile=`mktemp`
cat <<EOF >${cfgfile}
grubshell=yes
insmod serial
serial
terminal_input serial
terminal_output serial
EOF
for mod in ${modules}
do
echo "insmod ${mod}" >> ${cfgfile}
done
cat <<EOF >>${cfgfile}
source /boot/grub/testcase.cfg
halt
EOF
isofile=`mktemp`
grub-mkrescue --output=${isofile} --override-directory=${builddir} \
/boot/grub/grub.cfg=${cfgfile} /boot/grub/testcase.cfg=${source} \
>/dev/null 2>&1
hdafile=`mktemp`
cp ${isofile} ${hdafile}
fdafile=`mktemp`
cp ${isofile} ${fdafile}
outfile=`mktemp`
qemu-system-i386 ${qemuopts} -nographic -serial stdio -hda ${hdafile} -fda ${fdafile} -cdrom ${isofile} -boot ${bootdev} | tr -d "\r" >${outfile}
cat $outfile
rm -f ${tmpfile} ${outfile} ${cfgfile} ${isofile} ${hdafile} ${fdafile}
exit 0

View file

@ -19,14 +19,6 @@
#include <config.h>
#if defined(HAVE_NCURSES_CURSES_H)
# include <ncurses/curses.h>
#elif defined(HAVE_NCURSES_H)
# include <ncurses.h>
#elif defined(HAVE_CURSES_H)
# include <curses.h>
#endif
/* For compatibility. */
#ifndef A_NORMAL
# define A_NORMAL 0
@ -39,6 +31,14 @@
#include <grub/term.h>
#include <grub/types.h>
#if defined(HAVE_NCURSES_CURSES_H)
# include <ncurses/curses.h>
#elif defined(HAVE_NCURSES_H)
# include <ncurses.h>
#elif defined(HAVE_CURSES_H)
# include <curses.h>
#endif
static int grub_console_attr = A_NORMAL;
grub_uint8_t grub_console_cur_color = 7;
@ -367,8 +367,7 @@ static struct grub_term_output grub_ncurses_term_output =
.setcolor = grub_ncurses_setcolor,
.getcolor = grub_ncurses_getcolor,
.setcursor = grub_ncurses_setcursor,
.refresh = grub_ncurses_refresh,
.flags = 0,
.refresh = grub_ncurses_refresh
};
void
@ -376,8 +375,6 @@ grub_console_init (void)
{
grub_term_register_output ("console", &grub_ncurses_term_output);
grub_term_register_input ("console", &grub_ncurses_term_input);
grub_term_set_current_output (&grub_ncurses_term_output);
grub_term_set_current_input (&grub_ncurses_term_input);
}
void

View file

@ -328,7 +328,7 @@ static void
usage (int status)
{
if (status)
fprintf (stderr, "Try ``%s --help'' for more information.\n", program_name);
fprintf (stderr, "Try `%s --help' for more information.\n", program_name);
else
printf ("\
Usage: %s -o FILE [OPTION]... [MODULES]\n\

View file

@ -115,14 +115,14 @@ grub_get_prefix (const char *dir)
saved_cwd = xgetcwd ();
if (chdir (dir) < 0)
grub_util_error ("Cannot change directory to `%s'", dir);
grub_util_error ("cannot change directory to `%s'", dir);
abs_dir = xgetcwd ();
strip_extra_slashes (abs_dir);
prev_dir = xstrdup (abs_dir);
if (stat (".", &prev_st) < 0)
grub_util_error ("Cannot stat `%s'", dir);
grub_util_error ("cannot stat `%s'", dir);
if (! S_ISDIR (prev_st.st_mode))
grub_util_error ("`%s' is not a directory", dir);
@ -130,13 +130,13 @@ grub_get_prefix (const char *dir)
while (1)
{
if (chdir ("..") < 0)
grub_util_error ("Cannot change directory to the parent");
grub_util_error ("cannot change directory to the parent");
if (stat (".", &st) < 0)
grub_util_error ("Cannot stat current directory");
grub_util_error ("cannot stat current directory");
if (! S_ISDIR (st.st_mode))
grub_util_error ("Current directory is not a directory???");
grub_util_error ("current directory is not a directory???");
if (prev_st.st_dev != st.st_dev || prev_st.st_ino == st.st_ino)
break;
@ -153,7 +153,7 @@ grub_get_prefix (const char *dir)
strip_extra_slashes (prefix);
if (chdir (saved_cwd) < 0)
grub_util_error ("Cannot change directory to `%s'", dir);
grub_util_error ("cannot change directory to `%s'", dir);
#ifdef __CYGWIN__
if (st.st_dev != (DEV_CYGDRIVE_MAJOR << 16))
@ -236,7 +236,7 @@ find_root_device (const char *dir, dev_t dev)
if (res)
{
if (chdir (saved_cwd) < 0)
grub_util_error ("Cannot restore the original directory");
grub_util_error ("cannot restore the original directory");
free (saved_cwd);
closedir (dp);
@ -279,7 +279,7 @@ find_root_device (const char *dir, dev_t dev)
continue;
if (chdir (saved_cwd) < 0)
grub_util_error ("Cannot restore the original directory");
grub_util_error ("cannot restore the original directory");
free (saved_cwd);
closedir (dp);
@ -288,7 +288,7 @@ find_root_device (const char *dir, dev_t dev)
}
if (chdir (saved_cwd) < 0)
grub_util_error ("Cannot restore the original directory");
grub_util_error ("cannot restore the original directory");
free (saved_cwd);
closedir (dp);
@ -445,7 +445,7 @@ grub_guess_root_device (const char *dir)
struct stat st;
if (stat (dir, &st) < 0)
grub_util_error ("Cannot stat `%s'", dir);
grub_util_error ("cannot stat `%s'", dir);
#ifdef __CYGWIN__
/* Cygwin specific function. */
@ -591,7 +591,7 @@ grub_util_get_grub_dev (const char *os_dev)
free (p);
}
else
grub_util_error ("Unknown kind of RAID device `%s'", os_dev);
grub_util_error ("unknown kind of RAID device `%s'", os_dev);
break;
@ -608,7 +608,7 @@ grub_util_check_block_device (const char *blk_dev)
struct stat st;
if (stat (blk_dev, &st) < 0)
grub_util_error ("Cannot stat `%s'", blk_dev);
grub_util_error ("cannot stat `%s'", blk_dev);
if (S_ISBLK (st.st_mode))
return (blk_dev);
@ -622,7 +622,7 @@ grub_util_check_char_device (const char *blk_dev)
struct stat st;
if (stat (blk_dev, &st) < 0)
grub_util_error ("Cannot stat `%s'", blk_dev);
grub_util_error ("cannot stat `%s'", blk_dev);
if (S_ISCHR (st.st_mode))
return (blk_dev);

View file

@ -46,9 +46,6 @@ grub_refresh (void)
fflush (stdout);
}
struct grub_handler_class grub_term_input_class;
struct grub_handler_class grub_term_output_class;
int
grub_getkey (void)
{
@ -72,10 +69,10 @@ static void
usage (int status)
{
if (status)
fprintf (stderr, "Try ``grub-editenv --help'' for more information.\n");
fprintf (stderr, "Try `%s --help' for more information.\n", program_name);
else
printf ("\
Usage: grub-editenv [OPTIONS] [FILENAME] COMMAND\n\
Usage: %s [OPTIONS] [FILENAME] COMMAND\n\
\n\
Tool to edit environment block.\n\
\nCommands:\n\
@ -91,7 +88,7 @@ Tool to edit environment block.\n\
If not given explicitly, FILENAME defaults to %s.\n\
\n\
Report bugs to <%s>.\n",
DEFAULT_DIRECTORY "/" GRUB_ENVBLK_DEFCFG, PACKAGE_BUGREPORT);
program_name, DEFAULT_DIRECTORY "/" GRUB_ENVBLK_DEFCFG, PACKAGE_BUGREPORT);
exit (status);
}

View file

@ -129,10 +129,10 @@ usage (int status)
{
if (status)
fprintf (stderr,
"Try ``grub-emu --help'' for more information.\n");
"Try `%s --help' for more information.\n", program_name);
else
printf (
"Usage: grub-emu [OPTION]...\n"
"Usage: %s [OPTION]...\n"
"\n"
"GRUB emulator.\n"
"\n"
@ -144,7 +144,7 @@ usage (int status)
" -h, --help display this message and exit\n"
" -V, --version print version information and exit\n"
"\n"
"Report bugs to <%s>.\n", DEFAULT_DEVICE_MAP, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT);
"Report bugs to <%s>.\n", program_name, DEFAULT_DEVICE_MAP, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT);
return status;
}
@ -220,14 +220,14 @@ main (int argc, char *argv[])
{
char *device_name = grub_guess_root_device (dir);
if (! device_name)
grub_util_error ("cannot find a device for %s.\n", dir);
grub_util_error ("cannot find a device for %s", dir);
root_dev = grub_util_get_grub_dev (device_name);
if (! root_dev)
{
grub_util_info ("guessing the root device failed, because of `%s'",
grub_errmsg);
grub_util_error ("Cannot guess the root device. Specify the option ``--root-device''.");
grub_util_error ("cannot guess the root device. Specify the option `--root-device'");
}
}

View file

@ -71,7 +71,7 @@ execute_command (char *name, int n, char **args)
cmd = grub_command_find (name);
if (! cmd)
grub_util_error ("Can\'t find command %s", name);
grub_util_error ("can\'t find command %s", name);
return (cmd->func) (cmd, n, args);
}
@ -100,9 +100,9 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len))
dev = grub_device_open (0);
if ((! dev) || (! dev->disk))
grub_util_error ("Can\'t open device.");
grub_util_error ("can\'t open device");
grub_util_info ("total sectors : %lld.",
grub_util_info ("total sectors : %lld",
(unsigned long long) dev->disk->total_sectors);
if (! leng)
@ -115,7 +115,7 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len))
len = (leng > BUF_SIZE) ? BUF_SIZE : leng;
if (grub_disk_read (dev->disk, 0, skip, len, buf))
grub_util_error ("Disk read fails at offset %lld, length %d.",
grub_util_error ("disk read fails at offset %lld, length %d",
skip, len);
if (hook (skip, buf, len))
@ -132,15 +132,15 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len))
file = grub_file_open (pathname);
if (!file)
{
grub_util_error ("cannot open file %s.", pathname);
grub_util_error ("cannot open file %s", pathname);
return;
}
grub_util_info ("file size : %lld.", (unsigned long long) file->size);
grub_util_info ("file size : %lld", (unsigned long long) file->size);
if (skip > file->size)
{
grub_util_error ("invalid skip value %lld.", (unsigned long long) skip);
grub_util_error ("invalid skip value %lld", (unsigned long long) skip);
return;
}
@ -158,7 +158,7 @@ read_file (char *pathname, int (*hook) (grub_off_t ofs, char *buf, int len))
sz = grub_file_read (file, buf, (len > BUF_SIZE) ? BUF_SIZE : len);
if (sz < 0)
{
grub_util_error ("read error at offset %llu.", ofs);
grub_util_error ("read error at offset %llu", ofs);
break;
}
@ -184,7 +184,7 @@ cmd_cp (char *src, char *dest)
if ((int) fwrite (buf, 1, len, ff) != len)
{
grub_util_error ("write error.");
grub_util_error ("write error");
return 1;
}
@ -194,7 +194,7 @@ cmd_cp (char *src, char *dest)
ff = fopen (dest, "wb");
if (ff == NULL)
{
grub_util_error ("open error.");
grub_util_error ("open error");
return;
}
read_file (src, cp_hook);
@ -212,7 +212,7 @@ cmd_cmp (char *src, char *dest)
{
if ((int) fread (buf_1, 1, len, ff) != len)
{
grub_util_error ("read error at offset %llu.", ofs);
grub_util_error ("read error at offset %llu", ofs);
return 1;
}
@ -223,7 +223,7 @@ cmd_cmp (char *src, char *dest)
for (i = 0; i < len; i++, ofs++)
if (buf_1[i] != buf[i])
{
grub_util_error ("compare fail at offset %llu.", ofs);
grub_util_error ("compare fail at offset %llu", ofs);
return 1;
}
}
@ -233,12 +233,12 @@ cmd_cmp (char *src, char *dest)
ff = fopen (dest, "rb");
if (ff == NULL)
{
grub_util_error ("open error.");
grub_util_error ("open error");
return;
}
if ((skip) && (fseeko (ff, skip, SEEK_SET)))
grub_util_error ("seek error.");
grub_util_error ("seek error");
read_file (src, cmp_hook);
fclose (ff);
@ -286,13 +286,13 @@ fstest (char **images, int num_disks, int cmd, int n, char **args)
for (i = 0; i < num_disks; i++)
{
if (grub_strlen (images[i]) + 7 > sizeof (host_file))
grub_util_error ("Pathname %s too long.", images[i]);
grub_util_error ("pathname %s too long", images[i]);
grub_sprintf (loop_name, "loop%d", i);
grub_sprintf (host_file, "(host)%s", images[i]);
if (execute_command ("loopback", 3, argv))
grub_util_error ("loopback command fails.");
grub_util_error ("loopback command fails");
}
grub_lvm_fini ();
@ -349,7 +349,7 @@ static void
usage (int status)
{
if (status)
fprintf (stderr, "Try ``%s --help'' for more information.\n", program_name);
fprintf (stderr, "Try `%s --help' for more information.\n", program_name);
else
printf ("\
Usage: %s [OPTION]... IMAGE_PATH COMMANDS\n\

View file

@ -40,6 +40,7 @@ else
fi
grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}`
rootdir=
grub_prefix=`echo /boot/grub | sed ${transform}`
modules=
@ -87,9 +88,11 @@ fi
INSTALL_DEVICE can be a GRUB device name or a system device filename.
grub-install copies GRUB images into the DIR/boot directory specified by
--root-directory, and uses grub-setup to install grub into the boot
sector.
grub-install copies GRUB images into /boot/grub (or /grub on NetBSD and
OpenBSD), and uses grub-setup to install grub into the boot sector.
If the --root-directory option is used, then grub-install will copy
images into the operating system installation rooted at that directory.
Report bugs to <bug-grub@gnu.org>.
EOF
@ -261,6 +264,10 @@ done
# Write device to a variable so we don't have to traverse /dev every time.
grub_device=`$grub_probe --target=device ${grubdir}`
if ! test -f ${grubdir}/grubenv; then
$grub_editenv ${grubdir}/grubenv create
fi
# Create the core image. First, auto-detect the filesystem module.
fs_module=`$grub_probe --target=fs --device ${grub_device}`
if test "x$fs_module" = x -a "x$modules" = x; then

View file

@ -94,6 +94,15 @@ convert_system_path_to_grub_path ()
echo ${drive}${relative_path}
}
save_default_entry ()
{
if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then
cat << EOF
savedefault
EOF
fi
}
prepare_grub_to_access_device ()
{
device=$1

Some files were not shown because too many files have changed in this diff Show more