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> 2010-01-08 Robert Millan <rmh.grub@aybabtu.com>
* src/mkisofs.c: Remove `ifdef linux' portability kludge. * src/mkisofs.c: Remove `ifdef linux' portability kludge.

View file

@ -167,6 +167,8 @@ ifeq ($(platform), emu)
include $(srcdir)/conf/any-emu.mk include $(srcdir)/conf/any-emu.mk
else else
include $(srcdir)/conf/$(target_cpu)-$(platform).mk include $(srcdir)/conf/$(target_cpu)-$(platform).mk
# For tests.
include $(srcdir)/conf/tests.mk
# For external modules. # For external modules.
-include $(wildcard $(GRUB_CONTRIB)/*/conf/common.mk) -include $(wildcard $(GRUB_CONTRIB)/*/conf/common.mk)
endif endif
@ -174,7 +176,7 @@ endif
### General targets. ### General targets.
CLEANFILES += $(pkglib_DATA) $(pkgdata_DATA) po/*.mo 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 moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep.awk
cat $(DEFSYMFILES) /dev/null \ cat $(DEFSYMFILES) /dev/null \
| $(AWK) -f $(srcdir)/genmoddep.awk $(UNDSYMFILES) > $@ \ | $(AWK) -f $(srcdir)/genmoddep.awk $(UNDSYMFILES) > $@ \
@ -192,6 +194,9 @@ partmap.lst: $(PARTMAPFILES)
handler.lst: $(HANDLERFILES) handler.lst: $(HANDLERFILES)
cat $^ /dev/null | sort > $@ cat $^ /dev/null | sort > $@
terminal.lst: $(TERMINALFILES)
cat $^ /dev/null | sort > $@
parttool.lst: $(PARTTOOLFILES) parttool.lst: $(PARTTOOLFILES)
cat $^ /dev/null | sort | uniq > $@ cat $^ /dev/null | sort | uniq > $@
@ -458,7 +463,26 @@ distcheck: dist
@echo "$(distdir).tar.gz is ready for distribution" | \ @echo "$(distdir).tar.gz is ready for distribution" | \
sed 'h;s/./=/g;p;x;p;x' 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:
.SUFFIX: .c .o .S .d .SUFFIX: .c .o .S .d

View file

@ -26,10 +26,9 @@
#include <grub/i18n.h> #include <grub/i18n.h>
static grub_err_t static grub_err_t
grub_cmd_handler (struct grub_command *cmd, grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)),
int argc, char **args) int argc, char **args)
{ {
char *class_name;
void *curr_item = 0; void *curr_item = 0;
grub_handler_class_t head; grub_handler_class_t head;
@ -44,23 +43,19 @@ grub_cmd_handler (struct grub_command *cmd,
return 0; return 0;
} }
class_name = (grub_strcmp (cmd->name, "handler")) ? (char *) cmd->name : 0;
head = grub_handler_class_list; 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); grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_item);
} }
else else
{ {
char *class_name;
grub_handler_class_t class; grub_handler_class_t class;
if (class_name == 0) class_name = args[0];
{ argc--;
class_name = args[0]; args++;
argc--;
args++;
}
class = grub_named_list_find (GRUB_AS_NAMED_LIST (head), class_name); class = grub_named_list_find (GRUB_AS_NAMED_LIST (head), class_name);
if (! class) if (! class)
@ -90,7 +85,7 @@ grub_cmd_handler (struct grub_command *cmd,
return 0; return 0;
} }
static grub_command_t cmd_handler, cmd_terminal_input, cmd_terminal_output; static grub_command_t cmd_handler;
GRUB_MOD_INIT(handler) GRUB_MOD_INIT(handler)
{ {
@ -98,19 +93,9 @@ GRUB_MOD_INIT(handler)
grub_register_command ("handler", grub_cmd_handler, grub_register_command ("handler", grub_cmd_handler,
N_("[class [handler]]"), N_("[class [handler]]"),
N_("List or select a 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_MOD_FINI(handler)
{ {
grub_unregister_command (cmd_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/i18n.h>
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/normal.h> #include <grub/normal.h>
#include <grub/charset.h>
static grub_err_t static grub_err_t
grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, 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) && if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) &&
(cmd->flags & GRUB_COMMAND_FLAG_CMDLINE)) (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE))
{ {
struct grub_term_output *term;
const char *summary_translated = _(cmd->summary);
char *command_help; char *command_help;
int stringwidth;
grub_uint32_t *unicode_command_help; grub_uint32_t *unicode_command_help;
grub_uint32_t *unicode_last_position; 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) + command_help = grub_malloc (grub_strlen (cmd->name) +
sizeof (" ") - 1 + sizeof (" ") - 1 +
@ -55,28 +55,34 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help, grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help,
&unicode_last_position); &unicode_last_position);
unicode_last_screen_position = unicode_command_help;
stringwidth = 0; FOR_ACTIVE_TERM_OUTPUTS(term)
{
unsigned stringwidth;
grub_uint32_t *unicode_last_screen_position;
while (unicode_last_screen_position < unicode_last_position && unicode_last_screen_position = unicode_command_help;
stringwidth < ((GRUB_TERM_WIDTH / 2) - 2))
{
stringwidth += grub_getcharwidth (*unicode_last_screen_position);
unicode_last_screen_position++;
}
grub_print_ucs4 (unicode_command_help, unicode_last_screen_position); stringwidth = 0;
if ((cnt++) % 2) while (unicode_last_screen_position < unicode_last_position &&
{ stringwidth < ((grub_term_width (term) / 2) - 2))
grub_putchar ('\n'); {
} stringwidth
else += grub_term_getcharwidth (term,
{ *unicode_last_screen_position);
grub_print_spaces (GRUB_TERM_WIDTH / 2 - stringwidth); unicode_last_screen_position++;
} }
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 (command_help);
grub_free (unicode_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) if (argc == 0)
grub_command_iterate (print_command_info); {
grub_command_iterate (print_command_info);
if (!(cnt % 2))
grub_printf ("\n");
}
else else
{ {
int i; int i;

View file

@ -49,13 +49,24 @@ grub_cmd_keystatus (grub_extcmd_t cmd,
if (state[2].set) if (state[2].set)
expect_mods |= GRUB_TERM_STATUS_ALT; expect_mods |= GRUB_TERM_STATUS_ALT;
grub_dprintf ("keystatus", "expect_mods: %d\n", expect_mods);
/* Without arguments, just check whether getkeystatus is supported at /* Without arguments, just check whether getkeystatus is supported at
all. */ all. */
if (!grub_cur_term_input->getkeystatus) if (expect_mods == 0)
return grub_error (GRUB_ERR_TEST_FAILURE, "false"); {
grub_dprintf ("keystatus", "expect_mods: %d\n", expect_mods); grub_term_input_t term;
if (!expect_mods) int nterms = 0;
return 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");
return 0;
}
mods = grub_getkeystatus (); mods = grub_getkeystatus ();
grub_dprintf ("keystatus", "mods: %d\n", mods); 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} {0, 0, 0, 0, 0, 0}
}; };
static grub_uint8_t x, y; static grub_uint16_t *pos;
static void static void
do_print (int n) do_print (int n)
{ {
grub_gotoxy (x, y); grub_term_restore_pos (pos);
/* NOTE: Do not remove the trailing space characters. /* NOTE: Do not remove the trailing space characters.
They are required to clear the line. */ They are required to clear the line. */
grub_printf ("%d ", n); grub_printf ("%d ", n);
@ -64,7 +64,6 @@ static grub_err_t
grub_cmd_sleep (grub_extcmd_t cmd, int argc, char **args) grub_cmd_sleep (grub_extcmd_t cmd, int argc, char **args)
{ {
struct grub_arg_list *state = cmd->state; struct grub_arg_list *state = cmd->state;
grub_uint16_t xy;
int n; int n;
if (argc != 1) if (argc != 1)
@ -78,9 +77,7 @@ grub_cmd_sleep (grub_extcmd_t cmd, int argc, char **args)
return 0; return 0;
} }
xy = grub_getxy (); pos = grub_term_save_pos ();
x = xy >> 8;
y = xy & 0xff;
for (; n; n--) 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)), int argc __attribute__ ((unused)),
char **args __attribute__ ((unused))) char **args __attribute__ ((unused)))
{ {
if (grub_video_set_mode ("1024x768;800x600;640x480", 0) != GRUB_ERR_NONE) grub_err_t err;
return grub_errno;
grub_video_color_t color; grub_video_color_t color;
unsigned int x; unsigned int x;
unsigned int y; unsigned int y;
@ -50,6 +48,10 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)),
const char *str; const char *str;
int texty; 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_get_viewport (&x, &y, &width, &height);
grub_video_create_render_target (&text_layer, 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); 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); color = grub_video_map_rgb (i, 33, 77);
grub_video_fill_rect (color, 0, 0, width, height); grub_video_fill_rect (color, 0, 0, width, height);
grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, 0, 0, grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, 0, 0,
0, 0, width, height); 0, 0, width, height);
grub_video_swap_buffers ();
} }
grub_getkey (); 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/err.c kern/list.c kern/handler.c \
kern/command.c kern/corecmd.c commands/extcmd.c kern/file.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/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 \ kern/rescue_reader.c kern/rescue_parser.c \
lib/arg.c normal/cmdline.c normal/datetime.c normal/misc.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/handler.c normal/auth.c lib/crypto.c normal/autofs.c \
normal/completion.c normal/main.c normal/color.c \ normal/completion.c normal/main.c normal/color.c \
normal/menu.c normal/menu_entry.c normal/menu_viewer.c \ normal/menu.c normal/menu_entry.c \
normal/menu_text.c normal/crypto.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/main.c script/execute.c script/function.c \
script/lexer.c script/script.c grub_script.tab.c \ script/lexer.c script/script.c grub_script.tab.c \
partmap/amiga.c partmap/apple.c partmap/msdos.c partmap/sun.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 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. # Filing systems.
pkglib_MODULES += fshelp.mod fat.mod ufs1.mod ufs2.mod ext2.mod ntfs.mod \ 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 \ 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_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
normal/auth.c normal/autofs.c normal/handler.c \ normal/auth.c normal/autofs.c normal/handler.c \
normal/color.c normal/completion.c normal/datetime.c normal/menu.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/menu_entry.c normal/menu_text.c \
normal/misc.c normal/crypto.c normal/misc.c normal/crypto.c normal/term.c
normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_CFLAGS = $(COMMON_CFLAGS)
normal_mod_LDFLAGS = $(COMMON_LDFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
@ -672,6 +686,11 @@ charset_mod_SOURCES = lib/charset.c
charset_mod_CFLAGS = $(COMMON_CFLAGS) charset_mod_CFLAGS = $(COMMON_CFLAGS)
charset_mod_LDFLAGS = $(COMMON_LDFLAGS) 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 pkglib_MODULES += crypto.mod
crypto_mod_SOURCES = lib/crypto.c crypto_mod_SOURCES = lib/crypto.c
crypto_mod_CFLAGS = $(COMMON_CFLAGS) crypto_mod_CFLAGS = $(COMMON_CFLAGS)

View file

@ -21,7 +21,7 @@ kernel_img_SOURCES = kern/i386/coreboot/startup.S \
kern/i386/halt.c \ kern/i386/halt.c \
kern/main.c kern/device.c \ kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.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/rescue_parser.c kern/rescue_reader.c \
kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.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 \ 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/i386/halt.c \
kern/main.c kern/device.c \ kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.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/rescue_parser.c kern/rescue_reader.c \
kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.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 \ 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_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS) 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. # For aout.mod.
aout_mod_SOURCES = loader/aout.c aout_mod_SOURCES = loader/aout.c
aout_mod_CFLAGS = $(COMMON_CFLAGS) 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_EXPORTS = no
kernel_img_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \ 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/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/rescue_parser.c kern/rescue_reader.c \
kern/$(target_cpu)/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.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 \ 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/ieee1275/cmain.c kern/ieee1275/openfw.c \
kern/main.c kern/device.c \ kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.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/rescue_parser.c kern/rescue_reader.c \
kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \ kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \
kern/env.c \ kern/env.c \

