merge mainline into newreloc

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-01-10 01:56:47 +01:00
commit 6b60576149
73 changed files with 3459 additions and 2567 deletions

218
ChangeLog
View file

@ -1,3 +1,221 @@
2010-01-07 Vladimir Serbinenko <phcoder@gmail.com>
2010-01-09 Robert Millan <rmh.grub@aybabtu.com>
Support for multiple terminals.
* Makefile.in (pkglib_DATA): terminal.lst.
(terminal.lst): New target.
* commands/handler.c (grub_cmd_handler): Don't handle terminals.
(GRUB_MOD_INIT(handler)): Likewise.
(GRUB_MOD_FINI(handler)): Likewise.
* commands/help.c (grub_cmd_help): Handle multiple terminals.
* commands/keystatus.c (grub_cmd_keystatus): Likewise.
* commands/sleep.c (do_print): Use grub_term_restore_pos.
(grub_cmd_sleep): Use grub_term_save_pos.
* commands/terminal.c: New file.
* conf/any-emu.rmk (grub_emu_SOURCES): Add normal/term.c
commands/terminal.c and lib/charset.c.
* conf/common.rmk (normal_mod_SOURCES): Add normal/term.c.
(pkglib_MODULES): Add terminal.mod.
(terminal_mod_SOURCES): New variable.
(terminal_mod_CFLAGS): Likewise.
(terminal_mod_LDFLAGS): Likewise.
* genhandlerlist.sh: Don't handle terminals.
* genmk.rb: Generate terminal-*.lst.
* genterminallist.sh: New file.
* include/grub/charset.h (grub_ucs4_to_utf8_alloc): New proto.
(grub_is_valid_utf8): Likewise.
(grub_utf8_to_ucs4_alloc): Likewise.
* include/grub/menu_viewer.h (grub_menu_viewer): Rewritten.
(grub_menu_register_viewer): Changed argument.
(grub_menu_try_text): New proto.
(grub_gfxmenu_try_hook): New declaration.
* include/grub/normal.h (grub_normal_exit_level): New declaration.
(grub_menu_init_page): Additional argument term.
(grub_normal_init_page): Likewise.
(grub_cmdline_get): Arguments simplified.
(grub_utf8_to_ucs4_alloc): Removed.
(grub_print_ucs4): Additional argument term.
(grub_getstringwidth): Likewise.
(grub_print_message_indented): Likewise.
(grub_menu_text_register_instances): New proto.
(grub_show_menu): Likewise.
(read_terminal_list): Likewise.
(grub_set_more): Likewise.
* include/grub/parser.h: Include handler.h.
* include/grub/reader.h: Rewritten.
* include/grub/term.h (GRUB_TERM_NEED_INIT): Removed.
(GRUB_TERM_WIDTH): Changed to function.
(GRUB_TERM_HEIGHT): Likewise.
(GRUB_TERM_BORDER_WIDTH): Likewise.
(GRUB_TERM_BORDER_HEIGHT): Likewise.
(GRUB_TERM_NUM_ENTRIES): Likewise.
(GRUB_TERM_ENTRY_WIDTH): Likewise.
(GRUB_TERM_CURSOR_X): Likewise.
(grub_term_input_class): Likewise.
(grub_term_output_class): Likewise.
(grub_term_outputs_disabled): New declaration.
(grub_term_inputs_disabled): Likewise.
(grub_term_outputs): Likewise.
(grub_term_inputs): Likewise.
(grub_term_register_input): Rewritten.
(grub_term_register_output): Likewise.
(grub_term_unregister_input): Likewise.
(grub_term_unregister_output): Likewise.
(FOR_ACTIVE_TERM_INPUTS): New macro.
(FOR_DISABLED_TERM_INPUTS): Likewise.
(FOR_ACTIVE_TERM_OUTPUTS): Likewise.
(FOR_DISABLED_TERM_OUTPUTS): Likewise.
* include/grub/terminfo.h: Add oterm argument to all protypes.
* kern/main.c (grub_main): Don't call grub_register_rescue_reader.
Use grub_rescue_run.
* kern/misc.c (grub_utf8_to_ucs4): Put '?' for invalid characters.
All users updated.
* kern/reader.c: Removed. All users updated.
* kern/rescue_reader.c (grub_rescue_init): Removed.
(grub_rescue_reader): Likewise.
(grub_register_rescue_reader): Likewise.
(grub_rescue_run): New function based on kern/reader.c.
* kern/term.c: Adapted for multiterm.
* lib/charset.c (grub_ucs4_to_utf8_alloc): New function.
(grub_is_valid_utf8): Likewise.
(grub_utf8_to_ucs4_alloc): Moved from normal/menu_text.c.
* loader/i386/efi/linux.c (grub_cmd_linux): Retrieve parameters of
right terminal.
* loader/i386/linux.c (grub_linux_boot): Likewise.
* normal/auth.c (grub_username_get): New function.
(grub_auth_check_authentication): Use grub_username_get.
* normal/cmdline.c: Changed to UCS4. Adapted for multiterm.
* normal/color.c: Adapt for multiterm.
* normal/main.c (read_config_file): Don't use grub_reader_loop.
(grub_normal_init_page): Additional argument term.
(read_lists): Call read_terminal_lists.
(grub_enter_normal_mode): Call grub_cmdline_run.
Handle grub_normal_exit_level.
(grub_cmd_normal): Make reentrant.
(grub_cmd_normal_exit): New function.
(grub_normal_reader_init): Additional argument nested. Handle multiterm.
* normal/menu.c: Adapt for multiterm.
* normal/menu_entry.c: Likewise.
* normal/menu_text.c: Likewise.
* normal/menu_viewer.c: Removed. All users updated.
* normal/term.c: New file.
* util/console.c: Change order of includes to workaround a bug in
ncurses headers.
* term/terminfo.c: New argument oterm on all exported functions.
All users updated.
* util/grub-editenv.c (grub_term_input_class): Removed.
(grub_term_output_class): Likewise.
2010-01-09 Robert Millan <rmh.grub@aybabtu.com>
Make loader output a bit more user-friendly.
* util/grub.d/10_hurd.in: Print message indicating that GNU Mach
is being loaded. Likewise for the Hurd.
* util/grub.d/10_kfreebsd.in (kfreebsd_entry): Print message indicating
that kernel of FreeBSD ${version} is being loaded.
* loader/i386/linux.c (grub_cmd_linux): Move debug info to
grub_dprintf().
(grub_cmd_initrd): Likewise.
* util/grub.d/10_linux.in (linux_entry): Print message indicating
that Linux ${version} is being loaded. Likewise for initrd.
2010-01-09 Carles Pina i Estany <carles@pina.cat>
* gettext/gettext.c (GRUB_MOD_INIT): Gettextizze.
2010-01-08 Carles Pina i Estany <carles@pina.cat>
* loader/efi/appleloader.c: Include `<grub/i18n.h>'.
(GRUB_MOD_INIT): Gettextizze.
* loader/efi/chainloader.c: Include `<grub/i18n.h>'.
(GRUB_MOD_INIT): Gettextizze.
* loader/i386/efi/linux.c: Include `<grub/i18n.h>'.
(grub_cmd_linux): Capitalise Linux.
(GRUB_MOD_INIT): Gettextizze.
* loader/i386/ieee1275/linux.c: Include `<grub/i18n.h>'.
(grub_cmd_linux): Capitalise Linux.
(GRUB_MOD_INIT): Gettextizze.
* loader/i386/linux.c: Include `<grub/i18n.h>'.
(grub_cmd_linux): Capitalise Linux.
(GRUB_MOD_INIT): Gettextizze.
* loader/i386/pc/chainloader.c: Include `<grub/i18n.h>'.
(GRUB_MOD_INIT): Gettextizze.
* loader/i386/pc/linux.c: Include `<grub/i18n.h>'.
(grub_cmd_linux): Capitalise Linux.
(GRUB_MOD_INIT): Gettextizze.
* loader/i386/xnu.c: Include `<grub/i18n.h>'.
(grub_cpu_xnu_init): Gettextizze.
* loader/multiboot_loader.c: Include `<grub/i18n.h>'.
(GRUB_MOD_INIT): Gettextizze.
* loader/powerpc/ieee1275/linux.c: Include `<grub/i18n.h>'.
(GRUB_MOD_INIT): Gettextizze.
* loader/sparc64/ieee1275/linux.c: Include `<grub/i18n.h>'.
(grub_linux_load64): Capitalise Linux.
(GRUB_MOD_INIT): Gettextizze.
* loader/xnu.c: Include `<grub/i18n.h>'.
(GRUB_MOD_INIT): Gettextizze.
* po/POTFILES: Add `loader/efi/appleloader.c',
`loader/efi/chainloader.c', `loader/i386/efi/linux.c',
`loader/i386/ieee1275/linux.c', `loader/i386/linux.c',
`loader/i386/pc/chainloader.c', `loader/i386/pc/linux.c',
`loader/i386/xnu.c', `loader/multiboot_loader.c',
`loader/powerpc/ieee1275/linux.c', `loader/sparc64/ieee1275/linux.c'
and `loader/xnu.c'.
2010-01-08 Robert Millan <rmh.grub@aybabtu.com>
* src/mkisofs.c: Remove `ifdef linux' portability kludge.
2010-01-08 Robert Millan <rmh.grub@aybabtu.com>
* util/mkisofs/defaults.h (APPID_DEFAULT): Redefine using PACKAGE_NAME.
(SYSTEM_ID_DEFAULT): Set to "GNU" unconditionally.
* util/mkisofs/mkisofs.c (main): Readjust --version output.
2010-01-07 Robert Millan <rmh.grub@aybabtu.com>
Reset Multiboot 2 support. New loader implements the draft in
/branches/multiboot2 and shares as much code as possible with the
production Multiboot 1 implementation.
* loader/ieee1275/multiboot2.c: Remove file. Update all users.
* loader/multiboot2.c: Likewise.
* loader/i386/multiboot_helper.S: Likewise.
* include/multiboot2.h: Replace with latest version from the draft
in /branches/multiboot2.
* conf/i386-coreboot.rmk (multiboot_mod_SOURCES): Remove
`loader/i386/multiboot_helper.S', `loader/i386/pc/multiboot2.c'
and `loader/multiboot2.c'.
(pkglib_MODULES): Add `multiboot2.mod'.
(multiboot2_mod_SOURCES): New variable.
(multiboot2_mod_LDFLAGS): Likewise.
(multiboot2_mod_CFLAGS): Likewise. Define `GRUB_USE_MULTIBOOT2'.
* conf/i386-pc.rmk: Likewise.
* conf/powerpc-ieee1275.rmk (pkglib_MODULES): Remove `multiboot.mod'.
(multiboot_mod_SOURCES): Remove variable.
(multiboot_mod_LDFLAGS): Likewise.
(multiboot_mod_CFLAGS): Likewise.
* include/grub/multiboot.h [GRUB_USE_MULTIBOOT2]: Include
`<multiboot2.h>' instead of `<multiboot.h>'.
[GRUB_USE_MULTIBOOT2] (MULTIBOOT_BOOTLOADER_MAGIC)
(MULTIBOOT_HEADER_MAGIC): New macros.
* loader/multiboot_loader.c (module_version_status): Remove variable.
(find_multi_boot2_header): Remove function.
(grub_cmd_multiboot_loader): Remove Multiboot 2 / Multiboot 1 selection
logic. Always check for the Multiboot version we're compiling for.
(grub_cmd_module_loader): Likewise.
[GRUB_USE_MULTIBOOT2] (GRUB_MOD_INIT(multiboot)): Register `multiboot2'
command instead of `multiboot'.
2010-01-07 Robert Millan <rmh.grub@aybabtu.com> 2010-01-07 Robert Millan <rmh.grub@aybabtu.com>
* include/multiboot.h (MULTIBOOT_UNSUPPORTED): Moved from here ... * include/multiboot.h (MULTIBOOT_UNSUPPORTED): Moved from here ...