View file

@ -48,7 +48,7 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \
kern/i386/misc.S \ kern/i386/misc.S \
kern/main.c kern/device.c \ kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.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/rescue_parser.c kern/rescue_reader.c \
kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.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 \ 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_CFLAGS = $(COMMON_CFLAGS)
serial_mod_LDFLAGS = $(COMMON_LDFLAGS) 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. # For vbe.mod.
vbe_mod_SOURCES = video/i386/pc/vbe.c vbe_mod_SOURCES = video/i386/pc/vbe.c
vbe_mod_CFLAGS = $(COMMON_CFLAGS) vbe_mod_CFLAGS = $(COMMON_CFLAGS)

View file

@ -25,3 +25,19 @@ pkglib_MODULES += ata.mod
ata_mod_SOURCES = disk/ata.c ata_mod_SOURCES = disk/ata.c
ata_mod_CFLAGS = $(COMMON_CFLAGS) ata_mod_CFLAGS = $(COMMON_CFLAGS)
ata_mod_LDFLAGS = $(COMMON_LDFLAGS) 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 \ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \
kern/ieee1275/ieee1275.c kern/main.c kern/device.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/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/rescue_parser.c kern/rescue_reader.c \
kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/ieee1275/init.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 \ kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \
kern/ieee1275/ieee1275.c kern/main.c kern/device.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/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/rescue_parser.c kern/rescue_reader.c \
kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
kern/sparc64/ieee1275/ieee1275.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 \ pkglib_MODULES = kernel.img chain.mod appleldr.mod \
halt.mod reboot.mod linux.mod pci.mod lspci.mod \ halt.mod reboot.mod linux.mod pci.mod lspci.mod \
datetime.mod date.mod datehook.mod loadbios.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. # For kernel.img.
kernel_img_EXPORTS = no kernel_img_EXPORTS = no
kernel_img_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \ kernel_img_SOURCES = kern/x86_64/efi/startup.S kern/x86_64/efi/callwrap.S \
kern/main.c kern/device.c \ kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.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/rescue_parser.c kern/rescue_reader.c \
kern/$(target_cpu)/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.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 \ 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_CFLAGS = $(COMMON_CFLAGS)
acpi_mod_LDFLAGS = $(COMMON_LDFLAGS) 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. # For mmap.mod.
mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \ mmap_mod_SOURCES = mmap/mmap.c mmap/i386/uppermem.c mmap/i386/mmap.c \
mmap/efi/mmap.c mmap/efi/mmap.c
@ -166,10 +161,5 @@ xnu_mod_CFLAGS = $(COMMON_CFLAGS)
xnu_mod_LDFLAGS = $(COMMON_LDFLAGS) xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
pkglib_MODULES += relocator.mod include $(srcdir)/conf/i386.mk
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/common.mk include $(srcdir)/conf/common.mk

View file

@ -16,8 +16,4 @@
module=$1 module=$1
grep -v "^#" | sed -n \ grep -v "^#" | sed -n \
-e "/grub_parser_register *( *\"/{s/.*( *\"\([^\"]*\)\".*/parser.\1: $module/;p;}" \ -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;}"

View file

@ -192,6 +192,7 @@ endif
fs = 'fs-' + obj.suffix('lst') fs = 'fs-' + obj.suffix('lst')
partmap = 'partmap-' + obj.suffix('lst') partmap = 'partmap-' + obj.suffix('lst')
handler = 'handler-' + obj.suffix('lst') handler = 'handler-' + obj.suffix('lst')
terminal = 'terminal-' + obj.suffix('lst')
parttool = 'parttool-' + obj.suffix('lst') parttool = 'parttool-' + obj.suffix('lst')
video = 'video-' + obj.suffix('lst') video = 'video-' + obj.suffix('lst')
dep = deps[i] dep = deps[i]
@ -213,6 +214,7 @@ FSFILES += #{fs}
PARTTOOLFILES += #{parttool} PARTTOOLFILES += #{parttool}
PARTMAPFILES += #{partmap} PARTMAPFILES += #{partmap}
HANDLERFILES += #{handler} HANDLERFILES += #{handler}
TERMINALFILES += #{terminal}
VIDEOFILES += #{video} VIDEOFILES += #{video}
#{command}: #{src} $(#{src}_DEPENDENCIES) gencmdlist.sh #{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 $< \ $(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) | 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 #{video}: #{src} $(#{src}_DEPENDENCIES) genvideolist.sh
set -e; \ set -e; \
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -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} "CLEANFILES += #{@name}
#{@name}: #{src} $(#{src}_DEPENDENCIES) config.status #{@name}: #{src} $(#{src}_DEPENDENCIES) config.status
./config.status --file=#{name}:#{src} ./config.status --file=-:#{src} | sed -e 's,@pkglib_DATA@,$(pkglib_DATA),g' > $@
sed -i -e 's,@pkglib_DATA@,$(pkglib_DATA),g' $@
chmod +x $@ 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; 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), cur = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_gettext_msg_list),
orig); orig);
if (cur) if (cur)
return cur->translated; {
grub_error_pop ();
return cur->translated;
}
if (fd_mo == 0) if (fd_mo == 0)
return orig; {
grub_error_pop ();
return orig;
}
min = 0; min = 0;
max = grub_gettext_max; max = grub_gettext_max;
@ -205,6 +215,7 @@ grub_gettext_translate (const char *orig)
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
} }
grub_error_pop ();
return ret; return ret;
} }
@ -308,7 +319,7 @@ grub_gettext_delete_list (void)
char *original = (char *) ((struct grub_gettext_msg *) item)->name; char *original = (char *) ((struct grub_gettext_msg *) item)->name;
grub_free (original); 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_gettext_init_ext (lang);
grub_register_command_p1 ("gettext", grub_cmd_translate, grub_register_command_p1 ("gettext", grub_cmd_translate,
"STRING", N_("STRING"),
"Translates the string with the current settings."); N_("Translates the string with the current settings."));
/* Reload .mo file information if lang changes. */ /* Reload .mo file information if lang changes. */
grub_register_variable_hook ("lang", NULL, grub_gettext_env_write_lang); 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; 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 #endif

View file

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

View file

@ -1,6 +1,6 @@
/* /*
* GRUB -- GRand Unified Bootloader * 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 * GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * 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_tmp_addr);
extern char *EXPORT_VAR(grub_linux_real_addr); extern char *EXPORT_VAR(grub_linux_real_addr);
extern grub_int32_t EXPORT_VAR(grub_linux_is_bzimage); 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
#endif /* ! GRUB_LOADER_CPU_HEADER */ #endif /* ! GRUB_LOADER_CPU_HEADER */

View file

@ -24,20 +24,25 @@
#include <grub/symbol.h> #include <grub/symbol.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/menu.h> #include <grub/menu.h>
#include <grub/term.h>
struct grub_menu_viewer 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; 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 */ #endif /* GRUB_MENU_VIEWER_HEADER */

View file

@ -199,11 +199,11 @@ int EXPORT_FUNC(grub_sprintf) (char *str, const char *fmt, ...) __attribute__ ((
int EXPORT_FUNC(grub_vsprintf) (char *str, const char *fmt, va_list args); 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_exit) (void) __attribute__ ((noreturn));
void EXPORT_FUNC(grub_abort) (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, grub_size_t destsize,
const grub_uint8_t *src, const grub_uint8_t *src,
grub_size_t srcsize, grub_size_t srcsize,
const grub_uint8_t **srcend); const grub_uint8_t **srcend);
grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
grub_uint32_t d, grub_uint32_t *r); grub_uint32_t d, grub_uint32_t *r);

View file

@ -29,7 +29,22 @@
#include <multiboot.h> #include <multiboot.h>
#endif #endif
#include <grub/types.h>
#include <grub/err.h>
void grub_multiboot (int argc, char *argv[]); void grub_multiboot (int argc, char *argv[]);
void grub_module (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 */ #endif /* ! GRUB_MULTIBOOT_HEADER */

View file

@ -20,6 +20,7 @@
#ifndef GRUB_NORMAL_HEADER #ifndef GRUB_NORMAL_HEADER
#define GRUB_NORMAL_HEADER 1 #define GRUB_NORMAL_HEADER 1
#include <grub/term.h>
#include <grub/symbol.h> #include <grub/symbol.h>
#include <grub/err.h> #include <grub/err.h>
#include <grub/env.h> #include <grub/env.h>
@ -45,21 +46,21 @@ enum grub_completion_type
typedef enum grub_completion_type grub_completion_type_t; typedef enum grub_completion_type grub_completion_type_t;
extern struct grub_menu_viewer grub_normal_text_menu_viewer; extern struct grub_menu_viewer grub_normal_text_menu_viewer;
extern int grub_normal_exit_level;
/* Defined in `main.c'. */ /* Defined in `main.c'. */
void grub_enter_normal_mode (const char *config); void grub_enter_normal_mode (const char *config);
void grub_normal_execute (const char *config, int nested, int batch); 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, grub_err_t grub_normal_add_menu_entry (int argc, const char **args,
const char *sourcecode); const char *sourcecode);
char *grub_file_getline (grub_file_t file); char *grub_file_getline (grub_file_t file);
void grub_cmdline_run (int nested); void grub_cmdline_run (int nested);
/* Defined in `cmdline.c'. */ /* Defined in `cmdline.c'. */
int grub_cmdline_get (const char *prompt, char cmdline[], unsigned max_len, char *grub_cmdline_get (const char *prompt);
int echo_char, int readline, int history);
grub_err_t grub_set_history (int newsize); grub_err_t grub_set_history (int newsize);
/* Defined in `completion.c'. */ /* 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'. */ /* Defined in `menu_text.c'. */
void grub_wait_after_message (void); 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, 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, 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, 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'. */ /* Defined in `handler.c'. */
void read_handler_list (void); void read_handler_list (void);
@ -97,6 +103,9 @@ void read_fs_list (void);
void read_crypto_list (void); void read_crypto_list (void);
void read_terminal_list (void);
void grub_set_more (int onoff);
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
void grub_normal_init (void); void grub_normal_init (void);

View file

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

View file

@ -20,60 +20,10 @@
#ifndef GRUB_READER_HEADER #ifndef GRUB_READER_HEADER
#define GRUB_READER_HEADER 1 #define GRUB_READER_HEADER 1
#include <grub/types.h>
#include <grub/err.h> #include <grub/err.h>
#include <grub/handler.h>
typedef grub_err_t (*grub_reader_getline_t) (char **, int); typedef grub_err_t (*grub_reader_getline_t) (char **, int);
struct grub_reader void grub_rescue_run (void);
{
/* 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);
#endif /* ! GRUB_READER_HEADER */ #endif /* ! GRUB_READER_HEADER */

View file

@ -1,6 +1,6 @@
/* /*
* GRUB -- GRand Unified Bootloader * 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 * GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * 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) #define GRUB_TERM_NO_EDIT (1 << 1)
/* Set when the terminal cannot do fancy things. */ /* Set when the terminal cannot do fancy things. */
#define GRUB_TERM_DUMB (1 << 2) #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. */ /* Bitmasks for modifier keys returned by grub_getkeystatus. */
@ -93,10 +91,6 @@ grub_term_color_state;
/* Menu-related geometrical constants. */ /* 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. */ /* The number of lines of "GRUB version..." at the top. */
#define GRUB_TERM_INFO_HEIGHT 1 #define GRUB_TERM_INFO_HEIGHT 1
@ -113,37 +107,12 @@ grub_term_color_state;
/* The X position of the left border. */ /* The X position of the left border. */
#define GRUB_TERM_LEFT_BORDER_X GRUB_TERM_MARGIN #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. */ /* The number of lines of messages at the bottom. */
#define GRUB_TERM_MESSAGE_HEIGHT 8 #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. */ /* The Y position of the first entry. */
#define GRUB_TERM_FIRST_ENTRY_Y (GRUB_TERM_TOP_BORDER_Y + 1) #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 struct grub_term_input
{ {
/* The next terminal. */ /* The next terminal. */
@ -224,86 +193,222 @@ struct grub_term_output
}; };
typedef struct grub_term_output *grub_term_output_t; typedef struct grub_term_output *grub_term_output_t;
extern struct grub_handler_class EXPORT_VAR(grub_term_input_class); extern struct grub_term_output *EXPORT_VAR(grub_term_outputs_disabled);
extern struct grub_handler_class EXPORT_VAR(grub_term_output_class); 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 static inline void
grub_term_register_input (const char *name __attribute__ ((unused)), grub_term_register_input (const char *name __attribute__ ((unused)),
grub_term_input_t term) 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 static inline void
grub_term_register_output (const char *name __attribute__ ((unused)), grub_term_register_output (const char *name __attribute__ ((unused)),
grub_term_output_t term) 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 static inline void
grub_term_unregister_input (grub_term_input_t term) 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 static inline void
grub_term_unregister_output (grub_term_output_t term) 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 #define FOR_ACTIVE_TERM_INPUTS(var) for (var = grub_term_inputs; var; var = var->next)
grub_term_set_current_input (grub_term_input_t term) #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)
return grub_handler_set_current (&grub_term_input_class, #define FOR_DISABLED_TERM_OUTPUTS(var) for (var = grub_term_outputs_disabled; var; var = var->next)
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;
}
void EXPORT_FUNC(grub_putchar) (int c); void EXPORT_FUNC(grub_putchar) (int c);
void EXPORT_FUNC(grub_putcode) (grub_uint32_t code); void EXPORT_FUNC(grub_putcode) (grub_uint32_t code,
grub_ssize_t EXPORT_FUNC(grub_getcharwidth) (grub_uint32_t code); struct grub_term_output *term);
int EXPORT_FUNC(grub_getkey) (void); int EXPORT_FUNC(grub_getkey) (void);
int EXPORT_FUNC(grub_checkkey) (void); int EXPORT_FUNC(grub_checkkey) (void);
int EXPORT_FUNC(grub_getkeystatus) (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_cls) (void);
void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state); 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_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 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) while (--number_spaces >= 0)
grub_putchar (' '); grub_putcode (' ', term);
} }

View file

@ -21,15 +21,17 @@
#include <grub/err.h> #include <grub/err.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/term.h>
char *grub_terminfo_get_current (void); char *grub_terminfo_get_current (void);
grub_err_t grub_terminfo_set_current (const char *); grub_err_t grub_terminfo_set_current (const char *);
void grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y); void grub_terminfo_gotoxy (grub_uint8_t x, grub_uint8_t y,
void grub_terminfo_cls (void); grub_term_output_t oterm);
void grub_terminfo_reverse_video_on (void); void grub_terminfo_cls (grub_term_output_t oterm);
void grub_terminfo_reverse_video_off (void); void grub_terminfo_reverse_video_on (grub_term_output_t oterm);
void grub_terminfo_cursor_on (void); void grub_terminfo_reverse_video_off (grub_term_output_t oterm);
void grub_terminfo_cursor_off (void); void grub_terminfo_cursor_on (grub_term_output_t oterm);
void grub_terminfo_cursor_off (grub_term_output_t oterm);
#endif /* ! GRUB_TERMINFO_HEADER */ #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). */ 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 struct grub_video_adapter
{ {
/* The video adapter name. */ /* The video adapter name. */
const char *name; const char *name;
grub_video_driver_id_t id;
/* Initialize the video adapter. */ /* Initialize the video adapter. */
grub_err_t (*init) (void); grub_err_t (*init) (void);
@ -171,7 +180,7 @@ struct grub_video_adapter
grub_err_t (*fini) (void); grub_err_t (*fini) (void);
grub_err_t (*setup) (unsigned int width, unsigned int height, 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); 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_get_active_render_target (struct grub_video_render_target **target);
grub_err_t grub_video_set_mode (const char *modestring, grub_err_t grub_video_set_mode (const char *modestring,
int NESTED_FUNC_ATTR (*hook) (grub_video_adapter_t p, unsigned int modemask,
struct grub_video_mode_info *mode_info)); 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 */ #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 #define MULTIBOOT_INFO_APM_TABLE 0x00000400
/* Is there video information? */ /* 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 #ifndef ASM_FILE
typedef unsigned char multiboot_uint8_t;
typedef unsigned short multiboot_uint16_t; typedef unsigned short multiboot_uint16_t;
typedef unsigned int multiboot_uint32_t; typedef unsigned int multiboot_uint32_t;
typedef unsigned long long multiboot_uint64_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_seg;
multiboot_uint16_t vbe_interface_off; multiboot_uint16_t vbe_interface_off;
multiboot_uint16_t vbe_interface_len; 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; 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 struct multiboot_mmap_entry
{ {
multiboot_uint32_t size; multiboot_uint32_t size;

View file

@ -85,10 +85,12 @@
#define MULTIBOOT_INFO_APM_TABLE 0x00000400 #define MULTIBOOT_INFO_APM_TABLE 0x00000400
/* Is there video information? */ /* 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 #ifndef ASM_FILE
typedef unsigned char multiboot_uint8_t;
typedef unsigned short multiboot_uint16_t; typedef unsigned short multiboot_uint16_t;
typedef unsigned int multiboot_uint32_t; typedef unsigned int multiboot_uint32_t;
typedef unsigned long long multiboot_uint64_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_seg;
multiboot_uint16_t vbe_interface_off; multiboot_uint16_t vbe_interface_off;
multiboot_uint16_t vbe_interface_len; 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; 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 struct multiboot_mmap_entry
{ {
multiboot_uint32_t size; multiboot_uint32_t size;

View file

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

View file

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

View file

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

View file

@ -169,9 +169,8 @@ grub_main (void)
grub_register_core_commands (); grub_register_core_commands ();
grub_register_rescue_parser (); grub_register_rescue_parser ();
grub_register_rescue_reader ();
grub_load_config (); grub_load_config ();
grub_load_normal_mode (); 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 /* 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. 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 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 If SRCEND is not NULL, then *SRCEND is set to the next byte after the
last byte used in SRC. */ last byte used in SRC. */
grub_ssize_t grub_size_t
grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize, 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 *src, grub_size_t srcsize,
const grub_uint8_t **srcend) 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) if ((c & 0xc0) != 0x80)
{ {
/* invalid */ /* invalid */
return -1; code = '?';
count = 0;
} }
else else
{ {
@ -959,7 +960,11 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
code = c & 0x01; code = c & 0x01;
} }
else else
return -1; {
/* invalid */
code = '?';
count = 0;
}
} }
if (count == 0) if (count == 0)
@ -978,15 +983,14 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
void void
grub_abort (void) grub_abort (void)
{ {
if (grub_term_get_current_output ()) grub_printf ("\nAborted.");
#ifndef GRUB_UTIL
if (grub_term_inputs)
#endif
{ {
grub_printf ("\nAborted."); grub_printf (" Press any key to exit.");
grub_getkey ();
if (grub_term_get_current_input ())
{
grub_printf (" Press any key to exit.");
grub_getkey ();
}
} }
grub_exit (); 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/types.h>
#include <grub/reader.h> #include <grub/reader.h>
#include <grub/parser.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/term.h> #include <grub/term.h>
#include <grub/mm.h>
#define GRUB_RESCUE_BUF_SIZE 256 #define GRUB_RESCUE_BUF_SIZE 256
static char linebuf[GRUB_RESCUE_BUF_SIZE]; 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. */ /* Prompt to input a command and read the line. */
static grub_err_t static grub_err_t
grub_rescue_read_line (char **line, int cont) grub_rescue_read_line (char **line, int cont)
@ -74,15 +69,24 @@ grub_rescue_read_line (char **line, int cont)
return 0; return 0;
} }
static struct grub_reader grub_rescue_reader =
{
.name = "rescue",
.init = grub_rescue_init,
.read_line = grub_rescue_read_line
};
void 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/mm.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/env.h> #include <grub/env.h>
#include <grub/time.h>
/* The amount of lines counted by the pager. */ struct grub_term_output *grub_term_outputs_disabled;
static int grub_more_lines; 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. */ void (*grub_newline_hook) (void) = NULL;
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 ()
/* Put a Unicode character. */ /* Put a Unicode character. */
void 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' && term->getxy)
if (code == '\t' && grub_cur_term_output->getxy)
{ {
int n; int n;
n = 8 - ((grub_getxy () >> 8) & 7); n = 8 - ((term->getxy () >> 8) & 7);
while (n--) while (n--)
grub_putcode (' '); grub_putcode (' ', term);
return; return;
} }
(grub_cur_term_output->putchar) (code); (term->putchar) (code);
if (code == '\n') if (code == '\n')
{ (term->putchar) ('\r');
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;
}
}
} }
/* Put a character. C is one byte of a UTF-8 stream. /* 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_size_t size = 0;
static grub_uint8_t buf[6]; static grub_uint8_t buf[6];
grub_uint32_t code; grub_uint32_t code;
grub_ssize_t ret; grub_size_t ret;
buf[size++] = c; buf[size++] = c;
ret = grub_utf8_to_ucs4 (&code, 1, buf, size, 0); ret = grub_utf8_to_ucs4 (&code, 1, buf, size, 0);
if (ret > 0) if (ret != 0)
{ {
struct grub_term_output *term;
size = 0; 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 int
grub_getkey (void) 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 int
grub_checkkey (void) 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 int
grub_getkeystatus (void) grub_getkeystatus (void)
{ {
if (grub_cur_term_input->getkeystatus) int status = 0;
return (grub_cur_term_input->getkeystatus) (); grub_term_input_t term;
else
return 0;
}
grub_uint16_t FOR_ACTIVE_TERM_INPUTS(term)
grub_getxy (void) {
{ if (term->getkeystatus)
return (grub_cur_term_output->getxy) (); status |= term->getkeystatus ();
} }
grub_uint16_t return status;
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);
} }
void void
grub_cls (void) grub_cls (void)
{ {
if ((grub_cur_term_output->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug"))) struct grub_term_output *term;
{
grub_putchar ('\n'); FOR_ACTIVE_TERM_OUTPUTS(term)
grub_refresh (); {
} if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
else {
(grub_cur_term_output->cls) (); grub_putcode ('\n', term);
grub_term_refresh (term);
}
else
(term->cls) ();
}
} }
void void
grub_setcolorstate (grub_term_color_state state) grub_setcolorstate (grub_term_color_state state)
{ {
if (grub_cur_term_output->setcolorstate) struct grub_term_output *term;
(grub_cur_term_output->setcolorstate) (state);
} FOR_ACTIVE_TERM_OUTPUTS(term)
grub_term_setcolorstate (term, state);
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;
} }
void void
grub_refresh (void) grub_refresh (void)
{ {
if (grub_cur_term_output->refresh) struct grub_term_output *term;
(grub_cur_term_output->refresh) ();
}
void FOR_ACTIVE_TERM_OUTPUTS(term)
grub_set_more (int onoff) grub_term_refresh (term);
{
if (onoff == 1)
grub_more++;
else
grub_more--;
grub_more_lines = 0;
} }

View file

@ -24,6 +24,8 @@
last byte used in SRC. */ last byte used in SRC. */
#include <grub/charset.h> #include <grub/charset.h>
#include <grub/mm.h>
#include <grub/misc.h>
grub_ssize_t grub_ssize_t
grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize, 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; *srcend = src;
return p - dest; 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/api.h>
#include <grub/efi/efi.h> #include <grub/efi/efi.h>
#include <grub/command.h> #include <grub/command.h>
#include <grub/i18n.h>
static grub_dl_t my_mod; static grub_dl_t my_mod;
@ -321,7 +322,7 @@ static grub_command_t cmd;
GRUB_MOD_INIT(appleloader) GRUB_MOD_INIT(appleloader)
{ {
cmd = grub_register_command ("appleloader", grub_cmd_appleloader, cmd = grub_register_command ("appleloader", grub_cmd_appleloader,
"[OPTS]", "Boot legacy system."); "[OPTS]", N_("Boot legacy system."));
my_mod = mod; my_mod = mod;
} }