View file

@ -174,7 +174,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 +192,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 > $@

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 +
@ -56,27 +56,33 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help, grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help,
&unicode_last_position); &unicode_last_position);
unicode_last_screen_position = unicode_command_help; FOR_ACTIVE_TERM_OUTPUTS(term)
{
unsigned stringwidth;
grub_uint32_t *unicode_last_screen_position;
stringwidth = 0; unicode_last_screen_position = unicode_command_help;
while (unicode_last_screen_position < unicode_last_position && stringwidth = 0;
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); while (unicode_last_screen_position < unicode_last_position &&
stringwidth < ((grub_term_width (term) / 2) - 2))
{
stringwidth
+= grub_term_getcharwidth (term,
*unicode_last_screen_position);
unicode_last_screen_position++;
}
if ((cnt++) % 2) grub_print_ucs4 (unicode_command_help,
{ unicode_last_screen_position, term);
grub_putchar ('\n'); if (!(cnt % 2))
} grub_print_spaces (term, grub_term_width (term) / 2
else - stringwidth);
{ }
grub_print_spaces (GRUB_TERM_WIDTH / 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

@ -28,8 +28,9 @@ grub_emu_SOURCES = commands/minicmd.c commands/cat.c commands/cmp.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

@ -549,8 +549,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)
@ -651,6 +651,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 \
@ -102,7 +102,7 @@ bin_SCRIPTS += grub-mkrescue
grub_mkrescue_SOURCES = util/grub-mkrescue.in grub_mkrescue_SOURCES = util/grub-mkrescue.in
# Modules. # Modules.
pkglib_MODULES = linux.mod multiboot.mod \ pkglib_MODULES = linux.mod \
aout.mod play.mod serial.mod \ aout.mod play.mod serial.mod \
memdisk.mod pci.mod lspci.mod reboot.mod \ memdisk.mod pci.mod lspci.mod reboot.mod \
halt.mod datetime.mod date.mod datehook.mod \ halt.mod datetime.mod date.mod datehook.mod \
@ -140,16 +140,20 @@ 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)
# For multiboot.mod. pkglib_MODULES += multiboot.mod
multiboot_mod_SOURCES = loader/i386/multiboot.c \ multiboot_mod_SOURCES = loader/i386/multiboot.c \
loader/i386/multiboot_helper.S \
loader/i386/pc/multiboot2.c \
loader/multiboot2.c \
loader/multiboot_loader.c loader/multiboot_loader.c
multiboot_mod_CFLAGS = $(COMMON_CFLAGS) multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS) 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 \
@ -204,14 +204,18 @@ serial_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For multiboot.mod. # For multiboot.mod.
#pkglib_MODULES += multiboot.mod #pkglib_MODULES += multiboot.mod
multiboot_mod_SOURCES = loader/i386/multiboot.c \ multiboot_mod_SOURCES = loader/i386/multiboot.c \
loader/i386/multiboot_helper.S \
loader/i386/pc/multiboot2.c \
loader/multiboot2.c \
loader/multiboot_loader.c loader/multiboot_loader.c
multiboot_mod_CFLAGS = $(COMMON_CFLAGS) multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS) multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS) 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

@ -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 \
@ -61,7 +61,6 @@ pkglib_MODULES = halt.mod \
linux.mod \ linux.mod \
reboot.mod \ reboot.mod \
suspend.mod \ suspend.mod \
multiboot.mod \
memdisk.mod \ memdisk.mod \
lsmmap.mod lsmmap.mod
@ -91,13 +90,6 @@ halt_mod_SOURCES = commands/halt.c
halt_mod_CFLAGS = $(COMMON_CFLAGS) halt_mod_CFLAGS = $(COMMON_CFLAGS)
halt_mod_LDFLAGS = $(COMMON_LDFLAGS) halt_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For multiboot.mod
multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \
loader/multiboot2.c \
loader/multiboot_loader.c
multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For memdisk.mod. # For memdisk.mod.
memdisk_mod_SOURCES = disk/memdisk.c memdisk_mod_SOURCES = disk/memdisk.c
memdisk_mod_CFLAGS = $(COMMON_CFLAGS) memdisk_mod_CFLAGS = $(COMMON_CFLAGS)

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 \

View file

@ -39,7 +39,7 @@ 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 \

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 $< \

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

@ -347,8 +347,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

@ -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

@ -201,11 +201,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

@ -1,7 +1,7 @@
/* multiboot.h - multiboot header file with grub definitions. */ /* multiboot.h - multiboot header file with grub definitions. */
/* /*
* GRUB -- GRand Unified Bootloader * GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2007,2008 Free Software Foundation, Inc. * Copyright (C) 2003,2007,2008,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
@ -20,7 +20,14 @@
#ifndef GRUB_MULTIBOOT_HEADER #ifndef GRUB_MULTIBOOT_HEADER
#define GRUB_MULTIBOOT_HEADER 1 #define GRUB_MULTIBOOT_HEADER 1
#ifdef GRUB_USE_MULTIBOOT2
#include <multiboot2.h>
/* Same thing as far as our loader is concerned. */
#define MULTIBOOT_BOOTLOADER_MAGIC MULTIBOOT2_BOOTLOADER_MAGIC
#define MULTIBOOT_HEADER_MAGIC MULTIBOOT2_HEADER_MAGIC
#else
#include <multiboot.h> #include <multiboot.h>
#endif
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[]);

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 */

View file