View file

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

View file

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

View file

@ -33,6 +33,7 @@
#include <grub/pci.h> #include <grub/pci.h>
#include <grub/command.h> #include <grub/command.h>
#include <grub/memory.h> #include <grub/memory.h>
#include <grub/i18n.h>
#define GRUB_LINUX_CL_OFFSET 0x1000 #define GRUB_LINUX_CL_OFFSET 0x1000
#define GRUB_LINUX_CL_END_OFFSET 0x2000 #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_mask_size = 8;
params->reserved_field_pos = 24; 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 */ params->vid_mode = 0x338; /* 1024x768x32 */
return 0; 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)) 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; goto fail;
} }
@ -693,13 +694,32 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
params->ext_mem = ((32 * 0x100000) >> 10); params->ext_mem = ((32 * 0x100000) >> 10);
params->alt_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_page = 0; /* ??? */
params->video_mode = grub_efi_system_table->con_out->mode->mode; params->video_mode = grub_efi_system_table->con_out->mode->mode;
params->video_width = (grub_getwh () >> 8);
params->video_ega_bx = 0; params->video_ega_bx = 0;
params->video_height = (grub_getwh () & 0xff);
params->have_vga = 0; params->have_vga = 0;
params->font_size = 16; /* XXX */ 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) else if (grub_memcmp (argv[i], "video=efifb", 11) == 0)
{ {
if (params->have_vga) if (params->have_vga)
params->have_vga = GRUB_VIDEO_TYPE_EFI; params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
} }
/* Specify the boot file. */ /* Specify the boot file. */
@ -989,9 +1009,9 @@ static grub_command_t cmd_linux, cmd_initrd;
GRUB_MOD_INIT(linux) GRUB_MOD_INIT(linux)
{ {
cmd_linux = grub_register_command ("linux", grub_cmd_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, cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
0, "Load initrd."); 0, N_("Load initrd."));
my_mod = mod; my_mod = mod;
} }

View file

@ -1,7 +1,7 @@
/* linux.c - boot Linux zImage or bzImage */ /* linux.c - boot Linux zImage or bzImage */
/* /*
* GRUB -- GRand Unified Bootloader * 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 * GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -32,6 +32,7 @@
#include <grub/cpu/linux.h> #include <grub/cpu/linux.h>
#include <grub/ieee1275/ieee1275.h> #include <grub/ieee1275/ieee1275.h>
#include <grub/command.h> #include <grub/command.h>
#include <grub/i18n.h>
#define GRUB_OFW_LINUX_PARAMS_ADDR 0x90000 #define GRUB_OFW_LINUX_PARAMS_ADDR 0x90000
#define GRUB_OFW_LINUX_KERNEL_ADDR 0x100000 #define GRUB_OFW_LINUX_KERNEL_ADDR 0x100000
@ -109,8 +110,29 @@ grub_linux_boot (void)
params->cl_magic = GRUB_LINUX_CL_MAGIC; params->cl_magic = GRUB_LINUX_CL_MAGIC;
params->cl_offset = GRUB_OFW_LINUX_CL_OFFSET; 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->font_size = 16;
params->ofw_signature = GRUB_LINUX_OFW_SIGNATURE; 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)) 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; goto fail;
} }
@ -276,9 +298,9 @@ static grub_command_t cmd_linux, cmd_initrd;
GRUB_MOD_INIT(linux) GRUB_MOD_INIT(linux)
{ {
cmd_linux = grub_register_command ("linux", grub_cmd_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, cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
0, "Load initrd."); 0, N_("Load initrd."));
my_mod = mod; my_mod = mod;
} }

View file

@ -1,6 +1,6 @@
/* /*
* GRUB -- GRand Unified Bootloader * 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 * GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -33,6 +33,8 @@
#include <grub/video_fb.h> #include <grub/video_fb.h>
#include <grub/command.h> #include <grub/command.h>
#include <grub/i386/pc/vbe.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_OFFSET 0x1000
#define GRUB_LINUX_CL_END_OFFSET 0x2000 #define GRUB_LINUX_CL_END_OFFSET 0x2000
@ -522,11 +524,11 @@ grub_linux_boot (void)
if (! tmp) if (! tmp)
return grub_errno; return grub_errno;
grub_sprintf (tmp, "%s;text", modevar); grub_sprintf (tmp, "%s;text", modevar);
err = grub_video_set_mode (tmp, 0); err = grub_video_set_mode (tmp, 0, 0);
grub_free (tmp); grub_free (tmp);
} }
else else
err = grub_video_set_mode ("text", 0); err = grub_video_set_mode ("text", 0, 0);
if (err) if (err)
{ {
@ -536,19 +538,34 @@ grub_linux_boot (void)
} }
if (! grub_linux_setup_video (params)) if (! grub_linux_setup_video (params))
params->have_vga = GRUB_VIDEO_TYPE_VLFB; params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA;
else else
{ {
params->have_vga = GRUB_VIDEO_TYPE_TEXT; params->have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT;
params->video_width = 80; params->video_width = 80;
params->video_height = 25; params->video_height = 25;
} }
/* Initialize these last, because terminal position could be affected by printfs above. */ /* 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; grub_term_output_t term;
params->video_cursor_y = grub_getxy () & 0xff; 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__ #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)) 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; goto fail;
} }
@ -712,8 +729,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE); 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); (unsigned) real_size, (unsigned) prot_size);
/* Look for memory size and video mode specified on the command line. */ /* Look for memory size and video mode specified on the command line. */
linux_mem_size = 0; linux_mem_size = 0;
@ -963,8 +980,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
goto fail; 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); (unsigned) addr, (unsigned) size);
lh->ramdisk_image = addr; lh->ramdisk_image = addr;
lh->ramdisk_size = size; lh->ramdisk_size = size;
@ -982,9 +999,9 @@ static grub_command_t cmd_linux, cmd_initrd;
GRUB_MOD_INIT(linux) GRUB_MOD_INIT(linux)
{ {
cmd_linux = grub_register_command ("linux", grub_cmd_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, cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
0, "Load initrd."); 0, N_("Load initrd."));
my_mod = mod; my_mod = mod;
} }