@ -1,110 +1,220 @@
/* multiboot2.h - multiboot 2 header file. */ /* multiboot2.h - Multiboot 2 header file. */
/* /* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc.
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2007,2009 Free Software Foundation, Inc.
* *
* GRUB is free software: you can redistribute it and/or modify * Permission is hereby granted, free of charge, to any person obtaining a copy
* it under the terms of the GNU General Public License as published by * of this software and associated documentation files (the "Software"), to
* the Free Software Foundation, either version 3 of the License, or * deal in the Software without restriction, including without limitation the
* (at your option) any later version. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* *
* GRUB is distributed in the hope that it will be useful, * The above copyright notice and this permission notice shall be included in
* but WITHOUT ANY WARRANTY; without even the implied warranty of * all copies or substantial portions of the Software.
* 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 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* along with GRUB. If not, see <http://www.gnu.org/licenses/>. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
* DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
#ifndef MULTIBOOT2_HEADER #ifndef MULTIBOOT_HEADER
#define MULTIBOOT2_HEADER 1 #define MULTIBOOT_HEADER 1
/* How many bytes from the start of the file we search for the header. */ /* How many bytes from the start of the file we search for the header. */
#define MULTIBOOT2_HEADER_SEARCH 8192 #define MULTIBOOT_SEARCH 8192
/* The magic field should contain this. */ /* The magic field should contain this. */
#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 #define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
/* Passed from the bootloader to the kernel. */ /* This should be in %eax. */
#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 #define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
/* Alignment of multiboot modules. */ /* Alignment of multiboot modules. */
#define MULTIBOOT2_MOD_ALIGN 0x00001000 #define MULTIBOOT_MOD_ALIGN 0x00001000
/* Alignment of the multiboot info structure. */
#define MULTIBOOT_INFO_ALIGN 0x00000004
/* Flags set in the 'flags' member of the multiboot header. */
/* Align all boot modules on i386 page (4KB) boundaries. */
#define MULTIBOOT_PAGE_ALIGN 0x00000001
/* Must pass memory information to OS. */
#define MULTIBOOT_MEMORY_INFO 0x00000002
/* Must pass video information to OS. */
#define MULTIBOOT_VIDEO_MODE 0x00000004
/* This flag indicates the use of the address fields in the header. */
#define MULTIBOOT_AOUT_KLUDGE 0x00010000
/* Flags to be set in the 'flags' member of the multiboot info structure. */
/* is there basic lower/upper memory information? */
#define MULTIBOOT_INFO_MEMORY 0x00000001
/* is there a boot device set? */
#define MULTIBOOT_INFO_BOOTDEV 0x00000002
/* is the command-line defined? */
#define MULTIBOOT_INFO_CMDLINE 0x00000004
/* are there modules to do something with? */
#define MULTIBOOT_INFO_MODS 0x00000008
/* These next two are mutually exclusive */
/* is there a symbol table loaded? */
#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010
/* is there an ELF section header table? */
#define MULTIBOOT_INFO_ELF_SHDR 0X00000020
/* is there a full memory map? */
#define MULTIBOOT_INFO_MEM_MAP 0x00000040
/* Is there drive info? */
#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080
/* Is there a config table? */
#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100
/* Is there a boot loader name? */
#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200
/* Is there a APM table? */
#define MULTIBOOT_INFO_APM_TABLE 0x00000400
/* Is there video information? */
#define MULTIBOOT_INFO_VIDEO_INFO 0x00000800
#ifndef ASM_FILE #ifndef ASM_FILE
#ifndef __WORDSIZE typedef unsigned short multiboot_uint16_t;
#include <stdint.h> typedef unsigned int multiboot_uint32_t;
#endif typedef unsigned long long multiboot_uint64_t;
/* XXX not portable? */ struct multiboot_header
#if __WORDSIZE == 64
typedef uint64_t multiboot2_word;
#else
typedef uint32_t multiboot2_word;
#endif
struct multiboot2_header
{ {
uint32_t magic; /* Must be MULTIBOOT_MAGIC - see above. */
uint32_t flags; multiboot_uint32_t magic;
/* Feature flags. */
multiboot_uint32_t flags;
/* The above fields plus this one must equal 0 mod 2^32. */
multiboot_uint32_t checksum;
/* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */
multiboot_uint32_t header_addr;
multiboot_uint32_t load_addr;
multiboot_uint32_t load_end_addr;
multiboot_uint32_t bss_end_addr;
multiboot_uint32_t entry_addr;
/* These are only valid if MULTIBOOT_VIDEO_MODE is set. */
multiboot_uint32_t mode_type;
multiboot_uint32_t width;
multiboot_uint32_t height;
multiboot_uint32_t depth;
}; };
struct multiboot2_tag_header /* The symbol table for a.out. */
struct multiboot_aout_symbol_table
{ {
uint32_t key; multiboot_uint32_t tabsize;
uint32_t len; multiboot_uint32_t strsize;
multiboot_uint32_t addr;
multiboot_uint32_t reserved;
}; };
typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t;
#define MULTIBOOT2_TAG_RESERVED1 0 /* The section header table for ELF. */
#define MULTIBOOT2_TAG_RESERVED2 (~0) struct multiboot_elf_section_header_table
#define MULTIBOOT2_TAG_START 1
struct multiboot2_tag_start
{ {
struct multiboot2_tag_header header; multiboot_uint32_t num;
multiboot2_word size; /* Total size of all multiboot tags. */ multiboot_uint32_t size;
multiboot_uint32_t addr;
multiboot_uint32_t shndx;
}; };
typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t;
#define MULTIBOOT2_TAG_NAME 2 struct multiboot_info
struct multiboot2_tag_name
{ {
struct multiboot2_tag_header header; /* Multiboot info version number */
char name[1]; multiboot_uint32_t flags;
};
#define MULTIBOOT2_TAG_MODULE 3 /* Available memory from BIOS */
struct multiboot2_tag_module multiboot_uint32_t mem_lower;
{ multiboot_uint32_t mem_upper;
struct multiboot2_tag_header header;
multiboot2_word addr;
multiboot2_word size;
char type[36];
char cmdline[1];
};
#define MULTIBOOT2_TAG_MEMORY 4 /* "root" partition */
struct multiboot2_tag_memory multiboot_uint32_t boot_device;
{
struct multiboot2_tag_header header;
multiboot2_word addr;
multiboot2_word size;
multiboot2_word type;
};
#define MULTIBOOT2_TAG_UNUSED 5 /* Kernel command line */
struct multiboot2_tag_unused multiboot_uint32_t cmdline;
{
struct multiboot2_tag_header header;
};
#define MULTIBOOT2_TAG_END 0xffff /* Boot-Module list */
struct multiboot2_tag_end multiboot_uint32_t mods_count;
{ multiboot_uint32_t mods_addr;
struct multiboot2_tag_header header;
union
{
multiboot_aout_symbol_table_t aout_sym;
multiboot_elf_section_header_table_t elf_sec;
} u;
/* Memory Mapping buffer */
multiboot_uint32_t mmap_length;
multiboot_uint32_t mmap_addr;
/* Drive Info buffer */
multiboot_uint32_t drives_length;
multiboot_uint32_t drives_addr;
/* ROM configuration table */
multiboot_uint32_t config_table;
/* Boot Loader Name */
multiboot_uint32_t boot_loader_name;
/* APM table */
multiboot_uint32_t apm_table;
/* Video */
multiboot_uint32_t vbe_control_info;
multiboot_uint32_t vbe_mode_info;
multiboot_uint16_t vbe_mode;
multiboot_uint16_t vbe_interface_seg;
multiboot_uint16_t vbe_interface_off;
multiboot_uint16_t vbe_interface_len;
}; };
typedef struct multiboot_info multiboot_info_t;
struct multiboot_mmap_entry
{
multiboot_uint32_t size;
multiboot_uint64_t addr;
multiboot_uint64_t len;
#define MULTIBOOT_MEMORY_AVAILABLE 1
#define MULTIBOOT_MEMORY_RESERVED 2
multiboot_uint32_t type;
} __attribute__((packed));
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
struct multiboot_mod_list
{
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
multiboot_uint32_t mod_start;
multiboot_uint32_t mod_end;
/* Module command line */
multiboot_uint32_t cmdline;
/* padding to take it to 16 bytes (must be zero) */
multiboot_uint32_t pad;
};
typedef struct multiboot_mod_list multiboot_module_t;
#endif /* ! ASM_FILE */ #endif /* ! ASM_FILE */
#endif /* ! MULTIBOOT2_HEADER */ #endif /* ! MULTIBOOT_HEADER */

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.");
{
grub_printf ("\nAborted.");
if (grub_term_get_current_input ()) #ifndef GRUB_UTIL
{ if (grub_term_inputs)
grub_printf (" Press any key to exit."); #endif
grub_getkey (); {
} 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);
}
void FOR_ACTIVE_TERM_OUTPUTS(term)
grub_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color) grub_term_setcolorstate (term, state);
{
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

@ -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
@ -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 */
@ -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

@ -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
@ -165,7 +166,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 +277,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
@ -547,8 +549,23 @@ grub_linux_boot (void)
/* 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_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,43 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,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/>.
*/
#include <grub/symbol.h>
#include <multiboot.h>
#include <multiboot2.h>
.p2align 2 /* force 4-byte alignment */
/*
* This starts the multiboot 2 kernel.
*/
FUNCTION(grub_multiboot2_real_boot)
/* Push the entry address on the stack. */
pushl %eax
/* Move the address of the multiboot information structure to ebx. */
movl %edx,%ebx
/* Interrupts should be disabled. */
cli
/* Move the magic value into eax and jump to the kernel. */
movl $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
popl %ecx
cld
jmp *%ecx

View file

@ -32,6 +32,7 @@
#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>
static grub_dl_t my_mod; static grub_dl_t my_mod;
static int boot_drive; static int boot_drive;
@ -146,7 +147,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

@ -30,6 +30,7 @@
#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>
#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
@ -81,7 +82,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 +384,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

@ -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

@ -1,147 +0,0 @@
/* multiboot.c - boot a multiboot 2 OS image. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2007,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/loader.h>
#include <grub/ieee1275/ieee1275.h>
#include <grub/multiboot2.h>
#include <multiboot2.h>
#include <grub/err.h>
#include <grub/elf.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/machine/kernel.h>
#include <grub/machine/loader.h>
#ifdef __i386__
#include <grub/cpu/multiboot.h>
#endif
typedef void (*kernel_entry_t) (unsigned long, void *, int (void *),
unsigned long, unsigned long);
/* Claim the memory occupied by the multiboot kernel. */
grub_err_t
grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr,
grub_addr_t *addr __attribute__((unused)),
int *do_load)
{
int rc;
if (phdr->p_type != PT_LOAD)
{
*do_load = 0;
return 0;
}
*do_load = 1;
rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
if (rc)
return grub_error(GRUB_ERR_OUT_OF_MEMORY, "couldn't claim %x - %x",
phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
grub_dprintf ("loader", "Loading segment at 0x%x - 0x%x\n", phdr->p_paddr,
phdr->p_paddr + phdr->p_memsz);
return GRUB_ERR_NONE;
}
/* Claim the memory occupied by the multiboot kernel. */
grub_err_t
grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr,
grub_addr_t *addr __attribute__((unused)),
int *do_load)
{
int rc;
if (phdr->p_type != PT_LOAD)
{
*do_load = 0;
return 0;
}
*do_load = 1;
rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
if (rc)
return grub_error(GRUB_ERR_OUT_OF_MEMORY, "couldn't claim 0x%lx - 0x%lx",
phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
grub_dprintf ("loader", "Loading segment at 0x%lx - 0x%lx\n",
(unsigned long) phdr->p_paddr,
(unsigned long) (phdr->p_paddr + phdr->p_memsz));
return GRUB_ERR_NONE;
}
grub_err_t
grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
{
int rc;
/* XXX Will need to map on some firmwares. */
rc = grub_ieee1275_claim (0, size, MULTIBOOT2_MOD_ALIGN, addr);
if (rc)
return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"firmware couldn't allocate memory (size 0x%lx)", size);
return GRUB_ERR_NONE;
}
grub_err_t
grub_mb2_arch_module_free (grub_addr_t addr, grub_size_t size)
{
grub_ieee1275_release (addr, size);
return GRUB_ERR_NONE;
}
grub_err_t
grub_mb2_tags_arch_create (void)
{
/* Nothing special. */
return GRUB_ERR_NONE;
}
/* Release the memory we claimed from Open Firmware above. */
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_ieee1275_release (module->addr, module->size);
}
}
}
void
grub_mb2_arch_boot (grub_addr_t entry_addr, void *tags)
{
#if defined(__powerpc__)
kernel_entry_t entry = (kernel_entry_t) entry_addr;
entry (MULTIBOOT2_BOOTLOADER_MAGIC, tags, grub_ieee1275_entry_fn, 0, 0);
#elif defined(__i386__)
grub_multiboot2_real_boot (entry_addr, tags);
#else
#error
#endif
}