View file

@ -1,7 +1,7 @@
/* multiboot.c - boot a multiboot OS image. */ /* multiboot.c - boot a multiboot OS image. */
/* /*
* GRUB -- GRand Unified Bootloader * 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 * GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * 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. */ /* 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/loader.h>
#include <grub/machine/loader.h> #include <grub/machine/loader.h>
#include <grub/multiboot.h> #include <grub/multiboot.h>
#include <grub/machine/init.h>
#include <grub/machine/memory.h>
#include <grub/cpu/multiboot.h> #include <grub/cpu/multiboot.h>
#include <grub/elf.h> #include <grub/elf.h>
#include <grub/aout.h> #include <grub/aout.h>
@ -45,31 +43,29 @@
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/gzio.h> #include <grub/gzio.h>
#include <grub/env.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/i386/relocator.h>
#include <grub/video.h>
#ifdef GRUB_MACHINE_EFI
#include <grub/efi/efi.h>
#endif
extern grub_dl_t my_mod; extern grub_dl_t my_mod;
static struct multiboot_info *mbi, *mbi_dest; static grub_size_t code_size, alloc_mbi;
static grub_size_t code_size;
char *grub_multiboot_payload_orig; char *grub_multiboot_payload_orig;
grub_addr_t grub_multiboot_payload_dest; 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; grub_uint32_t grub_multiboot_payload_eip;
static grub_err_t static grub_err_t
grub_multiboot_boot (void) grub_multiboot_boot (void)
{ {
grub_size_t mbi_size;
grub_err_t err;
struct grub_relocator32_state state = struct grub_relocator32_state state =
{ {
.eax = MULTIBOOT_BOOTLOADER_MAGIC, .eax = MULTIBOOT_BOOTLOADER_MAGIC,
.ebx = PTR_TO_UINT32 (mbi_dest),
.ecx = 0, .ecx = 0,
.edx = 0, .edx = 0,
.eip = grub_multiboot_payload_eip, .eip = grub_multiboot_payload_eip,
@ -78,6 +74,29 @@ grub_multiboot_boot (void)
.esp = 0x7ff00 .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_relocator32_boot (grub_multiboot_payload_orig,
grub_multiboot_payload_dest, grub_multiboot_payload_dest,
state); state);
@ -89,69 +108,18 @@ grub_multiboot_boot (void)
static grub_err_t static grub_err_t
grub_multiboot_unload (void) grub_multiboot_unload (void)
{ {
if (mbi) grub_multiboot_free_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_relocator32_free (grub_multiboot_payload_orig); grub_relocator32_free (grub_multiboot_payload_orig);
mbi = NULL; alloc_mbi = 0;
grub_multiboot_payload_orig = NULL; grub_multiboot_payload_orig = NULL;
grub_dl_unref (my_mod); grub_dl_unref (my_mod);
return GRUB_ERR_NONE; 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 #define MULTIBOOT_LOAD_ELF64
#include "multiboot_elfxx.c" #include "multiboot_elfxx.c"
#undef MULTIBOOT_LOAD_ELF64 #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"); 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 void
grub_multiboot (int argc, char *argv[]) grub_multiboot (int argc, char *argv[])
{ {
grub_file_t file = 0; grub_file_t file = 0;
char buffer[MULTIBOOT_SEARCH], *cmdline = 0, *p; char buffer[MULTIBOOT_SEARCH];
struct multiboot_header *header; struct multiboot_header *header;
grub_ssize_t len, cmdline_length, boot_loader_name_length; grub_ssize_t len;
grub_uint32_t mmap_length;
int i;
int cmdline_argc;
char **cmdline_argv;
grub_loader_unset (); grub_loader_unset ();
@ -274,31 +197,8 @@ grub_multiboot (int argc, char *argv[])
grub_relocator32_free (grub_multiboot_payload_orig); grub_relocator32_free (grub_multiboot_payload_orig);
grub_multiboot_payload_orig = NULL; grub_multiboot_payload_orig = NULL;
mmap_length = grub_get_multiboot_mmap_len ();
/* Figure out cmdline length. */
/* Skip filename. */ /* Skip filename. */
cmdline_argc = argc - 1; grub_multiboot_init_mbi (argc - 1, argv + 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;
if (header->flags & MULTIBOOT_AOUT_KLUDGE) if (header->flags & MULTIBOOT_AOUT_KLUDGE)
{ {
@ -313,10 +213,12 @@ grub_multiboot (int argc, char *argv[])
code_size = load_size; code_size = load_size;
grub_multiboot_payload_dest = header->load_addr; 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_multiboot_payload_orig
= grub_relocator32_alloc (grub_multiboot_payload_size); = grub_relocator32_alloc (grub_multiboot_pure_size + alloc_mbi);
if (! grub_multiboot_payload_orig) if (! grub_multiboot_payload_orig)
goto fail; goto fail;
@ -338,53 +240,37 @@ grub_multiboot (int argc, char *argv[])
else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE) else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE)
goto fail; goto fail;
/* This provides alignment for the MBI, the memory map and the backward relocator. */ if (header->flags & MULTIBOOT_VIDEO_MODE)
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++)
{ {
p = grub_stpcpy (p, cmdline_argv[i]); switch (header->mode_type)
*(p++) = ' '; {
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. */ grub_multiboot_set_accepts_video (!!(header->flags & MULTIBOOT_VIDEO_MODE));
if (p != cmdline)
p--;
*p = 0;
mbi->flags |= MULTIBOOT_INFO_CMDLINE; grub_multiboot_set_bootdev ();
mbi->cmdline = (grub_uint32_t) cmdline_addr (grub_multiboot_payload_dest);
grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0);
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);
fail: fail:
if (file) if (file)
@ -392,22 +278,18 @@ grub_multiboot (int argc, char *argv[])
if (grub_errno != GRUB_ERR_NONE) if (grub_errno != GRUB_ERR_NONE)
{ {
grub_free (cmdline); grub_relocator32_free (grub_multiboot_payload_orig);
grub_free (mbi);
grub_dl_unref (my_mod); grub_dl_unref (my_mod);
} }
} }
void void
grub_module (int argc, char *argv[]) grub_module (int argc, char *argv[])
{ {
grub_file_t file = 0; grub_file_t file = 0;
grub_ssize_t size, len = 0; grub_ssize_t size;
char *module = 0, *cmdline = 0, *p; char *module = 0;
int i; grub_err_t err;
int cmdline_argc;
char **cmdline_argv;
if (argc == 0) if (argc == 0)
{ {
@ -415,7 +297,7 @@ grub_module (int argc, char *argv[])
goto fail; goto fail;
} }
if (!mbi) if (!grub_multiboot_payload_orig)
{ {
grub_error (GRUB_ERR_BAD_ARGUMENT, grub_error (GRUB_ERR_BAD_ARGUMENT,
"you need to load the multiboot kernel first"); "you need to load the multiboot kernel first");
@ -431,73 +313,19 @@ grub_module (int argc, char *argv[])
if (! module) if (! module)
goto fail; 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) if (grub_file_read (file, module, size) != size)
{ {
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
goto fail; 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: fail:
if (file) if (file)
grub_file_close (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; 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_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_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) if (!grub_multiboot_payload_orig)
return grub_errno; 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 */ /* chainloader.c - boot another boot loader */
/* /*
* GRUB -- GRand Unified Bootloader * 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 * GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -32,6 +32,9 @@
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/command.h> #include <grub/command.h>
#include <grub/machine/biosnum.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 grub_dl_t my_mod;
static int boot_drive; static int boot_drive;
@ -40,6 +43,7 @@ static void *boot_part_addr;
static grub_err_t static grub_err_t
grub_chainloader_boot (void) grub_chainloader_boot (void)
{ {
grub_video_set_mode ("text", 0, 0);
grub_chainloader_real_boot (boot_drive, boot_part_addr); grub_chainloader_real_boot (boot_drive, boot_part_addr);
/* Never reach here. */ /* Never reach here. */
@ -146,7 +150,7 @@ static grub_command_t cmd;
GRUB_MOD_INIT(chainloader) GRUB_MOD_INIT(chainloader)
{ {
cmd = grub_register_command ("chainloader", grub_cmd_chainloader, cmd = grub_register_command ("chainloader", grub_cmd_chainloader,
0, "Load another boot loader."); 0, N_("Load another boot loader."));
my_mod = mod; my_mod = mod;
} }

View file

@ -1,7 +1,7 @@
/* linux.c - boot Linux zImage or bzImage */ /* linux.c - boot Linux zImage or bzImage */
/* /*
* GRUB -- GRand Unified Bootloader * 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 * GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -30,6 +30,9 @@
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/cpu/linux.h> #include <grub/cpu/linux.h>
#include <grub/command.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_OFFSET 0x9000
#define GRUB_LINUX_CL_END_OFFSET 0x90FF #define GRUB_LINUX_CL_END_OFFSET 0x90FF
@ -47,6 +50,16 @@ grub_linux_unload (void)
return GRUB_ERR_NONE; 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 static grub_err_t
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[]) 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)) 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; goto fail;
} }
@ -383,10 +396,10 @@ GRUB_MOD_INIT(linux16)
{ {
cmd_linux = cmd_linux =
grub_register_command ("linux16", grub_cmd_linux, grub_register_command ("linux16", grub_cmd_linux,
0, "Load Linux."); 0, N_("Load Linux."));
cmd_initrd = cmd_initrd =
grub_register_command ("initrd16", grub_cmd_initrd, grub_register_command ("initrd16", grub_cmd_initrd,
0, "Load initrd."); 0, N_("Load initrd."));
my_mod = mod; 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 min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b))
#define DEFAULT_VIDEO_MODE "1024x768x32,800x600x32,640x480x32" #define DEFAULT_VIDEO_MODE "auto"
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;
}
/* Setup video for xnu. */ /* Setup video for xnu. */
grub_err_t grub_err_t
@ -48,8 +39,12 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params)
grub_err_t err; grub_err_t err;
modevar = grub_env_get ("gfxpayload"); modevar = grub_env_get ("gfxpayload");
/* Consider only graphical 32-bit deep modes. */
if (! modevar || *modevar == 0) 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 else
{ {
tmp = grub_malloc (grub_strlen (modevar) 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, return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't allocate temporary storag"); "couldn't allocate temporary storag");
grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); 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); grub_free (tmp);
} }

View file

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

View file

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

View file

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

View file

@ -27,6 +27,7 @@
#include <grub/machine/loader.h> #include <grub/machine/loader.h>
#include <grub/gzio.h> #include <grub/gzio.h>
#include <grub/command.h> #include <grub/command.h>
#include <grub/i18n.h>
static grub_dl_t my_mod; 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, return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't map physical 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_addr, paddr, linux_size);
linux_paddr = paddr; linux_paddr = paddr;
@ -516,9 +517,9 @@ GRUB_MOD_INIT(linux)
fetch_translations (); fetch_translations ();
cmd_linux = grub_register_command ("linux", grub_cmd_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, cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
0, "Load initrd."); 0, N_("Load initrd."));
my_mod = mod; my_mod = mod;
} }