View file

@ -1,461 +0,0 @@
/* multiboot2.c - boot a multiboot 2 OS image. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2007,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/loader.h>
#include <grub/machine/loader.h>
#include <grub/multiboot2.h>
#include <multiboot2.h>
#include <grub/elfload.h>
#include <grub/file.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/gzio.h>
static grub_addr_t entry;
extern grub_dl_t my_mod;
static char *grub_mb2_tags;
static char *grub_mb2_tags_pos;
static grub_size_t grub_mb2_tags_len;
static int grub_mb2_tags_count;
static void
grub_mb2_tags_free (void)
{
grub_dprintf ("loader", "Freeing all tags...\n");
grub_free (grub_mb2_tags);
grub_mb2_tags = 0;
grub_mb2_tags_pos = 0;
grub_mb2_tags_len = 0;
grub_mb2_tags_count = 0;
}
grub_err_t
grub_mb2_tag_alloc (grub_addr_t *addr, int key, grub_size_t len)
{
struct multiboot2_tag_header *tag;
grub_size_t used;
grub_size_t needed;
grub_dprintf ("loader", "Allocating tag: key 0x%x, size 0x%lx.\n",
key, (unsigned long) len);
used = grub_mb2_tags_pos - grub_mb2_tags;
len = ALIGN_UP (len, sizeof (multiboot2_word));
needed = used + len;
if (needed > grub_mb2_tags_len)
{
/* Allocate new buffer. */
grub_size_t newsize = needed * 2;
char *newarea;
grub_dprintf ("loader", "Reallocating tag buffer (new size 0x%lx).\n",
(unsigned long) newsize);
newarea = grub_malloc (newsize);
if (! newarea)
return grub_errno;
grub_memcpy (newarea, grub_mb2_tags, grub_mb2_tags_len);
grub_free (grub_mb2_tags);
grub_mb2_tags_len = newsize;
grub_mb2_tags = newarea;
grub_mb2_tags_pos = newarea + used;
}
tag = (struct multiboot2_tag_header *) grub_mb2_tags_pos;
grub_mb2_tags_pos += len;
tag->key = key;
tag->len = len;
if (addr)
*addr = (grub_addr_t) tag;
grub_mb2_tags_count++;
grub_dprintf ("loader", "Allocated tag %u at %p.\n", grub_mb2_tags_count, tag);
return 0;
}
static grub_err_t
grub_mb2_tag_start_create (void)
{
return grub_mb2_tag_alloc (0, MULTIBOOT2_TAG_START,
sizeof (struct multiboot2_tag_start));
}
static grub_err_t
grub_mb2_tag_name_create (void)
{
struct multiboot2_tag_name *name;
grub_addr_t name_addr;
grub_err_t err;
const char *grub_version = PACKAGE_STRING;
err = grub_mb2_tag_alloc (&name_addr, MULTIBOOT2_TAG_NAME,
sizeof (struct multiboot2_tag_name) +
sizeof (grub_version) + 1);
if (err)
return err;
name = (struct multiboot2_tag_name *) name_addr;
grub_strcpy (name->name, grub_version);
return GRUB_ERR_NONE;
}
typedef grub_err_t (*tag_create_t) (void);
static tag_create_t grub_mb2_tag_creators[] = {
grub_mb2_tag_start_create,
grub_mb2_tag_name_create,
grub_mb2_tags_arch_create,
0,
};
static grub_err_t
grub_mb2_tags_create (void)
{
tag_create_t *creator;
grub_err_t err;
for (creator = grub_mb2_tag_creators; *creator != 0; creator++)
{
err = (*creator) ();
if (err)
goto error;
}
return GRUB_ERR_NONE;
error:
grub_error_push ();
grub_mb2_tags_free ();
grub_error_pop ();
return err;
}
static grub_err_t
grub_mb2_tags_finish (void)
{
struct multiboot2_tag_start *start;
grub_err_t err;
/* Create the `end' tag. */
err = grub_mb2_tag_alloc (0, MULTIBOOT2_TAG_END,
sizeof (struct multiboot2_tag_end));
if (err)
goto error;
/* We created the `start' tag first. Update it now. */
start = (struct multiboot2_tag_start *) grub_mb2_tags;
start->size = grub_mb2_tags_pos - grub_mb2_tags;
return GRUB_ERR_NONE;
error:
grub_error_push ();
grub_mb2_tags_free ();
grub_error_pop ();
return err;
}
static grub_err_t
grub_mb2_boot (void)
{
grub_mb2_tags_finish ();
grub_dprintf ("loader", "Tags at %p\n", grub_mb2_tags);
grub_mb2_arch_boot (entry, grub_mb2_tags);
/* Not reached. */
return GRUB_ERR_NONE;
}
static grub_err_t
grub_mb2_unload (void)
{
struct multiboot2_tag_header *tag;
struct multiboot2_tag_header *tags =
(struct multiboot2_tag_header *) grub_mb2_tags;
/* 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);
}
}
/* Allow architecture to un-reserve memory. */
grub_mb2_arch_unload (tags);
/* Free the tags themselves. */
grub_mb2_tags_free ();
grub_dl_unref (my_mod);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_mb2_load_other (grub_file_t file __attribute__ ((unused)),
void *buffer __attribute__ ((unused)))
{
/* XXX Create module tag here. */
return grub_error (GRUB_ERR_UNKNOWN_OS, "currently only ELF is supported");
}
/* Create the tag containing the cmdline and the address of the module data. */
static grub_err_t
grub_mb2_tag_module_create (grub_addr_t modaddr, grub_size_t modsize,
char *type, int key, int argc, char *argv[])
{
struct multiboot2_tag_module *module;
grub_ssize_t argslen = 0;
grub_err_t err;
char *p;
grub_addr_t module_addr;
int i;
/* Allocate enough space for the arguments and spaces between them. */
for (i = 0; i < argc; i++)
argslen += grub_strlen (argv[i]) + 1;
/* Note: includes implicit 1-byte cmdline. */
err = grub_mb2_tag_alloc (&module_addr, key,
sizeof (struct multiboot2_tag_module) + argslen);
if (err)
return grub_errno;
module = (struct multiboot2_tag_module *) module_addr;
module->addr = modaddr;
module->size = modsize;
grub_strcpy(module->type, type);
/* Fill in the command line. */
p = module->cmdline;
for (i = 0; i < argc; i++)
{
p = grub_stpcpy (p, argv[i]);
*p++ = ' ';
}
module->cmdline[argslen] = '\0';
return GRUB_ERR_NONE;
}
/* Load ELF32 or ELF64. */
static grub_err_t
grub_mb2_load_elf (grub_elf_t elf, int argc, char *argv[])
{
grub_addr_t kern_base;
grub_size_t kern_size;
grub_err_t err;
if (grub_elf_is_elf32 (elf))
{
entry = elf->ehdr.ehdr32.e_entry;
err = grub_elf32_load (elf, grub_mb2_arch_elf32_hook, &kern_base,
&kern_size);
}
else if (grub_elf_is_elf64 (elf))
{
entry = elf->ehdr.ehdr64.e_entry;
err = grub_elf64_load (elf, grub_mb2_arch_elf64_hook, &kern_base,
&kern_size);
}
else
err = grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class");
if (err)
goto fail;
grub_dprintf ("loader", "Entry point is 0x%lx.\n", (unsigned long) entry);
grub_mb2_tag_module_create (kern_base, kern_size, "kernel",
MULTIBOOT2_TAG_MODULE, argc, argv);
fail:
return err;
}
void
grub_multiboot2 (int argc, char *argv[])
{
char *buffer;
grub_file_t file = 0;
grub_elf_t elf = 0;
struct multiboot2_header *header = 0;
char *p;
grub_ssize_t len;
grub_err_t err;
int header_found = 0;
grub_loader_unset ();
if (argc == 0)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
goto fail;
}
file = grub_gzfile_open (argv[0], 1);
if (! file)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file");
goto fail;
}
buffer = grub_malloc (MULTIBOOT2_HEADER_SEARCH);
if (! buffer)
return;
len = grub_file_read (file, buffer, MULTIBOOT2_HEADER_SEARCH);
if (len < 32)
{
grub_error (GRUB_ERR_BAD_OS, "file too small");
goto fail;
}
/* Look for the multiboot header in the buffer. The header should
be at least 8 bytes and aligned on a 8-byte boundary. */
for (p = buffer; p <= buffer + len - 8; p += 8)
{
header = (struct multiboot2_header *) p;
if (header->magic == MULTIBOOT2_HEADER_MAGIC)
{
header_found = 1;
break;
}
}
if (! header_found)
grub_dprintf ("loader", "No multiboot 2 header found.\n");
/* Create the basic tags. */
grub_dprintf ("loader", "Creating multiboot 2 tags\n");
grub_mb2_tags_create ();
/* Load the kernel and create its tag. */
elf = grub_elf_file (file);
if (elf)
{
grub_dprintf ("loader", "Loading ELF multiboot 2 file.\n");
err = grub_mb2_load_elf (elf, argc-1, &argv[1]);
grub_elf_close (elf);
}
else
{
grub_errno = 0;
grub_dprintf ("loader", "Loading non-ELF multiboot 2 file.\n");
if (header)
err = grub_mb2_load_other (file, header);
else
err = grub_error (GRUB_ERR_BAD_OS,
"need multiboot 2 header to load non-ELF files");
grub_file_close (file);
}
grub_free (buffer);
if (err)
goto fail;
/* Good to go. */
grub_loader_set (grub_mb2_boot, grub_mb2_unload, 1);
return;
fail:
grub_mb2_tags_free ();
grub_dl_unref (my_mod);
}
void
grub_module2 (int argc, char *argv[])
{
grub_file_t file;
grub_addr_t modaddr = 0;
grub_ssize_t modsize = 0;
grub_err_t err;
if (argc == 0)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified");
return;
}
if (argc == 1)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "no module type specified");
return;
}
if (entry == 0)
{
grub_error (GRUB_ERR_BAD_ARGUMENT,
"you need to load the multiboot kernel first");
return;
}
/* Load module data. */
file = grub_gzfile_open (argv[0], 1);
if (! file)
goto out;
modsize = grub_file_size (file);
err = grub_mb2_arch_module_alloc (modsize, &modaddr);
if (err)
goto out;
grub_dprintf ("loader", "Loading module at 0x%x - 0x%x\n", modaddr,
modaddr + modsize);
if (grub_file_read (file, (void *) modaddr, modsize) != modsize)
{
grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file");
goto out;
}
/* Create the module tag. */
err = grub_mb2_tag_module_create (modaddr, modsize,
argv[1], MULTIBOOT2_TAG_MODULE,
argc-2, &argv[2]);
if (err)
goto out;
out:
grub_error_push ();
if (file)
grub_file_close (file);
if (modaddr)
grub_mb2_arch_module_free (modaddr, modsize);
grub_error_pop ();
}