View file

@ -32,6 +32,7 @@
#include <grub/command.h> #include <grub/command.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/env.h> #include <grub/env.h>
#include <grub/i18n.h>
struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0; struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0;
static int driverspackagenum = 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) GRUB_MOD_INIT(xnu)
{ {
cmd_kernel = grub_register_command ("xnu_kernel", grub_cmd_xnu_kernel, 0, 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, 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, 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, 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, cmd_kextdir = grub_register_command ("xnu_kextdir", grub_cmd_xnu_kextdir,
"DIRECTORY [OSBundleRequired]", N_("DIRECTORY [OSBundleRequired]"),
"Load XNU extension directory."); N_("Load XNU extension directory."));
cmd_ramdisk = grub_register_command ("xnu_ramdisk", grub_cmd_xnu_ramdisk, 0, cmd_ramdisk = grub_register_command ("xnu_ramdisk", grub_cmd_xnu_ramdisk, 0,
"Load XNU ramdisk. " N_("Load XNU ramdisk. "
"It will be seen as md0."); "It will be seen as md0."));
cmd_splash = grub_register_command ("xnu_splash", grub_cmd_xnu_splash, 0, 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 #ifndef GRUB_UTIL
cmd_resume = grub_register_command ("xnu_resume", grub_cmd_xnu_resume, cmd_resume = grub_register_command ("xnu_resume", grub_cmd_xnu_resume,
0, "Load XNU hibernate image."); 0, N_("Load XNU hibernate image."));
#endif #endif
grub_cpu_xnu_init (); grub_cpu_xnu_init ();

View file

@ -154,6 +154,49 @@ is_authenticated (const char *userlist)
return grub_list_iterate (GRUB_AS_LIST (users), hook); 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_err_t
grub_auth_check_authentication (const char *userlist) grub_auth_check_authentication (const char *userlist)
{ {
@ -187,11 +230,12 @@ grub_auth_check_authentication (const char *userlist)
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
if (!grub_cmdline_get (N_("Enter username:"), login, sizeof (login) - 1, grub_puts_ (N_("Enter username: "));
0, 0, 0))
if (!grub_username_get (login, sizeof (login) - 1))
goto access_denied; goto access_denied;
grub_printf ("Enter password: "); grub_puts_ (N_("Enter password: "));
if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN)) if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
goto access_denied; goto access_denied;

View file

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

View file

@ -103,23 +103,31 @@ free_and_return:
grub_free (fg_name); 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). */ /* Replace default `normal' colors with the ones specified by user (if any). */
char * char *
grub_env_write_color_normal (struct grub_env_var *var __attribute__ ((unused)), grub_env_write_color_normal (struct grub_env_var *var __attribute__ ((unused)),
const char *val) 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); grub_parse_color_name_pair (&color_normal, val);
/* Reloads terminal `normal' and `highlight' colors. */ set_colors ();
grub_setcolor (color_normal, color_highlight);
/* Propagates `normal' color to terminal current color. */
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
return grub_strdup (val); return grub_strdup (val);
} }
@ -129,21 +137,9 @@ char *
grub_env_write_color_highlight (struct grub_env_var *var __attribute__ ((unused)), grub_env_write_color_highlight (struct grub_env_var *var __attribute__ ((unused)),
const char *val) 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); grub_parse_color_name_pair (&color_highlight, val);
/* Reloads terminal `normal' and `highlight' colors. */ set_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);
return grub_strdup (val); return grub_strdup (val);
} }

View file

@ -30,9 +30,13 @@
#include <grub/menu_viewer.h> #include <grub/menu_viewer.h>
#include <grub/auth.h> #include <grub/auth.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/charset.h>
#define GRUB_DEFAULT_HISTORY_SIZE 50 #define GRUB_DEFAULT_HISTORY_SIZE 50
static int nested_level = 0;
int grub_normal_exit_level = 0;
/* Read a line from the file FILE. */ /* Read a line from the file FILE. */
char * char *
grub_file_getline (grub_file_t file) grub_file_getline (grub_file_t file)
@ -372,7 +376,21 @@ read_config_file (const char *config)
if (! file) if (! file)
return 0; 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); grub_file_close (file);
if (old_parser) if (old_parser)
@ -383,7 +401,7 @@ read_config_file (const char *config)
/* Initialize the screen. */ /* Initialize the screen. */
void void
grub_normal_init_page (void) grub_normal_init_page (struct grub_term_output *term)
{ {
int msg_len; int msg_len;
int posx; int posx;
@ -391,14 +409,13 @@ grub_normal_init_page (void)
char *msg_formatted = grub_malloc (grub_strlen(msg) + char *msg_formatted = grub_malloc (grub_strlen(msg) +
grub_strlen(PACKAGE_VERSION)); grub_strlen(PACKAGE_VERSION));
grub_cls ();
grub_sprintf (msg_formatted, msg, PACKAGE_VERSION);
grub_uint32_t *unicode_msg; grub_uint32_t *unicode_msg;
grub_uint32_t *last_position; 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, msg_len = grub_utf8_to_ucs4_alloc (msg_formatted,
&unicode_msg, &last_position); &unicode_msg, &last_position);
@ -407,17 +424,15 @@ grub_normal_init_page (void)
return; return;
} }
posx = grub_getstringwidth (unicode_msg, last_position); posx = grub_getstringwidth (unicode_msg, last_position, term);
posx = (GRUB_TERM_WIDTH - posx) / 2; posx = (grub_term_width (term) - posx) / 2;
grub_gotoxy (posx, 1); 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_printf("\n\n");
grub_free (unicode_msg); grub_free (unicode_msg);
} }
static int reader_nested;
static char * static char *
read_lists (struct grub_env_var *var __attribute__ ((unused)), read_lists (struct grub_env_var *var __attribute__ ((unused)),
const char *val) const char *val)
@ -425,6 +440,7 @@ read_lists (struct grub_env_var *var __attribute__ ((unused)),
read_command_list (); read_command_list ();
read_fs_list (); read_fs_list ();
read_crypto_list (); read_crypto_list ();
read_terminal_list ();
return val ? grub_strdup (val) : NULL; 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_register_variable_hook ("prefix", NULL, read_lists);
grub_command_execute ("parser.grub", 0, 0); grub_command_execute ("parser.grub", 0, 0);
reader_nested = nested;
if (config) if (config)
{ {
menu = read_config_file (config); menu = read_config_file (config);
@ -454,7 +468,7 @@ grub_normal_execute (const char *config, int nested, int batch)
{ {
if (menu && menu->size) if (menu && menu->size)
{ {
grub_menu_viewer_show_menu (menu, nested); grub_show_menu (menu, nested);
if (nested) if (nested)
free_menu (menu); free_menu (menu);
} }
@ -465,21 +479,24 @@ grub_normal_execute (const char *config, int nested, int batch)
void void
grub_enter_normal_mode (const char *config) grub_enter_normal_mode (const char *config)
{ {
nested_level++;
grub_normal_execute (config, 0, 0); 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. */ /* Enter normal mode from rescue mode. */
static grub_err_t static grub_err_t
grub_cmd_normal (struct grub_command *cmd, grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[]) int argc, char *argv[])
{ {
grub_unregister_command (cmd);
if (argc == 0) if (argc == 0)
{ {
/* Guess the config filename. It is necessary to make CONFIG static, /* Guess the config filename. It is necessary to make CONFIG static,
so that it won't get broken by longjmp. */ so that it won't get broken by longjmp. */
static char *config; char *config;
const char *prefix; const char *prefix;
prefix = grub_env_get ("prefix"); prefix = grub_env_get ("prefix");
@ -503,10 +520,82 @@ quit:
return 0; 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 void
grub_cmdline_run (int nested) grub_cmdline_run (int nested)
{ {
grub_reader_t reader;
grub_err_t err = GRUB_ERR_NONE; grub_err_t err = GRUB_ERR_NONE;
err = grub_auth_check_authentication (NULL); err = grub_auth_check_authentication (NULL);
@ -518,72 +607,28 @@ grub_cmdline_run (int nested)
return; return;
} }
reader = grub_reader_get_current (); grub_normal_reader_init (nested);
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);
while (1) while (1)
{ {
cmdline[0] = 0; char *line;
if (grub_cmdline_get (prompt, cmdline, sizeof (cmdline), 0, 1, 1))
if (grub_normal_exit_level)
break; break;
if ((reader_nested) || (cont)) /* Print an error, if any. */
{ grub_print_error ();
*line = 0; grub_errno = GRUB_ERR_NONE;
return grub_errno;
} grub_normal_read_line_real (&line, 0, nested);
if (! line)
break;
grub_parser_get_current ()->parse_line (line, grub_normal_read_line);
grub_free (line);
} }
*line = grub_strdup (cmdline);
return 0;
} }
static struct grub_reader grub_normal_reader =
{
.name = "normal",
.init = grub_normal_reader_init,
.read_line = grub_normal_read_line
};
static char * static char *
grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)), grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)),
const char *val) const char *val)
@ -598,17 +643,15 @@ GRUB_MOD_INIT(normal)
if (mod) if (mod)
grub_dl_ref (mod); grub_dl_ref (mod);
grub_menu_viewer_register (&grub_normal_text_menu_viewer);
grub_set_history (GRUB_DEFAULT_HISTORY_SIZE); 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); grub_register_variable_hook ("pager", 0, grub_env_write_pager);
/* Register a command "normal" for the rescue mode. */ /* Register a command "normal" for the rescue mode. */
grub_register_command_prio ("normal", grub_cmd_normal, grub_register_command ("normal", grub_cmd_normal,
0, "Enter normal mode.", 0); 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. */ /* Reload terminal colors when these variables are written to. */
grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal); 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_MOD_FINI(normal)
{ {
grub_set_history (0); grub_set_history (0);
grub_reader_unregister (&grub_normal_reader);
grub_register_variable_hook ("pager", 0, 0); grub_register_variable_hook ("pager", 0, 0);
grub_fs_autoload_hook = 0; grub_fs_autoload_hook = 0;
free_handler_list (); free_handler_list ();

View file

@ -27,6 +27,26 @@
#include <grub/command.h> #include <grub/command.h>
#include <grub/parser.h> #include <grub/parser.h>
#include <grub/auth.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. */ /* Get a menu entry by its index in the entry list. */
grub_menu_entry_t grub_menu_entry_t
@ -137,6 +157,8 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
return; return;
} }
grub_env_set ("chosen", entry->title);
grub_parser_execute ((char *) entry->sourcecode); grub_parser_execute ((char *) entry->sourcecode);
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) 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); 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/env.h>
#include <grub/menu_viewer.h> #include <grub/menu_viewer.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/charset.h>
/* Time to delay after displaying an error message about a default/fallback
entry failing to boot. */
#define DEFAULT_ENTRY_ERROR_DELAY_MS 2500
static grub_uint8_t grub_color_menu_normal; static grub_uint8_t grub_color_menu_normal;
static grub_uint8_t grub_color_menu_highlight; static grub_uint8_t grub_color_menu_highlight;
/* Wait until the user pushes any key so that the user struct menu_viewer_data
can see what happened. */
void
grub_wait_after_message (void)
{ {
grub_putchar ('\n'); int first, offset;
grub_printf_ (N_("Press any key to continue...")); grub_menu_t menu;
(void) grub_getkey (); struct grub_term_output *term;
grub_putchar ('\n'); };
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 void
grub_print_ucs4 (const grub_uint32_t * str, 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) while (str < last_position)
{ {
grub_putcode (*str); grub_putcode (*str, term);
str++; 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_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; grub_ssize_t width = 0;
while (str < last_position) while (str < last_position)
{ {
width += grub_getcharwidth (*str); width += grub_term_getcharwidth (term, *str);
str++; str++;
} }
return width; return width;
} }
void 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; int line_len;
line_len = GRUB_TERM_WIDTH - grub_getcharwidth ('m') *
(margin_left + margin_right);
grub_uint32_t *unicode_msg; grub_uint32_t *unicode_msg;
grub_uint32_t *last_position; grub_uint32_t *last_position;
int msg_len; 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); msg_len = grub_utf8_to_ucs4_alloc (msg, &unicode_msg, &last_position);
if (msg_len < 0) 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) while (current_position < last_position)
{ {
if (! first_loop) if (! first_loop)
grub_putchar ('\n'); grub_putcode ('\n', term);
next_new_line = (grub_uint32_t *) last_position; 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 != last_position && *next_new_line != ' '
&& next_new_line > current_position)) && 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_uint32_t *) last_position : next_new_line + line_len;
} }
grub_print_spaces (margin_left); print_spaces (margin_left, term);
grub_print_ucs4 (current_position, next_new_line); grub_print_ucs4 (current_position, next_new_line, term);
next_new_line++; next_new_line++;
current_position = 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 static void
draw_border (void) draw_border (struct grub_term_output *term)
{ {
unsigned i; 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_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y);
grub_putcode (GRUB_TERM_DISP_UL); grub_putcode (GRUB_TERM_DISP_UL, term);
for (i = 0; i < (unsigned) GRUB_TERM_BORDER_WIDTH - 2; i++) for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
grub_putcode (GRUB_TERM_DISP_HLINE); grub_putcode (GRUB_TERM_DISP_HLINE, term);
grub_putcode (GRUB_TERM_DISP_UR); 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_term_gotoxy (term, GRUB_TERM_MARGIN, 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_BORDER_WIDTH - 1, grub_term_gotoxy (term, GRUB_TERM_MARGIN + grub_term_border_width (term)
GRUB_TERM_TOP_BORDER_Y + i + 1); - 1,
grub_putcode (GRUB_TERM_DISP_VLINE); GRUB_TERM_TOP_BORDER_Y + i + 1);
grub_putcode (GRUB_TERM_DISP_VLINE, term);
} }
grub_gotoxy (GRUB_TERM_MARGIN, grub_term_gotoxy (term, GRUB_TERM_MARGIN,
GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES + 1); GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term) + 1);
grub_putcode (GRUB_TERM_DISP_LL); grub_putcode (GRUB_TERM_DISP_LL, term);
for (i = 0; i < (unsigned) GRUB_TERM_BORDER_WIDTH - 2; i++) for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
grub_putcode (GRUB_TERM_DISP_HLINE); grub_putcode (GRUB_TERM_DISP_HLINE, term);
grub_putcode (GRUB_TERM_DISP_LR); 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_gotoxy (term, GRUB_TERM_MARGIN,
(GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES (GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term)
+ GRUB_TERM_MARGIN + 1)); + GRUB_TERM_MARGIN + 1));
} }
static void 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) if (edit)
{ {
grub_putchar ('\n'); grub_putcode ('\n', term);
grub_print_message_indented (_("Minimum Emacs-like screen editing is \ grub_print_message_indented (_("Minimum Emacs-like screen editing is \
supported. TAB lists completions. Press Ctrl-x to boot, Ctrl-c for a \ 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 else
{ {
@ -210,23 +191,33 @@ entry is highlighted.\n");
grub_sprintf (msg_translated, msg, (grub_uint32_t) GRUB_TERM_DISP_UP, grub_sprintf (msg_translated, msg, (grub_uint32_t) GRUB_TERM_DISP_UP,
(grub_uint32_t) GRUB_TERM_DISP_DOWN); (grub_uint32_t) GRUB_TERM_DISP_DOWN);
grub_putchar ('\n'); 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_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) if (nested)
{ {
grub_printf ("\n "); grub_print_message_indented
grub_printf_ (N_("ESC to return previous menu.")); (_("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 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; int x;
const char *title; const char *title;
@ -252,482 +243,245 @@ print_entry (int y, int highlight, grub_menu_entry_t entry)
return; return;
} }
grub_getcolor (&old_color_normal, &old_color_highlight); grub_term_getcolor (term, &old_color_normal, &old_color_highlight);
grub_setcolor (grub_color_menu_normal, grub_color_menu_highlight); grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
grub_setcolorstate (highlight grub_term_setcolorstate (term, highlight
? GRUB_TERM_COLOR_HIGHLIGHT ? GRUB_TERM_COLOR_HIGHLIGHT
: GRUB_TERM_COLOR_NORMAL); : 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; 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++) i++)
{ {
if (i < len 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_TERM_MARGIN - 1))
{ {
grub_ssize_t width; 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_MARGIN - 1)) + grub_term_border_width (term)
grub_putcode (GRUB_TERM_DISP_RIGHT); - GRUB_TERM_MARGIN - 1))
grub_putcode (GRUB_TERM_DISP_RIGHT, term);
else else
grub_putcode (unicode_title[i]); grub_putcode (unicode_title[i], term);
x += width; x += width;
} }
else else
{ {
grub_putchar (' '); grub_putcode (' ', term);
x++; x++;
} }
} }
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL); grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
grub_putchar (' '); 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_term_setcolor (term, old_color_normal, old_color_highlight);
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL); grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
grub_free (unicode_title); grub_free (unicode_title);
} }
static void 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; grub_menu_entry_t e;
int i; int i;
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH, grub_term_gotoxy (term,
GRUB_TERM_FIRST_ENTRY_Y); GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term),
GRUB_TERM_FIRST_ENTRY_Y);
if (first) if (first)
grub_putcode (GRUB_TERM_DISP_UP); grub_putcode (GRUB_TERM_DISP_UP, term);
else else
grub_putchar (' '); grub_putcode (' ', term);
e = grub_menu_get_entry (menu, first); 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) if (e)
e = e->next; e = e->next;
} }
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH, grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X
GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES); + grub_term_border_width (term),
GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term));
if (e) if (e)
grub_putcode (GRUB_TERM_DISP_DOWN); grub_putcode (GRUB_TERM_DISP_DOWN, term);
else 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 /* 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 is run from another menu or a command-line. If EDIT is non-zero, show
a message for the menu entry editor. */ a message for the menu entry editor. */
void 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_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. */ /* By default, use the same colors for the menu. */
grub_color_menu_normal = old_color_normal; grub_color_menu_normal = old_color_normal;
grub_color_menu_highlight = old_color_highlight; grub_color_menu_highlight = old_color_highlight;
/* Then give user a chance to replace them. */ /* 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_normal,
grub_parse_color_name_pair (&grub_color_menu_highlight, grub_env_get ("menu_color_highlight")); 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_normal_init_page (term);
grub_setcolor (grub_color_menu_normal, grub_color_menu_highlight); grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
draw_border (); draw_border (term);
grub_setcolor (old_color_normal, old_color_highlight); grub_term_setcolor (term, old_color_normal, old_color_highlight);
print_message (nested, edit); print_message (nested, edit, term);
}
/* 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;
} }
static void static void
print_timeout (int timeout, int offset) menu_text_print_timeout (int timeout, void *dataptr)
{ {
const char *msg = const char *msg =
_("The highlighted entry will be executed automatically in %ds."); _("The highlighted entry will be executed automatically in %ds.");
struct menu_viewer_data *data = dataptr;
grub_gotoxy (0, GRUB_TERM_HEIGHT - 3); char *msg_translated;
char *msg_translated =
grub_malloc (sizeof (char) * grub_strlen (msg) + 5);
grub_sprintf (msg_translated, msg, timeout);
grub_print_message_indented (msg_translated, 3, 0);
int posx; int posx;
posx = grub_getxy() >> 8;
grub_print_spaces (GRUB_TERM_WIDTH - posx - 1);
grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset); grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
grub_refresh ();
}
/* Show the menu and handle menu entry selection. Returns the menu entry msg_translated = grub_malloc (sizeof (char) * grub_strlen (msg) + 5);
index that should be executed or -1 if no entry should be executed (e.g., if (!msg_translated)
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)))
{
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_print_error ();
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
return;
} }
grub_printf ("\n ");
grub_printf_ (N_("Failed to boot default entries.\n")); grub_sprintf (msg_translated, msg, timeout);
grub_wait_after_message (); grub_print_message_indented (msg_translated, 3, 0, data->term);
posx = grub_term_getxy (data->term) >> 8;
print_spaces (grub_term_width (data->term) - posx - 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);
} }
/* Callbacks used by the text menu to provide user feedback when menu entries static void
are executed. */ menu_text_set_chosen_entry (int entry, void *dataptr)
static struct grub_menu_execute_callback execution_callback =
{ {
.notify_booting = notify_booting, struct menu_viewer_data *data = dataptr;
.notify_fallback = notify_fallback, int oldoffset = data->offset;
.notify_failure = notify_execution_failure int complete_redraw = 0;
};
static grub_err_t data->offset = entry - data->first;
show_text_menu (grub_menu_t menu, int nested) if (data->offset > grub_term_num_entries (data->term) - 1)
{
while (1)
{ {
int boot_entry; data->first = entry - (grub_term_num_entries (data->term) - 1);
grub_menu_entry_t e; data->offset = grub_term_num_entries (data->term) - 1;
int auto_boot; complete_redraw = 1;
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);
}
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 ();
}
}
} }
if (data->offset < 0)
{
data->offset = 0;
data->first = entry;
complete_redraw = 1;
}
if (complete_redraw)
print_entries (data->menu, data->first, data->offset, data->term);
else
{
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)
{
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; 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 lib/arg.c
loader/efi/appleloader.c
loader/efi/chainloader.c
loader/i386/bsd.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/auth.c
normal/color.c normal/color.c

View file

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

View file

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

View file

@ -65,8 +65,7 @@ static struct grub_term_output grub_console_term_output =
.setcolorstate = grub_console_setcolorstate, .setcolorstate = grub_console_setcolorstate,
.setcolor = grub_console_setcolor, .setcolor = grub_console_setcolor,
.getcolor = grub_console_getcolor, .getcolor = grub_console_getcolor,
.setcursor = grub_console_setcursor, .setcursor = grub_console_setcursor
.flags = 0,
}; };
void void
@ -79,10 +78,6 @@ grub_console_init (void)
void void
grub_console_fini (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_input (&grub_console_term_input);
grub_term_unregister_output (&grub_console_term_output); grub_term_unregister_output (&grub_console_term_output);
} }