View file

@ -1,7 +1,7 @@
/* multiboot_loader.c - boot multiboot 1 or 2 OS image */ /* multiboot_loader.c - boot multiboot kernel image */
/* /*
* GRUB -- GRand Unified Bootloader * GRUB -- GRand Unified Bootloader
* Copyright (C) 2007,2008,2009 Free Software Foundation, Inc. * Copyright (C) 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
@ -18,8 +18,6 @@
*/ */
#include <grub/multiboot.h> #include <grub/multiboot.h>
#include <grub/multiboot2.h>
#include <multiboot2.h>
#include <grub/elf.h> #include <grub/elf.h>
#include <grub/file.h> #include <grub/file.h>
#include <grub/err.h> #include <grub/err.h>
@ -28,18 +26,10 @@
#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;
/* This tracks which version of multiboot to use when using
* the module command. By default use multiboot version 1.
* values:
* 1 - Multiboot version 1
* 2 - Multiboot version 2
*/
static unsigned int module_version_status = 1;
static int static int
find_multi_boot1_header (grub_file_t file) find_multi_boot1_header (grub_file_t file)
{ {
@ -69,34 +59,6 @@ find_multi_boot1_header (grub_file_t file)
return found_status; return found_status;
} }
static int
find_multi_boot2_header (grub_file_t file)
{
struct multiboot_header *header;
char buffer[MULTIBOOT_SEARCH];
int found_status = 0;
grub_ssize_t len;
len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
if (len < 32)
return found_status;
/* Look for the multiboot header in the buffer. The header should
be at least 8 bytes and aligned on a 8-byte boundary. */
for (header = (struct multiboot_header *) buffer;
((char *) header <= buffer + len - 8) || (header = 0);
header = (struct multiboot_header *) ((char *) header + 8))
{
if (header->magic == MULTIBOOT2_HEADER_MAGIC)
{
found_status = 1;
break;
}
}
return found_status;
}
static grub_err_t static grub_err_t
grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)), grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[]) int argc, char *argv[])
@ -122,8 +84,6 @@ grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)),
/* find which header is in the file */ /* find which header is in the file */
if (find_multi_boot1_header (file)) if (find_multi_boot1_header (file))
header_multi_ver_found = 1; header_multi_ver_found = 1;
else if (find_multi_boot2_header (file))
header_multi_ver_found = 2;
else else
{ {
grub_error (GRUB_ERR_BAD_OS, "multiboot header not found"); grub_error (GRUB_ERR_BAD_OS, "multiboot header not found");
@ -136,25 +96,9 @@ grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)),
/* Launch multi boot with header */ /* Launch multi boot with header */
/* XXX Find a better way to identify this. grub_dprintf ("multiboot_loader",
This is for i386-pc */ "Launching multiboot 1 grub_multiboot() function\n");
#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_COREBOOT) || \ grub_multiboot (argc, argv);
defined(GRUB_MACHINE_QEMU)
if (header_multi_ver_found == 1)
{
grub_dprintf ("multiboot_loader",
"Launching multiboot 1 grub_multiboot() function\n");
grub_multiboot (argc, argv);
module_version_status = 1;
}
#endif
if (header_multi_ver_found == 0 || header_multi_ver_found == 2)
{
grub_dprintf ("multiboot_loader",
"Launching multiboot 2 grub_multiboot2() function\n");
grub_multiboot2 (argc, argv);
module_version_status = 2;
}
return grub_errno; return grub_errno;
@ -172,21 +116,9 @@ grub_cmd_module_loader (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[]) int argc, char *argv[])
{ {
#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_COREBOOT) || \ grub_dprintf("multiboot_loader",
defined(GRUB_MACHINE_QEMU) "Launching multiboot 1 grub_module() function\n");
if (module_version_status == 1) grub_module (argc, argv);
{
grub_dprintf("multiboot_loader",
"Launching multiboot 1 grub_module() function\n");
grub_module (argc, argv);
}
#endif
if (module_version_status == 2)
{
grub_dprintf("multiboot_loader",
"Launching multiboot 2 grub_module2() function\n");
grub_module2 (argc, argv);
}
return grub_errno; return grub_errno;
} }
@ -196,11 +128,17 @@ static grub_command_t cmd_multiboot, cmd_module;
GRUB_MOD_INIT(multiboot) GRUB_MOD_INIT(multiboot)
{ {
cmd_multiboot = cmd_multiboot =
#ifdef GRUB_USE_MULTIBOOT2
grub_register_command ("multiboot2", grub_cmd_multiboot_loader,
0, N_("Load a multiboot 2 kernel."));
#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
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. */
@ -176,75 +202,113 @@ 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) if (cl_term->xpos++ > cl_term->width - 2)
{ {
grub_putchar ('\n'); grub_putcode ('\n', cl_term->term);
xpos = 1; cl_term->xpos = 1;
if (ypos == (unsigned) (grub_getxy () & 0xFF)) if (cl_term->ypos == (unsigned) (cl_term->height))
ystart--; cl_term->ystart--;
else else
ypos++; cl_term->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);
} }
} }
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 +318,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 +573,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 +587,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 +595,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
@ -178,3 +198,378 @@ 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 (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;
}
#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 ("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