View file

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

View file

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

View file

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

View file

@ -108,52 +108,52 @@ grub_terminfo_set_current (const char *str)
/* Wrapper for grub_putchar to write strings. */ /* Wrapper for grub_putchar to write strings. */
static void static void
putstr (const char *str) putstr (const char *str, grub_term_output_t oterm)
{ {
while (*str) while (*str)
grub_putchar (*str++); grub_putcode (*str++, oterm);
} }
/* Move the cursor to the given position starting with "0". */ /* Move the cursor to the given position starting with "0". */
void 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. */ /* Clear the screen. */
void 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. */ /* Set reverse video mode on. */
void 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. */ /* Set reverse video mode off. */
void 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. */ /* Show cursor. */
void 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. */ /* Hide cursor. */
void 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. */ /* 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> #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. */ /* For compatibility. */
#ifndef A_NORMAL #ifndef A_NORMAL
# define A_NORMAL 0 # define A_NORMAL 0
@ -39,6 +31,14 @@
#include <grub/term.h> #include <grub/term.h>
#include <grub/types.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; static int grub_console_attr = A_NORMAL;
grub_uint8_t grub_console_cur_color = 7; 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, .setcolor = grub_ncurses_setcolor,
.getcolor = grub_ncurses_getcolor, .getcolor = grub_ncurses_getcolor,
.setcursor = grub_ncurses_setcursor, .setcursor = grub_ncurses_setcursor,
.refresh = grub_ncurses_refresh, .refresh = grub_ncurses_refresh
.flags = 0,
}; };
void void
@ -376,8 +375,6 @@ grub_console_init (void)
{ {
grub_term_register_output ("console", &grub_ncurses_term_output); grub_term_register_output ("console", &grub_ncurses_term_output);
grub_term_register_input ("console", &grub_ncurses_term_input); 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 void

View file

@ -328,7 +328,7 @@ static void
usage (int status) usage (int status)
{ {
if (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 else
printf ("\ printf ("\
Usage: %s -o FILE [OPTION]... [MODULES]\n\ Usage: %s -o FILE [OPTION]... [MODULES]\n\

View file

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

View file

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

View file

@ -129,10 +129,10 @@ usage (int status)
{ {
if (status) if (status)
fprintf (stderr, fprintf (stderr,
"Try ``grub-emu --help'' for more information.\n"); "Try `%s --help' for more information.\n", program_name);
else else
printf ( printf (
"Usage: grub-emu [OPTION]...\n" "Usage: %s [OPTION]...\n"
"\n" "\n"
"GRUB emulator.\n" "GRUB emulator.\n"
"\n" "\n"
@ -144,7 +144,7 @@ usage (int status)
" -h, --help display this message and exit\n" " -h, --help display this message and exit\n"
" -V, --version print version information and exit\n" " -V, --version print version information and exit\n"
"\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; return status;
} }
@ -220,14 +220,14 @@ main (int argc, char *argv[])
{ {
char *device_name = grub_guess_root_device (dir); char *device_name = grub_guess_root_device (dir);
if (! device_name) 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); root_dev = grub_util_get_grub_dev (device_name);
if (! root_dev) if (! root_dev)
{ {
grub_util_info ("guessing the root device failed, because of `%s'", grub_util_info ("guessing the root device failed, because of `%s'",
grub_errmsg); 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); cmd = grub_command_find (name);
if (! cmd) 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); 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); dev = grub_device_open (0);
if ((! dev) || (! dev->disk)) 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); (unsigned long long) dev->disk->total_sectors);
if (! leng) 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; len = (leng > BUF_SIZE) ? BUF_SIZE : leng;
if (grub_disk_read (dev->disk, 0, skip, len, buf)) 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); skip, len);
if (hook (skip, buf, 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); file = grub_file_open (pathname);
if (!file) if (!file)
{ {
grub_util_error ("cannot open file %s.", pathname); grub_util_error ("cannot open file %s", pathname);
return; 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) 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; 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); sz = grub_file_read (file, buf, (len > BUF_SIZE) ? BUF_SIZE : len);
if (sz < 0) if (sz < 0)
{ {
grub_util_error ("read error at offset %llu.", ofs); grub_util_error ("read error at offset %llu", ofs);
break; break;
} }
@ -184,7 +184,7 @@ cmd_cp (char *src, char *dest)
if ((int) fwrite (buf, 1, len, ff) != len) if ((int) fwrite (buf, 1, len, ff) != len)
{ {
grub_util_error ("write error."); grub_util_error ("write error");
return 1; return 1;
} }
@ -194,7 +194,7 @@ cmd_cp (char *src, char *dest)
ff = fopen (dest, "wb"); ff = fopen (dest, "wb");
if (ff == NULL) if (ff == NULL)
{ {
grub_util_error ("open error."); grub_util_error ("open error");
return; return;
} }
read_file (src, cp_hook); read_file (src, cp_hook);
@ -212,7 +212,7 @@ cmd_cmp (char *src, char *dest)
{ {
if ((int) fread (buf_1, 1, len, ff) != len) 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; return 1;
} }
@ -223,7 +223,7 @@ cmd_cmp (char *src, char *dest)
for (i = 0; i < len; i++, ofs++) for (i = 0; i < len; i++, ofs++)
if (buf_1[i] != buf[i]) 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; return 1;
} }
} }
@ -233,12 +233,12 @@ cmd_cmp (char *src, char *dest)
ff = fopen (dest, "rb"); ff = fopen (dest, "rb");
if (ff == NULL) if (ff == NULL)
{ {
grub_util_error ("open error."); grub_util_error ("open error");
return; return;
} }
if ((skip) && (fseeko (ff, skip, SEEK_SET))) if ((skip) && (fseeko (ff, skip, SEEK_SET)))
grub_util_error ("seek error."); grub_util_error ("seek error");
read_file (src, cmp_hook); read_file (src, cmp_hook);
fclose (ff); 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++) for (i = 0; i < num_disks; i++)
{ {
if (grub_strlen (images[i]) + 7 > sizeof (host_file)) 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 (loop_name, "loop%d", i);
grub_sprintf (host_file, "(host)%s", images[i]); grub_sprintf (host_file, "(host)%s", images[i]);
if (execute_command ("loopback", 3, argv)) if (execute_command ("loopback", 3, argv))
grub_util_error ("loopback command fails."); grub_util_error ("loopback command fails");
} }
grub_lvm_fini (); grub_lvm_fini ();
@ -349,7 +349,7 @@ static void
usage (int status) usage (int status)
{ {
if (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 else
printf ("\ printf ("\
Usage: %s [OPTION]... IMAGE_PATH COMMANDS\n\ Usage: %s [OPTION]... IMAGE_PATH COMMANDS\n\

View file

@ -40,6 +40,7 @@ else
fi fi
grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}`
rootdir= rootdir=
grub_prefix=`echo /boot/grub | sed ${transform}` grub_prefix=`echo /boot/grub | sed ${transform}`
modules= modules=
@ -87,9 +88,11 @@ fi
INSTALL_DEVICE can be a GRUB device name or a system device filename. 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 grub-install copies GRUB images into /boot/grub (or /grub on NetBSD and
--root-directory, and uses grub-setup to install grub into the boot OpenBSD), and uses grub-setup to install grub into the boot sector.
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>. Report bugs to <bug-grub@gnu.org>.
EOF EOF
@ -261,6 +264,10 @@ done
# Write device to a variable so we don't have to traverse /dev every time. # Write device to a variable so we don't have to traverse /dev every time.
grub_device=`$grub_probe --target=device ${grubdir}` 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. # Create the core image. First, auto-detect the filesystem module.
fs_module=`$grub_probe --target=fs --device ${grub_device}` fs_module=`$grub_probe --target=fs --device ${grub_device}`
if test "x$fs_module" = x -a "x$modules" = x; then 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} echo ${drive}${relative_path}
} }
save_default_entry ()
{
if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then
cat << EOF
savedefault
EOF
fi
}
prepare_grub_to_access_device () prepare_grub_to_access_device ()
{ {
device=$1 device=$1

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