@ -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

@ -88,7 +88,7 @@ grub_ofconsole_putchar (grub_uint32_t c)
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_curr_x++; grub_curr_x++;
} }
} }
@ -319,7 +319,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
@ -414,8 +414,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

@ -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

@ -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)
{ {

View file

@ -1,7 +1,7 @@
#! /bin/sh -e #! /bin/sh -e
# grub-mkconfig helper script. # grub-mkconfig helper script.
# 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
@ -73,16 +73,18 @@ menuentry "${OS}" {
EOF EOF
prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/" prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | sed -e "s/^/\t/"
cat << EOF cat << EOF
multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/} echo $(gettext "Loading GNU Mach ...")
multiboot ${kernel} root=device:${GRUB_DEVICE#/dev/}
EOF EOF
prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/" prepare_grub_to_access_device ${GRUB_DEVICE} | sed -e "s/^/\t/"
cat << EOF cat << EOF
module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\ echo $(gettext "Loading the Hurd ...")
module /hurd/${hurd_fs}.static ${hurd_fs} --readonly \\
--multiboot-command-line='\${kernel-command-line}' \\ --multiboot-command-line='\${kernel-command-line}' \\
--host-priv-port='\${host-port}' \\ --host-priv-port='\${host-port}' \\
--device-master-port='\${device-port}' \\ --device-master-port='\${device-port}' \\
--exec-server-task='\${exec-task}' -T typed '\${root}' \\ --exec-server-task='\${exec-task}' -T typed '\${root}' \\
'\$(task-create)' '\$(task-resume)' '\$(task-create)' '\$(task-resume)'
module /lib/ld.so.1 exec /hurd/exec '\$(exec-task=task-create)' module /lib/ld.so.1 exec /hurd/exec '\$(exec-task=task-create)'
} }
EOF EOF

View file

@ -1,7 +1,7 @@
#! /bin/sh -e #! /bin/sh -e
# grub-mkconfig helper script. # grub-mkconfig helper script.
# 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
@ -44,12 +44,13 @@ kfreebsd_entry ()
fi fi
printf '%s\n' "${prepare_boot_cache}" printf '%s\n' "${prepare_boot_cache}"
cat << EOF cat << EOF
kfreebsd ${rel_dirname}/${basename} echo $(printf "$(gettext "Loading kernel of FreeBSD %s ...")" ${version})
kfreebsd ${rel_dirname}/${basename}
EOF EOF
if test -n "${devices}" ; then if test -n "${devices}" ; then
cat << EOF cat << EOF
kfreebsd_loadenv ${devices_rel_dirname}/${devices_basename} kfreebsd_loadenv ${devices_rel_dirname}/${devices_basename}
EOF EOF
fi fi

View file

@ -1,7 +1,7 @@
#! /bin/sh -e #! /bin/sh -e
# grub-mkconfig helper script. # grub-mkconfig helper script.
# 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
@ -64,10 +64,12 @@ linux_entry ()
fi fi
printf '%s\n' "${prepare_boot_cache}" printf '%s\n' "${prepare_boot_cache}"
cat << EOF cat << EOF
echo $(printf "$(gettext "Loading Linux %s ...")" ${version})
linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args}
EOF EOF
if test -n "${initrd}" ; then if test -n "${initrd}" ; then
cat << EOF cat << EOF
echo $(gettext "Loading initial ramdisk ...")
initrd ${rel_dirname}/${initrd} initrd ${rel_dirname}/${initrd}
EOF EOF
fi fi

View file

@ -8,7 +8,7 @@
#define PREPARER_DEFAULT NULL #define PREPARER_DEFAULT NULL
#define PUBLISHER_DEFAULT NULL #define PUBLISHER_DEFAULT NULL
#ifndef APPID_DEFAULT #ifndef APPID_DEFAULT
#define APPID_DEFAULT "MKISOFS ISO 9660 FILESYSTEM BUILDER" #define APPID_DEFAULT PACKAGE_NAME " ISO 9660 filesystem builder"
#endif #endif
#define COPYRIGHT_DEFAULT NULL #define COPYRIGHT_DEFAULT NULL
#define BIBLIO_DEFAULT NULL #define BIBLIO_DEFAULT NULL
@ -17,38 +17,4 @@
#define VOLUME_ID_DEFAULT "CDROM" #define VOLUME_ID_DEFAULT "CDROM"
#define BOOT_CATALOG_DEFAULT "boot.catalog" #define BOOT_CATALOG_DEFAULT "boot.catalog"
#define BOOT_IMAGE_DEFAULT NULL #define BOOT_IMAGE_DEFAULT NULL
#ifdef __QNX__ #define SYSTEM_ID_DEFAULT "GNU"
#define SYSTEM_ID_DEFAULT "QNX"
#endif
#ifdef __osf__
#define SYSTEM_ID_DEFAULT "OSF"
#endif
#ifdef __sun
#ifdef __SVR4
#define SYSTEM_ID_DEFAULT "Solaris"
#else
#define SYSTEM_ID_DEFAULT "SunOS"
#endif
#endif
#ifdef __hpux
#define SYSTEM_ID_DEFAULT "HP-UX"
#endif
#ifdef __sgi
#define SYSTEM_ID_DEFAULT "SGI"
#endif
#ifdef _AIX
#define SYSTEM_ID_DEFAULT "AIX"
#endif
#ifdef _WIN
#define SYSTEM_ID_DEFAULT "Win32"
#endif /* _WIN */
#ifndef SYSTEM_ID_DEFAULT
#define SYSTEM_ID_DEFAULT "LINUX"
#endif

View file

@ -26,12 +26,7 @@
#include "config.h" #include "config.h"
#include "mkisofs.h" #include "mkisofs.h"
#include "match.h" #include "match.h"
#ifdef linux
#include <getopt.h>
#else
#include "getopt.h" #include "getopt.h"
#endif
#include "iso9660.h" #include "iso9660.h"
#include <ctype.h> #include <ctype.h>
@ -914,7 +909,7 @@ int FDECL2(main, int, argc, char **, argv){
exit (0); exit (0);
break; break;
case OPTION_VERSION: case OPTION_VERSION:
printf ("%s (%s %s)\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); printf ("%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
exit (0); exit (0);
break; break;
case OPTION_NOSPLIT_SL_COMPONENT: case OPTION_NOSPLIT_SL_COMPONENT: