From acdf01cd1b5780152ce79f4dcce28dbe94fe2a8a Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 11 Dec 2009 21:28:27 +0100 Subject: [PATCH 01/96] cmostest command --- commands/i386/cmostest.c | 59 ++++++++++++++++++++++++++++++++++++++++ conf/i386-coreboot.rmk | 6 ++++ conf/i386-pc.rmk | 6 ++++ 3 files changed, 71 insertions(+) create mode 100644 commands/i386/cmostest.c diff --git a/commands/i386/cmostest.c b/commands/i386/cmostest.c new file mode 100644 index 000000000..7171766cd --- /dev/null +++ b/commands/i386/cmostest.c @@ -0,0 +1,59 @@ +/* + * 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 . + */ + +#include +#include +#include +#include + +static grub_err_t +grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int byte, bit; + char *rest; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required."); + + byte = grub_strtoul (argv[0], &rest, 0); + if (*rest != ':') + return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required."); + + bit = grub_strtoul (rest + 1, 0, 0); + + if (grub_cmos_read (byte) & (1 << bit)) + return GRUB_ERR_NONE; + + return grub_error (GRUB_ERR_TEST_FAILURE, "false"); +} + +static grub_command_t cmd; + + +GRUB_MOD_INIT(cmostest) +{ + cmd = grub_register_command ("cmostest", grub_cmd_cmostest, + "cmostest BYTE:BIT", + "Test bit at BYTE:BIT in CMOS."); +} + +GRUB_MOD_FINI(cmostest) +{ + grub_unregister_command (cmd); +} diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index e597328e7..b49af84ce 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -202,5 +202,11 @@ lsmmap_mod_SOURCES = commands/lsmmap.c lsmmap_mod_CFLAGS = $(COMMON_CFLAGS) lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For cmostest.mod +pkglib_MODULES += cmostest.mod +cmostest_mod_SOURCES = commands/i386/cmostest.c +cmostest_mod_CFLAGS = $(COMMON_CFLAGS) +cmostest_mod_LDFLAGS = $(COMMON_LDFLAGS) + include $(srcdir)/conf/i386.mk include $(srcdir)/conf/common.mk diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index 7e54b3b67..8d373e30b 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -335,6 +335,12 @@ hdparm_mod_SOURCES = commands/hdparm.c lib/hexdump.c hdparm_mod_CFLAGS = $(COMMON_CFLAGS) hdparm_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For cmostest.mod +pkglib_MODULES += cmostest.mod +cmostest_mod_SOURCES = commands/i386/cmostest.c +cmostest_mod_CFLAGS = $(COMMON_CFLAGS) +cmostest_mod_LDFLAGS = $(COMMON_LDFLAGS) + ifeq ($(enable_efiemu), yes) efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF) From d85da27cc0e1e670abee72758836f633cd52b297 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:14:24 +0100 Subject: [PATCH 02/96] Remove grub_commands_iterate --- commands/help.c | 145 ++++++++++++++++++++--------------------- include/grub/command.h | 7 +- normal/completion.c | 29 ++++----- 3 files changed, 82 insertions(+), 99 deletions(-) diff --git a/commands/help.c b/commands/help.c index 1181c3bfb..ecf77fa4c 100644 --- a/commands/help.c +++ b/commands/help.c @@ -33,94 +33,87 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, int cnt = 0; char *currarg; - auto int print_command_info (grub_command_t cmd); - auto int print_command_help (grub_command_t cmd); - - int print_command_info (grub_command_t cmd) - { - if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) && - (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE)) - { - struct grub_term_output *term; - const char *summary_translated = _(cmd->summary); - char *command_help; - grub_uint32_t *unicode_command_help; - grub_uint32_t *unicode_last_position; - - command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated); - if (!command_help) - return 1; - - grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help, - &unicode_last_position); - - FOR_ACTIVE_TERM_OUTPUTS(term) - { - unsigned stringwidth; - grub_uint32_t *unicode_last_screen_position; - - unicode_last_screen_position = unicode_command_help; - - stringwidth = 0; - - while (unicode_last_screen_position < unicode_last_position && - stringwidth < ((grub_term_width (term) / 2) - 2)) - { - stringwidth - += grub_term_getcharwidth (term, - *unicode_last_screen_position); - unicode_last_screen_position++; - } - - grub_print_ucs4 (unicode_command_help, - unicode_last_screen_position, term); - if (!(cnt % 2)) - grub_print_spaces (term, grub_term_width (term) / 2 - - stringwidth); - } - if (cnt % 2) - grub_printf ("\n"); - cnt++; - - grub_free (command_help); - grub_free (unicode_command_help); - } - return 0; - } - - int print_command_help (grub_command_t cmd) - { - if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) - { - if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg))) - { - if (cnt++ > 0) - grub_printf ("\n\n"); - - if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) - grub_arg_show_help ((grub_extcmd_t) cmd->data); - else - grub_printf ("%s %s %s\n%s\b", _("Usage:"), cmd->name, _(cmd->summary), - _(cmd->description)); - } - } - return 0; - } - if (argc == 0) { - grub_command_iterate (print_command_info); + grub_command_t cmd; + FOR_COMMANDS(cmd) + { + if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) && + (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE)) + { + struct grub_term_output *term; + const char *summary_translated = _(cmd->summary); + char *command_help; + grub_uint32_t *unicode_command_help; + grub_uint32_t *unicode_last_position; + + command_help = grub_xasprintf ("%s %s", cmd->name, summary_translated); + if (!command_help) + break; + + grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help, + &unicode_last_position); + + FOR_ACTIVE_TERM_OUTPUTS(term) + { + unsigned stringwidth; + grub_uint32_t *unicode_last_screen_position; + + unicode_last_screen_position = unicode_command_help; + + stringwidth = 0; + + while (unicode_last_screen_position < unicode_last_position && + stringwidth < ((grub_term_width (term) / 2) - 2)) + { + stringwidth + += grub_term_getcharwidth (term, + *unicode_last_screen_position); + unicode_last_screen_position++; + } + + grub_print_ucs4 (unicode_command_help, + unicode_last_screen_position, term); + if (!(cnt % 2)) + grub_print_spaces (term, grub_term_width (term) / 2 + - stringwidth); + } + if (cnt % 2) + grub_printf ("\n"); + cnt++; + + grub_free (command_help); + grub_free (unicode_command_help); + } + } if (!(cnt % 2)) grub_printf ("\n"); } else { int i; + grub_command_t cmd; for (i = 0; i < argc; i++) { currarg = args[i]; - grub_command_iterate (print_command_help); + FOR_COMMANDS(cmd) + { + if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) + { + if (! grub_strncmp (cmd->name, currarg, grub_strlen (currarg))) + { + if (cnt++ > 0) + grub_printf ("\n\n"); + + if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) + grub_arg_show_help ((grub_extcmd_t) cmd->data); + else + grub_printf ("%s %s %s\n%s\b", _("Usage:"), cmd->name, _(cmd->summary), + _(cmd->description)); + } + } + } } } diff --git a/include/grub/command.h b/include/grub/command.h index 6e9942b60..3fad88ed0 100644 --- a/include/grub/command.h +++ b/include/grub/command.h @@ -115,12 +115,7 @@ grub_command_execute (const char *name, int argc, char **argv) return (cmd) ? cmd->func (cmd, argc, argv) : GRUB_ERR_FILE_NOT_FOUND; } -static inline int -grub_command_iterate (int (*func) (grub_command_t)) -{ - return grub_list_iterate (GRUB_AS_LIST (grub_command_list), - (grub_list_hook_t) func); -} +#define FOR_COMMANDS(var) for ((var) = grub_command_list; (var); (var) = (var)->next) void grub_register_core_commands (void); diff --git a/normal/completion.c b/normal/completion.c index 13e8f7a6b..13c4b7b05 100644 --- a/normal/completion.c +++ b/normal/completion.c @@ -176,21 +176,6 @@ iterate_dev (const char *devname) return 0; } -static int -iterate_command (grub_command_t cmd) -{ - if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) - { - if (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE) - { - if (add_completion (cmd->name, " ", GRUB_COMPLETION_TYPE_COMMAND)) - return 1; - } - } - - return 0; -} - /* Complete a device. */ static int complete_device (void) @@ -421,8 +406,18 @@ grub_normal_do_completion (char *buf, int *restore, if (argc == 1 || argc == 0) { /* Complete a command. */ - if (grub_command_iterate (iterate_command)) - goto fail; + grub_command_t cmd; + FOR_COMMANDS(cmd) + { + if (cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) + { + if (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE) + { + if (add_completion (cmd->name, " ", GRUB_COMPLETION_TYPE_COMMAND)) + goto fail; + } + } + } } else if (*current_word == '-') { From fbc5a383e2742ffdf166ddcd98e12e87999aecf4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:18:19 +0100 Subject: [PATCH 03/96] Remove list_iterate usage auth.c --- normal/auth.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/normal/auth.c b/normal/auth.c index 156b84c37..6d475cc0a 100644 --- a/normal/auth.c +++ b/normal/auth.c @@ -133,25 +133,24 @@ static int is_authenticated (const char *userlist) { const char *superusers; - - auto int hook (grub_list_t item); - int hook (grub_list_t item) - { - const char *name; - if (!((struct grub_auth_user *) item)->authenticated) - return 0; - name = ((struct grub_auth_user *) item)->name; - - return (userlist && grub_strword (userlist, name)) - || grub_strword (superusers, name); - } + struct grub_auth_user *user; superusers = grub_env_get ("superusers"); if (!superusers) return 1; - return grub_list_iterate (GRUB_AS_LIST (users), hook); + for (user = users; user; user = user->next) + { + if (!(user->authenticated)) + continue; + + if ((userlist && grub_strword (userlist, user->name)) + || grub_strword (superusers, user->name)) + return 1; + } + + return 0; } static int From 2aa6398b64430fc5235361b69efbae56e0188aec Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:21:01 +0100 Subject: [PATCH 04/96] Remove second part of list_iterate usage auth.c --- normal/auth.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/normal/auth.c b/normal/auth.c index 6d475cc0a..87337afda 100644 --- a/normal/auth.c +++ b/normal/auth.c @@ -204,22 +204,7 @@ grub_auth_check_authentication (const char *userlist) grub_err_t err; static unsigned long punishment_delay = 1; char entered[GRUB_AUTH_MAX_PASSLEN]; - - auto int hook (grub_list_t item); - int hook (grub_list_t item) - { - if (grub_strcmp (login, ((struct grub_auth_user *) item)->name) == 0) - cur = (struct grub_auth_user *) item; - return 0; - } - - auto int hook_any (grub_list_t item); - int hook_any (grub_list_t item) - { - if (((struct grub_auth_user *) item)->callback) - cur = (struct grub_auth_user *) item; - return 0; - } + struct grub_auth_user *user; grub_memset (login, 0, sizeof (login)); @@ -239,7 +224,11 @@ grub_auth_check_authentication (const char *userlist) if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN)) goto access_denied; - grub_list_iterate (GRUB_AS_LIST (users), hook); + for (user = users; user; user = user->next) + { + if (grub_strcmp (login, user->name) == 0) + cur = user; + } if (!cur || ! cur->callback) goto access_denied; From 7c0ab99bd2095fdd081e5c627727a3c878b35409 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:23:19 +0100 Subject: [PATCH 05/96] Remove list_iterate usage functional_test.c --- tests/lib/functional_test.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tests/lib/functional_test.c b/tests/lib/functional_test.c index 8ff08cf8a..33eeec451 100644 --- a/tests/lib/functional_test.c +++ b/tests/lib/functional_test.c @@ -26,15 +26,10 @@ grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused))) { - auto int run_test (grub_test_t test); - int run_test (grub_test_t test) - { - grub_test_run (test); - return 0; - } + grub_test_t test; - grub_list_iterate (GRUB_AS_LIST (grub_test_list), - (grub_list_hook_t) run_test); + for (test = grub_test_list; test; test = test->next) + grub_test_run (test); return GRUB_ERR_NONE; } From 42ca71ca47cbd9b83c9febee2a6a1950c0fcd58f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:25:53 +0100 Subject: [PATCH 06/96] FOR_LIST_ELEMENTS convenience macros --- include/grub/list.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/grub/list.h b/include/grub/list.h index 5559158dc..1c00a349e 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -40,6 +40,8 @@ int EXPORT_FUNC(grub_list_iterate) (grub_list_t head, grub_list_hook_t hook); void EXPORT_FUNC(grub_list_insert) (grub_list_t *head, grub_list_t item, grub_list_test_t test); +#define FOR_LIST_ELEMENTS(var, list) for ((var) = (list); (var); (var) = (var)->next) + static inline void * grub_bad_type_cast_real (int line, const char *file) ATTRIBUTE_ERROR ("bad type cast between incompatible grub types"); From 3f8ae91c0913ec34baea73adb4368a44a41e9416 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:32:21 +0100 Subject: [PATCH 07/96] Use FOR_LIST_ELEMENTS convenience macros --- include/grub/command.h | 2 +- include/grub/partition.h | 2 +- include/grub/term.h | 8 ++++---- normal/auth.c | 2 +- tests/lib/functional_test.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/grub/command.h b/include/grub/command.h index 3fad88ed0..6bd3d07c9 100644 --- a/include/grub/command.h +++ b/include/grub/command.h @@ -115,7 +115,7 @@ grub_command_execute (const char *name, int argc, char **argv) return (cmd) ? cmd->func (cmd, argc, argv) : GRUB_ERR_FILE_NOT_FOUND; } -#define FOR_COMMANDS(var) for ((var) = grub_command_list; (var); (var) = (var)->next) +#define FOR_COMMANDS(var) FOR_LIST_ELEMENTS((var), grub_command_list) void grub_register_core_commands (void); diff --git a/include/grub/partition.h b/include/grub/partition.h index 80a9c15f0..722c7b3e0 100644 --- a/include/grub/partition.h +++ b/include/grub/partition.h @@ -91,7 +91,7 @@ grub_partition_map_unregister (grub_partition_map_t partmap) GRUB_AS_LIST (partmap)); } -#define FOR_PARTITION_MAPS(var) for (var = grub_partition_map_list; var; var = var->next) +#define FOR_PARTITION_MAPS(var) FOR_LIST_ELEMENTS((var), (grub_partition_map_list)) static inline grub_disk_addr_t diff --git a/include/grub/term.h b/include/grub/term.h index 143aabe1e..230436388 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -245,10 +245,10 @@ grub_term_unregister_output (grub_term_output_t term) GRUB_AS_LIST (term)); } -#define FOR_ACTIVE_TERM_INPUTS(var) for (var = grub_term_inputs; var; var = var->next) -#define FOR_DISABLED_TERM_INPUTS(var) for (var = grub_term_inputs_disabled; var; var = var->next) -#define FOR_ACTIVE_TERM_OUTPUTS(var) for (var = grub_term_outputs; var; var = var->next) -#define FOR_DISABLED_TERM_OUTPUTS(var) for (var = grub_term_outputs_disabled; var; var = var->next) +#define FOR_ACTIVE_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_inputs)) +#define FOR_DISABLED_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_inputs_disabled)) +#define FOR_ACTIVE_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs)) +#define FOR_DISABLED_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs_disabled)) void EXPORT_FUNC(grub_putchar) (int c); void EXPORT_FUNC(grub_putcode) (grub_uint32_t code, diff --git a/normal/auth.c b/normal/auth.c index 87337afda..c28f50024 100644 --- a/normal/auth.c +++ b/normal/auth.c @@ -140,7 +140,7 @@ is_authenticated (const char *userlist) if (!superusers) return 1; - for (user = users; user; user = user->next) + FOR_LIST_ELEMENTS (user, users) { if (!(user->authenticated)) continue; diff --git a/tests/lib/functional_test.c b/tests/lib/functional_test.c index 33eeec451..6aafe4dbb 100644 --- a/tests/lib/functional_test.c +++ b/tests/lib/functional_test.c @@ -28,7 +28,7 @@ grub_functional_test (struct grub_extcmd *cmd __attribute__ ((unused)), { grub_test_t test; - for (test = grub_test_list; test; test = test->next) + FOR_LIST_ELEMENTS (test, grub_test_list) grub_test_run (test); return GRUB_ERR_NONE; } From 41e12098274d28183aa5f46d0c26863383f5b26d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:35:34 +0100 Subject: [PATCH 08/96] Remove list_iterate usage tests/ --- tests/lib/test.c | 20 +++++++------------- tests/lib/unit_test.c | 12 ++++-------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/tests/lib/test.c b/tests/lib/test.c index b5c054370..3029495c6 100644 --- a/tests/lib/test.c +++ b/tests/lib/test.c @@ -134,23 +134,17 @@ grub_test_unregister (const char *name) int grub_test_run (grub_test_t test) { - auto int print_failure (grub_test_failure_t item); - int print_failure (grub_test_failure_t item) - { - grub_test_failure_t failure = (grub_test_failure_t) item; - - grub_printf (" %s:%s:%u: %s\n", - (failure->file ? : ""), - (failure->funp ? : ""), - failure->line, (failure->message ? : "")); - return 0; - } + grub_test_failure_t failure; test->main (); grub_printf ("%s:\n", test->name); - grub_list_iterate (GRUB_AS_LIST (failure_list), - (grub_list_hook_t) print_failure); + FOR_LIST_ELEMENTS (failure, failure_list) + grub_printf (" %s:%s:%u: %s\n", + (failure->file ? : ""), + (failure->funp ? : ""), + failure->line, (failure->message ? : "")); + if (!failure_list) grub_printf ("%s: PASS\n", test->name); else diff --git a/tests/lib/unit_test.c b/tests/lib/unit_test.c index e461150de..e8b97b1f4 100644 --- a/tests/lib/unit_test.c +++ b/tests/lib/unit_test.c @@ -34,16 +34,12 @@ main (int argc __attribute__ ((unused)), extern void grub_unit_test_init (void); extern void grub_unit_test_fini (void); - auto int run_test (grub_test_t test); - int run_test (grub_test_t test) - { - status = grub_test_run (test) ? : status; - return 0; - } + grub_test_t test; grub_unit_test_init (); - grub_list_iterate (GRUB_AS_LIST (grub_test_list), - (grub_list_hook_t) run_test); + FOR_LIST_ELEMENTS (test, grub_test_list) + status = grub_test_run (test) ? : status; + grub_unit_test_fini (); exit (status); From fda282327f5c373d2c4ffd8c2b3080d09d742af8 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 19:44:18 +0100 Subject: [PATCH 09/96] Complete eradication of grub_list_iterate --- commands/handler.c | 30 ++++++++++++++++-------------- include/grub/list.h | 1 - kern/list.c | 31 +++++-------------------------- normal/handler.c | 42 ++++++++++++++++-------------------------- 4 files changed, 37 insertions(+), 67 deletions(-) diff --git a/commands/handler.c b/commands/handler.c index f9270972b..2bfa67415 100644 --- a/commands/handler.c +++ b/commands/handler.c @@ -32,21 +32,17 @@ grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)), void *curr_item = 0; grub_handler_class_t head; - auto int list_item (grub_named_list_t item); - int list_item (grub_named_list_t item) - { - if (item == curr_item) - grub_putchar ('*'); - - grub_printf ("%s\n", item->name); - - return 0; - } - head = grub_handler_class_list; if (argc == 0) { - grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_item); + grub_handler_class_t item; + FOR_LIST_ELEMENTS(item, head) + { + if (item == curr_item) + grub_putchar ('*'); + + grub_printf ("%s\n", item->name); + } } else { @@ -63,9 +59,15 @@ grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)), if (argc == 0) { + grub_handler_class_t item; curr_item = class->cur_handler; - grub_list_iterate (GRUB_AS_LIST (class->handler_list), - (grub_list_hook_t) list_item); + FOR_LIST_ELEMENTS(item, head) + { + if (item == curr_item) + grub_putchar ('*'); + + grub_printf ("%s\n", item->name); + } } else { diff --git a/include/grub/list.h b/include/grub/list.h index 1c00a349e..2fd418aca 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -36,7 +36,6 @@ typedef int (*grub_list_test_t) (grub_list_t new_item, grub_list_t item); void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head); void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item); -int EXPORT_FUNC(grub_list_iterate) (grub_list_t head, grub_list_hook_t hook); void EXPORT_FUNC(grub_list_insert) (grub_list_t *head, grub_list_t item, grub_list_test_t test); diff --git a/kern/list.c b/kern/list.c index 379b0d886..507d13f86 100644 --- a/kern/list.c +++ b/kern/list.c @@ -53,18 +53,6 @@ grub_list_remove (grub_list_t *head, grub_list_t item) } } -int -grub_list_iterate (grub_list_t head, grub_list_hook_t hook) -{ - grub_list_t p; - - for (p = head; p; p = p->next) - if (hook (p)) - return 1; - - return 0; -} - void grub_list_insert (grub_list_t *head, grub_list_t item, grub_list_test_t test) @@ -82,22 +70,13 @@ grub_list_insert (grub_list_t *head, grub_list_t item, void * grub_named_list_find (grub_named_list_t head, const char *name) { - grub_named_list_t result = NULL; + grub_named_list_t item; - auto int list_find (grub_named_list_t item); - int list_find (grub_named_list_t item) - { - if (! grub_strcmp (item->name, name)) - { - result = item; - return 1; - } + FOR_LIST_ELEMENTS (item, head) + if (grub_strcmp (item->name, name) == 0) + return item; - return 0; - } - - grub_list_iterate (GRUB_AS_LIST (head), (grub_list_hook_t) list_find); - return result; + return NULL; } void diff --git a/normal/handler.c b/normal/handler.c index 686626929..8c97fd9a8 100644 --- a/normal/handler.c +++ b/normal/handler.c @@ -138,30 +138,6 @@ read_handler_list (void) static int first_time = 1; const char *class_name; - auto int iterate_handler (grub_handler_t handler); - int iterate_handler (grub_handler_t handler) - { - char name[grub_strlen (class_name) + grub_strlen (handler->name) + 2]; - - grub_strcpy (name, class_name); - grub_strcat (name, "."); - grub_strcat (name, handler->name); - - insert_handler (name, 0); - - return 0; - } - - auto int iterate_class (grub_handler_class_t class); - int iterate_class (grub_handler_class_t class) - { - class_name = class->name; - grub_list_iterate (GRUB_AS_LIST (class->handler_list), - (grub_list_hook_t) iterate_handler); - - return 0; - } - /* Make sure that this function does not get executed twice. */ if (! first_time) return; @@ -209,8 +185,22 @@ read_handler_list (void) } } - grub_list_iterate (GRUB_AS_LIST (grub_handler_class_list), - (grub_list_hook_t) iterate_class); + grub_handler_class_t class; + FOR_LIST_ELEMENTS (class, grub_handler_class_list) + { + grub_handler_t handler; + class_name = class->name; + FOR_LIST_ELEMENTS(handler, class->handler_list) + { + char name[grub_strlen (class_name) + grub_strlen (handler->name) + 2]; + + grub_strcpy (name, class_name); + grub_strcat (name, "."); + grub_strcat (name, handler->name); + + insert_handler (name, 0); + } + } /* Ignore errors. */ grub_errno = GRUB_ERR_NONE; From 82f542016ebd7bd31ce2b74085b22e5f4ead49af Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 20:00:06 +0100 Subject: [PATCH 10/96] Eradicate grub_list_insert --- include/grub/list.h | 2 -- kern/list.c | 39 ++++++++++++++------------------------- 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/include/grub/list.h b/include/grub/list.h index 2fd418aca..73d51be12 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -36,8 +36,6 @@ typedef int (*grub_list_test_t) (grub_list_t new_item, grub_list_t item); void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head); void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item); -void EXPORT_FUNC(grub_list_insert) (grub_list_t *head, grub_list_t item, - grub_list_test_t test); #define FOR_LIST_ELEMENTS(var, list) for ((var) = (list); (var); (var) = (var)->next) diff --git a/kern/list.c b/kern/list.c index 507d13f86..5b0248129 100644 --- a/kern/list.c +++ b/kern/list.c @@ -53,20 +53,6 @@ grub_list_remove (grub_list_t *head, grub_list_t item) } } -void -grub_list_insert (grub_list_t *head, grub_list_t item, - grub_list_test_t test) -{ - grub_list_t *p, q; - - for (p = head, q = *p; q; p = &(q->next), q = q->next) - if (test (item, q)) - break; - - *p = item; - item->next = q; -} - void * grub_named_list_find (grub_named_list_t head, const char *name) { @@ -84,27 +70,30 @@ grub_prio_list_insert (grub_prio_list_t *head, grub_prio_list_t nitem) { int inactive = 0; - auto int test (grub_prio_list_t new_item, grub_prio_list_t item); - int test (grub_prio_list_t new_item, grub_prio_list_t item) + grub_prio_list_t *p, q; + + for (p = head, q = *p; q; p = &(q->next), q = q->next) { int r; - r = grub_strcmp (new_item->name, item->name); - if (r) - return (r < 0); + r = grub_strcmp (nitem->name, q->name); + if (r < 0) + break; + if (r > 0) + continue; - if (new_item->prio >= (item->prio & GRUB_PRIO_LIST_PRIO_MASK)) + if (nitem->prio >= (q->prio & GRUB_PRIO_LIST_PRIO_MASK)) { - item->prio &= ~GRUB_PRIO_LIST_FLAG_ACTIVE; - return 1; + q->prio &= ~GRUB_PRIO_LIST_FLAG_ACTIVE; + break; } inactive = 1; - return 0; } - grub_list_insert (GRUB_AS_LIST_P (head), GRUB_AS_LIST (nitem), - (grub_list_test_t) test); + *p = nitem; + nitem->next = q; + if (! inactive) nitem->prio |= GRUB_PRIO_LIST_FLAG_ACTIVE; } From 8cfa78770df70c60637fddc12749b256382eca7d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 20:05:25 +0100 Subject: [PATCH 11/96] cleanup list.h a bit --- include/grub/list.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/grub/list.h b/include/grub/list.h index 73d51be12..d3abd69c4 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -30,9 +30,6 @@ struct grub_list }; typedef struct grub_list *grub_list_t; -typedef int (*grub_list_hook_t) (grub_list_t item); -typedef int (*grub_list_test_t) (grub_list_t new_item, grub_list_t item); - void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head); void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item); From 0959e5ec30d629f661129bbaf4dfed8c41c7a5d9 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 26 Mar 2010 20:20:52 +0100 Subject: [PATCH 12/96] Remove grub_list_pop --- gettext/gettext.c | 10 +++------- include/grub/list.h | 1 - kern/list.c | 12 ------------ normal/handler.c | 8 +++++--- tests/lib/test.c | 4 +++- 5 files changed, 11 insertions(+), 24 deletions(-) diff --git a/gettext/gettext.c b/gettext/gettext.c index 0aa8decbd..bc7d42824 100644 --- a/gettext/gettext.c +++ b/gettext/gettext.c @@ -309,14 +309,10 @@ grub_gettext_init_ext (const char *lang) static void grub_gettext_delete_list (void) { - struct grub_gettext_msg *item; - - while ((item = - grub_list_pop (GRUB_AS_LIST_P (&grub_gettext_msg_list))) != 0) + while (grub_gettext_msg_list) { - char *original = (char *) ((struct grub_gettext_msg *) item)->name; - grub_free (original); - + grub_free ((char *) grub_gettext_msg_list->name); + grub_gettext_msg_list = grub_gettext_msg_list->next; /* Don't delete the translated message because could be in use. */ } } diff --git a/include/grub/list.h b/include/grub/list.h index d3abd69c4..75353010c 100644 --- a/include/grub/list.h +++ b/include/grub/list.h @@ -31,7 +31,6 @@ struct grub_list typedef struct grub_list *grub_list_t; void EXPORT_FUNC(grub_list_push) (grub_list_t *head, grub_list_t item); -void * EXPORT_FUNC(grub_list_pop) (grub_list_t *head); void EXPORT_FUNC(grub_list_remove) (grub_list_t *head, grub_list_t item); #define FOR_LIST_ELEMENTS(var, list) for ((var) = (list); (var); (var) = (var)->next) diff --git a/kern/list.c b/kern/list.c index 5b0248129..33c334166 100644 --- a/kern/list.c +++ b/kern/list.c @@ -28,18 +28,6 @@ grub_list_push (grub_list_t *head, grub_list_t item) *head = item; } -void * -grub_list_pop (grub_list_t *head) -{ - grub_list_t item; - - item = *head; - if (item) - *head = item->next; - - return item; -} - void grub_list_remove (grub_list_t *head, grub_list_t item) { diff --git a/normal/handler.c b/normal/handler.c index 8c97fd9a8..4c8b8f769 100644 --- a/normal/handler.c +++ b/normal/handler.c @@ -33,7 +33,7 @@ struct grub_handler_list grub_command_t cmd; }; -static grub_list_t handler_list; +static struct grub_handler_list *handler_list; static grub_err_t grub_handler_cmd (struct grub_command *cmd, @@ -127,7 +127,7 @@ insert_handler (char *name, char *module) } item->cmd->data = data; - grub_list_push (&handler_list, GRUB_AS_LIST (item)); + grub_list_push (GRUB_AS_LIST_P (&handler_list), GRUB_AS_LIST (item)); } /* Read the file handler.lst for auto-loading. */ @@ -211,8 +211,10 @@ free_handler_list (void) { struct grub_handler_list *item; - while ((item = grub_list_pop (&handler_list)) != 0) + while (handler_list) { + item = handler_list; + handler_list = handler_list->next; grub_free (item->cmd->data); grub_unregister_command (item->cmd); grub_free (item->name); diff --git a/tests/lib/test.c b/tests/lib/test.c index 3029495c6..06d78b7d7 100644 --- a/tests/lib/test.c +++ b/tests/lib/test.c @@ -66,8 +66,10 @@ free_failures (void) { grub_test_failure_t item; - while ((item = grub_list_pop (GRUB_AS_LIST_P (&failure_list))) != 0) + while (failure_list) { + item = failure_list; + failure_list = item->next; if (item->message) grub_free (item->message); From d56a6ac7f67fcfaf5490c0d3d9bb9240ac2c31f7 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:19:42 +0100 Subject: [PATCH 13/96] Remove handlers --- commands/handler.c | 103 ------------------ conf/any-emu.rmk | 2 +- conf/common.rmk | 43 ++------ conf/i386-coreboot.rmk | 2 +- conf/i386-ieee1275.rmk | 2 +- conf/i386-pc.rmk | 4 +- conf/i386-qemu.rmk | 2 +- conf/mips-qemu-mips.rmk | 2 +- conf/mips-yeeloong.rmk | 2 +- conf/powerpc-ieee1275.rmk | 2 +- conf/sparc64-ieee1275.rmk | 2 +- conf/x86-efi.rmk | 2 +- include/grub/handler.h | 60 ---------- include/grub/parser.h | 32 +----- include/grub/script_sh.h | 3 + include/grub/term.h | 2 +- kern/handler.c | 64 ----------- kern/main.c | 1 - kern/parser.c | 8 +- kern/rescue_parser.c | 14 +-- kern/rescue_reader.c | 2 +- normal/handler.c | 223 -------------------------------------- normal/main.c | 53 ++------- normal/menu_entry.c | 3 +- script/main.c | 18 +-- util/grub-fstest.c | 3 - util/grub-probe.c | 3 - util/grub-script-check.c | 7 -- util/i386/pc/grub-setup.c | 3 - 29 files changed, 40 insertions(+), 627 deletions(-) delete mode 100644 commands/handler.c delete mode 100644 include/grub/handler.h delete mode 100644 kern/handler.c delete mode 100644 normal/handler.c diff --git a/commands/handler.c b/commands/handler.c deleted file mode 100644 index 2bfa67415..000000000 --- a/commands/handler.c +++ /dev/null @@ -1,103 +0,0 @@ -/* handler.c - commands to list or select handlers */ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include - -static grub_err_t -grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)), - int argc, char **args) -{ - void *curr_item = 0; - grub_handler_class_t head; - - head = grub_handler_class_list; - if (argc == 0) - { - grub_handler_class_t item; - FOR_LIST_ELEMENTS(item, head) - { - if (item == curr_item) - grub_putchar ('*'); - - grub_printf ("%s\n", item->name); - } - } - else - { - char *class_name; - grub_handler_class_t class; - - class_name = args[0]; - argc--; - args++; - - class = grub_named_list_find (GRUB_AS_NAMED_LIST (head), class_name); - if (! class) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found"); - - if (argc == 0) - { - grub_handler_class_t item; - curr_item = class->cur_handler; - FOR_LIST_ELEMENTS(item, head) - { - if (item == curr_item) - grub_putchar ('*'); - - grub_printf ("%s\n", item->name); - } - } - else - { - grub_handler_t handler; - - handler = - grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list), - args[0]); - - if (! handler) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found"); - - grub_handler_set_current (class, handler); - } - } - - return 0; -} - -static grub_command_t cmd_handler; - -GRUB_MOD_INIT(handler) -{ - cmd_handler = - grub_register_command ("handler", grub_cmd_handler, - N_("[class [handler]]"), - N_("List or select a handler.")); -} - -GRUB_MOD_FINI(handler) -{ - grub_unregister_command (cmd_handler); -} diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 758a8d720..3a2c47bf5 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -7,7 +7,7 @@ util/grub-emu.c_DEPENDENCIES = grub_emu_init.h kernel_img_RELOCATABLE = yes pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ - kern/err.c kern/list.c kern/handler.c kern/command.c \ + kern/err.c kern/list.c kern/command.c \ kern/corecmd.c kern/file.c kern/fs.c kern/main.c kern/misc.c \ kern/parser.c kern/partition.c kern/term.c \ kern/rescue_reader.c kern/rescue_parser.c \ diff --git a/conf/common.rmk b/conf/common.rmk index f55bbfe0c..6300af3aa 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -27,7 +27,7 @@ util/grub-probe.c_DEPENDENCIES = grub_probe_init.h grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \ util/hostdisk.c util/misc.c util/getroot.c \ kern/device.c kern/disk.c kern/err.c kern/misc.c \ - kern/parser.c kern/partition.c kern/file.c kern/list.c \ + kern/partition.c kern/file.c kern/list.c \ \ fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ @@ -104,12 +104,11 @@ DISTCLEANFILES += grub_script.yy.c grub_script.yy.h # For grub-script-check. bin_UTILITIES += grub-script-check -util/grub-script-check.c_DEPENDENCIES = grub_script_check_init.h grub_script_check_SOURCES = gnulib/progname.c gnulib/getdelim.c gnulib/getline.c \ util/grub-script-check.c util/misc.c \ script/main.c script/script.c script/function.c script/lexer.c \ - kern/handler.c kern/err.c kern/parser.c kern/list.c \ - kern/misc.c kern/env.c grub_script_check_init.c grub_script.tab.c \ + kern/err.c kern/list.c \ + kern/misc.c kern/env.c grub_script.tab.c \ grub_script.yy.c MOSTLYCLEANFILES += symlist.c kernel_syms.lst @@ -119,7 +118,7 @@ kernel_img_HEADERS += boot.h cache.h device.h disk.h dl.h elf.h elfload.h \ env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \ partition.h msdos_partition.h reader.h symbol.h term.h time.h types.h \ machine/memory.h machine/loader.h machine/kernel.h \ - list.h handler.h command.h i18n.h env_private.h + list.h command.h i18n.h env_private.h symlist.c: $(addprefix include/grub/,$(kernel_img_HEADERS)) config.h gensymlist.sh /bin/sh gensymlist.sh $(filter %.h,$^) > $@ || (rm -f $@; exit 1) @@ -132,19 +131,6 @@ grub_script.tab.c grub_script.tab.h: script/parser.y $(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y DISTCLEANFILES += grub_script.tab.c grub_script.tab.h -# For grub-script-check. -grub_script_check_init.lst: geninit.sh $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) - rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ -DISTCLEANFILES += grub_script_check_init.lst - -grub_script_check_init.h: grub_script_check_init.lst $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) geninitheader.sh - rm -f $@; sh $(srcdir)/geninitheader.sh $< > $@ -DISTCLEANFILES += grub_script_check_init.h - -grub_script_check_init.c: grub_script_check_init.lst $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES)) geninit.sh - rm -f $@; sh $(srcdir)/geninit.sh $< $(filter %.c,$^) > $@ -DISTCLEANFILES += grub_script_check_init.c - # For grub-probe. grub_probe_init.lst: geninit.sh $(filter-out grub_probe_init.c,$(grub_probe_SOURCES)) rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@ @@ -455,12 +441,12 @@ scsi_mod_CFLAGS = $(COMMON_CFLAGS) scsi_mod_LDFLAGS = $(COMMON_LDFLAGS) # Commands. -pkglib_MODULES += minicmd.mod extcmd.mod hello.mod handler.mod \ +pkglib_MODULES += minicmd.mod extcmd.mod hello.mod \ ls.mod cmp.mod cat.mod help.mod search.mod loopback.mod \ configfile.mod echo.mod \ terminfo.mod test.mod blocklist.mod hexdump.mod \ read.mod sleep.mod loadenv.mod crc.mod parttool.mod \ - msdospart.mod memrw.mod normal.mod sh.mod \ + msdospart.mod memrw.mod normal.mod \ gptsync.mod true.mod probe.mod password.mod \ keystatus.mod @@ -521,11 +507,6 @@ msdospart_mod_SOURCES = parttool/msdospart.c msdospart_mod_CFLAGS = $(COMMON_CFLAGS) msdospart_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For handler.mod. -handler_mod_SOURCES = commands/handler.c -handler_mod_CFLAGS = $(COMMON_CFLAGS) -handler_mod_LDFLAGS = $(COMMON_LDFLAGS) - # For ls.mod. ls_mod_SOURCES = commands/ls.c ls_mod_CFLAGS = $(COMMON_CFLAGS) @@ -645,19 +626,15 @@ keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS) # For normal.mod. 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/color.c normal/completion.c normal/datetime.c normal/menu.c \ normal/menu_entry.c normal/menu_text.c \ - normal/misc.c normal/crypto.c normal/term.c normal/context.c + normal/misc.c normal/crypto.c normal/term.c normal/context.c \ + script/main.c script/script.c script/execute.c \ + script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c normal_mod_CFLAGS = $(COMMON_CFLAGS) normal_mod_LDFLAGS = $(COMMON_LDFLAGS) -# For sh.mod. -sh_mod_SOURCES = script/main.c script/script.c script/execute.c \ - script/function.c script/lexer.c grub_script.tab.c grub_script.yy.c -sh_mod_CFLAGS = $(COMMON_CFLAGS) -sh_mod_LDFLAGS = $(COMMON_LDFLAGS) - ifneq (, $(FONT_SOURCE)) font/font.c_DEPENDENCIES = ascii.h endif diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk index 3cef9313f..0979f03ee 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -16,7 +16,7 @@ kernel_img_SOURCES = kern/i386/coreboot/startup.S \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \ kern/i386/tsc.c kern/i386/pit.c \ kern/generic/rtc_get_time_ms.c \ diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk index d4a459b3e..f8921df9b 100644 --- a/conf/i386-ieee1275.rmk +++ b/conf/i386-ieee1275.rmk @@ -18,7 +18,7 @@ kernel_img_SOURCES = kern/i386/ieee1275/startup.S \ kern/rescue_parser.c kern/rescue_reader.c \ kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \ kern/env.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/generic/millisleep.c \ kern/ieee1275/ieee1275.c \ term/ieee1275/ofconsole.c \ diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index ece88446b..7b624837b 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -45,7 +45,7 @@ kernel_img_SOURCES = kern/i386/pc/startup.S \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/$(target_cpu)/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \ kern/parser.c kern/partition.c \ kern/i386/tsc.c kern/i386/pit.c \ @@ -76,7 +76,7 @@ util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h grub_setup_SOURCES = gnulib/progname.c \ util/i386/pc/grub-setup.c util/hostdisk.c \ util/misc.c util/getroot.c kern/device.c kern/disk.c \ - kern/err.c kern/misc.c kern/parser.c kern/partition.c \ + kern/err.c kern/misc.c kern/partition.c \ kern/file.c kern/fs.c kern/env.c kern/list.c \ fs/fshelp.c \ \ diff --git a/conf/i386-qemu.rmk b/conf/i386-qemu.rmk index 97273e1ce..cbe6d0455 100644 --- a/conf/i386-qemu.rmk +++ b/conf/i386-qemu.rmk @@ -29,7 +29,7 @@ kernel_img_SOURCES = kern/i386/qemu/startup.S \ kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/$(target_cpu)/dl.c kern/parser.c kern/partition.c \ kern/i386/tsc.c kern/i386/pit.c \ kern/generic/rtc_get_time_ms.c \ diff --git a/conf/mips-qemu-mips.rmk b/conf/mips-qemu-mips.rmk index e06370122..7cddf72ad 100644 --- a/conf/mips-qemu-mips.rmk +++ b/conf/mips-qemu-mips.rmk @@ -12,7 +12,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/list.c kern/command.c kern/corecmd.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \ symlist.c kern/$(target_cpu)/cache.S diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 35cd01b4b..bf39bf668 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -15,7 +15,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/list.c kern/command.c kern/corecmd.c \ kern/parser.c kern/partition.c kern/env.c kern/$(target_cpu)/dl.c \ kern/generic/millisleep.c kern/generic/rtc_get_time_ms.c kern/time.c \ kern/$(target_cpu)/cache.S \ diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk index 86f6ddcb3..7b32b24f1 100644 --- a/conf/powerpc-ieee1275.rmk +++ b/conf/powerpc-ieee1275.rmk @@ -13,7 +13,7 @@ kernel_img_SOURCES = kern/powerpc/ieee1275/startup.S kern/ieee1275/cmain.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/list.c kern/command.c kern/corecmd.c \ kern/ieee1275/init.c \ kern/ieee1275/mmap.c \ term/ieee1275/ofconsole.c \ diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk index 78e511e31..b4079dd1f 100644 --- a/conf/sparc64-ieee1275.rmk +++ b/conf/sparc64-ieee1275.rmk @@ -25,7 +25,7 @@ kernel_img_SOURCES = kern/sparc64/ieee1275/crt0.S kern/ieee1275/cmain.c \ kern/disk.c kern/dl.c kern/err.c kern/file.c kern/fs.c \ kern/misc.c kern/mm.c kern/term.c \ kern/rescue_parser.c kern/rescue_reader.c \ - kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/list.c kern/command.c kern/corecmd.c \ kern/sparc64/ieee1275/ieee1275.c \ kern/sparc64/ieee1275/init.c \ kern/ieee1275/mmap.c \ diff --git a/conf/x86-efi.rmk b/conf/x86-efi.rmk index 5cb472168..bab68f0f4 100644 --- a/conf/x86-efi.rmk +++ b/conf/x86-efi.rmk @@ -30,7 +30,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/efi/startup.S kern/main.c kern/device.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 \ term/efi/console.c disk/efi/efidisk.c \ - kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \ + kern/time.c kern/list.c kern/command.c kern/corecmd.c \ kern/i386/tsc.c kern/i386/pit.c \ kern/generic/rtc_get_time_ms.c \ kern/generic/millisleep.c diff --git a/include/grub/handler.h b/include/grub/handler.h deleted file mode 100644 index 77dd7d9c1..000000000 --- a/include/grub/handler.h +++ /dev/null @@ -1,60 +0,0 @@ -/* handler.h - header for grub handler */ -/* - * 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 . - */ - -#ifndef GRUB_HANDLER_HEADER -#define GRUB_HANDLER_HEADER 1 - -#include -#include - -struct grub_handler -{ - struct grub_handler *next; - const char *name; - grub_err_t (*init) (void); - grub_err_t (*fini) (void); -}; -typedef struct grub_handler *grub_handler_t; - -struct grub_handler_class -{ - struct grub_handler_class *next; - const char *name; - grub_handler_t handler_list; - grub_handler_t cur_handler; -}; -typedef struct grub_handler_class *grub_handler_class_t; - -extern grub_handler_class_t EXPORT_VAR(grub_handler_class_list); - -void EXPORT_FUNC(grub_handler_register) (grub_handler_class_t class, - grub_handler_t handler); -void EXPORT_FUNC(grub_handler_unregister) (grub_handler_class_t class, - grub_handler_t handler); -grub_err_t EXPORT_FUNC(grub_handler_set_current) (grub_handler_class_t class, - grub_handler_t handler); - -#define GRUB_AS_HANDLER(ptr) \ - ((GRUB_FIELD_MATCH (ptr, grub_handler_t, next) && \ - GRUB_FIELD_MATCH (ptr, grub_handler_t, name) && \ - GRUB_FIELD_MATCH (ptr, grub_handler_t, init) && \ - GRUB_FIELD_MATCH (ptr, grub_handler_t, fini)) ? \ - (grub_handler_t) ptr : grub_bad_type_cast ()) - -#endif /* ! GRUB_HANDLER_HEADER */ diff --git a/include/grub/parser.h b/include/grub/parser.h index 17f0c4303..064f73fcb 100644 --- a/include/grub/parser.h +++ b/include/grub/parser.h @@ -22,7 +22,6 @@ #include #include -#include #include /* All the states for the command line. */ @@ -84,36 +83,9 @@ struct grub_parser }; typedef struct grub_parser *grub_parser_t; -extern struct grub_handler_class EXPORT_VAR(grub_parser_class); grub_err_t EXPORT_FUNC(grub_parser_execute) (char *source); -static inline void -grub_parser_register (const char *name __attribute__ ((unused)), - /* `name' is ignored here, but used by genhandlerlist.sh. */ - grub_parser_t parser) -{ - grub_handler_register (&grub_parser_class, GRUB_AS_HANDLER (parser)); -} - -static inline void -grub_parser_unregister (grub_parser_t parser) -{ - grub_handler_unregister (&grub_parser_class, GRUB_AS_HANDLER (parser)); -} - -static inline grub_parser_t -grub_parser_get_current (void) -{ - return (grub_parser_t) grub_parser_class.cur_handler; -} - -static inline grub_err_t -grub_parser_set_current (grub_parser_t parser) -{ - return grub_handler_set_current (&grub_parser_class, - GRUB_AS_HANDLER (parser)); -} - -void grub_register_rescue_parser (void); +grub_err_t +grub_rescue_parse_line (char *line, grub_reader_getline_t getline); #endif /* ! GRUB_PARSER_HEADER */ diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 33c6d2b85..5e85d983e 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -324,4 +324,7 @@ int grub_script_function_call (grub_script_function_t func, char ** grub_script_execute_arglist_to_argv (struct grub_script_arglist *arglist, int *count); +grub_err_t +grub_normal_parse_line (char *line, grub_reader_getline_t getline); + #endif /* ! GRUB_NORMAL_PARSER_HEADER */ diff --git a/include/grub/term.h b/include/grub/term.h index 230436388..4a05909da 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -38,7 +38,7 @@ #include #include #include -#include +#include /* These are used to represent the various color states we use. */ typedef enum diff --git a/kern/handler.c b/kern/handler.c deleted file mode 100644 index 2bf85313c..000000000 --- a/kern/handler.c +++ /dev/null @@ -1,64 +0,0 @@ -/* handler.c - grub handler function */ -/* - * 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 . - */ - -#include - -grub_handler_class_t grub_handler_class_list; - -void -grub_handler_register (grub_handler_class_t class, grub_handler_t handler) -{ - int first_handler = (class->handler_list == 0); - - grub_list_push (GRUB_AS_LIST_P (&class->handler_list), - GRUB_AS_LIST (handler)); - - if (first_handler) - { - grub_list_push (GRUB_AS_LIST_P (&grub_handler_class_list), - GRUB_AS_LIST (class)); - grub_handler_set_current (class, handler); - } -} - -void -grub_handler_unregister (grub_handler_class_t class, grub_handler_t handler) -{ - grub_list_remove (GRUB_AS_LIST_P (&class->handler_list), - GRUB_AS_LIST (handler)); - - if (class->handler_list == 0) - grub_list_remove (GRUB_AS_LIST_P (&grub_handler_class_list), - GRUB_AS_LIST (class)); -} - -grub_err_t -grub_handler_set_current (grub_handler_class_t class, grub_handler_t handler) -{ - if (class->cur_handler && class->cur_handler->fini) - if ((class->cur_handler->fini) () != GRUB_ERR_NONE) - return grub_errno; - - if (handler->init) - if ((handler->init) () != GRUB_ERR_NONE) - return grub_errno; - - class->cur_handler = handler; - return GRUB_ERR_NONE; -} diff --git a/kern/main.c b/kern/main.c index 2f2c951ab..e644ea5b1 100644 --- a/kern/main.c +++ b/kern/main.c @@ -191,7 +191,6 @@ grub_main (void) grub_set_root_dev (); grub_register_core_commands (); - grub_register_rescue_parser (); grub_load_config (); grub_load_normal_mode (); diff --git a/kern/parser.c b/kern/parser.c index 80312b9b4..06e4ed673 100644 --- a/kern/parser.c +++ b/kern/parser.c @@ -230,10 +230,6 @@ grub_parser_split_cmdline (const char *cmdline, grub_reader_getline_t getline, return 0; } -struct grub_handler_class grub_parser_class = { - .name = "parser" -}; - grub_err_t grub_parser_execute (char *source) { @@ -262,11 +258,9 @@ grub_parser_execute (char *source) while (source) { char *line; - grub_parser_t parser; getline (&line, 0); - parser = grub_parser_get_current (); - parser->parse_line (line, getline); + grub_rescue_parse_line (line, getline); grub_free (line); } diff --git a/kern/rescue_parser.c b/kern/rescue_parser.c index d3725e739..9c85ba6bd 100644 --- a/kern/rescue_parser.c +++ b/kern/rescue_parser.c @@ -24,7 +24,7 @@ #include #include -static grub_err_t +grub_err_t grub_rescue_parse_line (char *line, grub_reader_getline_t getline) { char *name; @@ -74,15 +74,3 @@ grub_rescue_parse_line (char *line, grub_reader_getline_t getline) return grub_errno; } - -static struct grub_parser grub_rescue_parser = - { - .name = "rescue", - .parse_line = grub_rescue_parse_line - }; - -void -grub_register_rescue_parser (void) -{ - grub_parser_register ("rescue", &grub_rescue_parser); -} diff --git a/kern/rescue_reader.c b/kern/rescue_reader.c index f573cf41f..2f053aaea 100644 --- a/kern/rescue_reader.c +++ b/kern/rescue_reader.c @@ -86,7 +86,7 @@ grub_rescue_run (void) if (! line || line[0] == '\0') continue; - grub_parser_get_current ()->parse_line (line, grub_rescue_read_line); + grub_rescue_parse_line (line, grub_rescue_read_line); grub_free (line); } } diff --git a/normal/handler.c b/normal/handler.c deleted file mode 100644 index 4c8b8f769..000000000 --- a/normal/handler.c +++ /dev/null @@ -1,223 +0,0 @@ -/* handler.c - support handler loading */ -/* - * 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 . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct grub_handler_list -{ - struct grub_handler_list *next; - char *name; - grub_command_t cmd; -}; - -static struct grub_handler_list *handler_list; - -static grub_err_t -grub_handler_cmd (struct grub_command *cmd, - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) -{ - char *p; - grub_handler_class_t class; - grub_handler_t handler; - - p = grub_strchr (cmd->name, '.'); - if (! p) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid command name"); - - if (cmd->data) - { - if (! grub_dl_get (cmd->data)) - { - grub_dl_t mod; - - mod = grub_dl_load (cmd->data); - if (mod) - grub_dl_ref (mod); - else - return grub_errno; - } - grub_free (cmd->data); - cmd->data = 0; - } - - *p = 0; - class = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_handler_class_list), - cmd->name); - *p = '.'; - - if (! class) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found"); - - - handler = grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list), - p + 1); - if (! handler) - return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found"); - - grub_handler_set_current (class, handler); - - return 0; -} - -static void -insert_handler (char *name, char *module) -{ - struct grub_handler_list *item; - char *data; - - if (grub_command_find (name)) - return; - - item = grub_malloc (sizeof (*item)); - if (! item) - return; - - item->name = grub_strdup (name); - if (! item->name) - { - grub_free (item); - return; - } - - if (module) - { - data = grub_strdup (module); - if (! data) - { - grub_free (item->name); - grub_free (item); - return; - } - } - else - data = 0; - - item->cmd = grub_register_command (item->name, grub_handler_cmd, 0, - "Set active handler."); - if (! item->cmd) - { - grub_free (data); - grub_free (item->name); - grub_free (item); - return; - } - - item->cmd->data = data; - grub_list_push (GRUB_AS_LIST_P (&handler_list), GRUB_AS_LIST (item)); -} - -/* Read the file handler.lst for auto-loading. */ -void -read_handler_list (void) -{ - const char *prefix; - static int first_time = 1; - const char *class_name; - - /* Make sure that this function does not get executed twice. */ - if (! first_time) - return; - first_time = 0; - - prefix = grub_env_get ("prefix"); - if (prefix) - { - char *filename; - - filename = grub_xasprintf ("%s/handler.lst", prefix); - if (filename) - { - grub_file_t file; - - file = grub_file_open (filename); - if (file) - { - char *buf = NULL; - for (;; grub_free (buf)) - { - char *p; - - buf = grub_file_getline (file); - - if (! buf) - break; - - if (! grub_isgraph (buf[0])) - continue; - - p = grub_strchr (buf, ':'); - if (! p) - continue; - - *p = '\0'; - while (*++p == ' ') - ; - - insert_handler (buf, p); - } - grub_file_close (file); - } - grub_free (filename); - } - } - - grub_handler_class_t class; - FOR_LIST_ELEMENTS (class, grub_handler_class_list) - { - grub_handler_t handler; - class_name = class->name; - FOR_LIST_ELEMENTS(handler, class->handler_list) - { - char name[grub_strlen (class_name) + grub_strlen (handler->name) + 2]; - - grub_strcpy (name, class_name); - grub_strcat (name, "."); - grub_strcat (name, handler->name); - - insert_handler (name, 0); - } - } - - /* Ignore errors. */ - grub_errno = GRUB_ERR_NONE; -} - -void -free_handler_list (void) -{ - struct grub_handler_list *item; - - while (handler_list) - { - item = handler_list; - handler_list = handler_list->next; - grub_free (item->cmd->data); - grub_unregister_command (item->cmd); - grub_free (item->name); - grub_free (item); - } -} diff --git a/normal/main.c b/normal/main.c index 5a5467485..e16e8ef7d 100644 --- a/normal/main.c +++ b/normal/main.c @@ -31,6 +31,7 @@ #include #include #include +#include #define GRUB_DEFAULT_HISTORY_SIZE 50 @@ -308,7 +309,6 @@ static grub_menu_t read_config_file (const char *config) { grub_file_t file; - grub_parser_t old_parser = 0; auto grub_err_t getline (char **line, int cont); grub_err_t getline (char **line, int cont __attribute__ ((unused))) @@ -322,36 +322,7 @@ read_config_file (const char *config) return grub_errno; if (buf[0] == '#') - { - if (buf[1] == '!') - { - grub_parser_t parser; - grub_named_list_t list; - - buf += 2; - while (grub_isspace (*buf)) - buf++; - - if (! old_parser) - old_parser = grub_parser_get_current (); - - list = GRUB_AS_NAMED_LIST (grub_parser_class.handler_list); - parser = grub_named_list_find (list, buf); - if (parser) - grub_parser_set_current (parser); - else - { - char cmd_name[8 + grub_strlen (buf)]; - - /* Perhaps it's not loaded yet, try the autoload - command. */ - grub_strcpy (cmd_name, "parser."); - grub_strcat (cmd_name, buf); - grub_command_execute (cmd_name, 0, 0); - } - } - grub_free (*line); - } + grub_free (*line); else break; } @@ -387,15 +358,12 @@ read_config_file (const char *config) if ((getline (&line, 0)) || (! line)) break; - grub_parser_get_current ()->parse_line (line, getline); + grub_normal_parse_line (line, getline); grub_free (line); } grub_file_close (file); - if (old_parser) - grub_parser_set_current (old_parser); - return newmenu; } @@ -453,7 +421,6 @@ grub_normal_execute (const char *config, int nested, int batch) grub_menu_t menu = 0; read_lists (NULL, NULL); - read_handler_list (); grub_register_variable_hook ("prefix", NULL, read_lists); grub_command_execute ("parser.grub", 0, 0); @@ -559,17 +526,15 @@ grub_normal_reader_init (int nested) 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; + const char *prompt; if (cont) - prompt = grub_xasprintf (">"); + prompt = ">"; else - prompt = grub_xasprintf ("%s>", parser->name); + prompt = "grub>"; if (!prompt) return grub_errno; @@ -583,14 +548,11 @@ grub_normal_read_line_real (char **line, int cont, int nested) if (cont || nested) { grub_free (*line); - grub_free (prompt); *line = 0; return grub_errno; } } - grub_free (prompt); - return 0; } @@ -631,7 +593,7 @@ grub_cmdline_run (int nested) if (! line) break; - grub_parser_get_current ()->parse_line (line, grub_normal_read_line); + grub_normal_parse_line (line, grub_normal_read_line); grub_free (line); } } @@ -679,5 +641,4 @@ GRUB_MOD_FINI(normal) grub_set_history (0); grub_register_variable_hook ("pager", 0, 0); grub_fs_autoload_hook = 0; - free_handler_list (); } diff --git a/normal/menu_entry.c b/normal/menu_entry.c index 644fe90fd..c23d67d70 100644 --- a/normal/menu_entry.c +++ b/normal/menu_entry.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -1189,7 +1190,7 @@ run (struct screen *screen) while (currline < screen->num_lines) { editor_getline (&nextline, 0); - if (grub_parser_get_current ()->parse_line (nextline, editor_getline)) + if (grub_normal_parse_line (nextline, editor_getline)) break; } diff --git a/script/main.c b/script/main.c index b5159dc7d..752a8cd8a 100644 --- a/script/main.c +++ b/script/main.c @@ -20,7 +20,7 @@ #include #include -static grub_err_t +grub_err_t grub_normal_parse_line (char *line, grub_reader_getline_t getline) { struct grub_script *parsed_script; @@ -39,19 +39,3 @@ grub_normal_parse_line (char *line, grub_reader_getline_t getline) return grub_errno; } - -static struct grub_parser grub_sh_parser = - { - .name = "grub", - .parse_line = grub_normal_parse_line - }; - -GRUB_MOD_INIT(sh) -{ - grub_parser_register ("grub", &grub_sh_parser); -} - -GRUB_MOD_FINI(sh) -{ - grub_parser_unregister (&grub_sh_parser); -} diff --git a/util/grub-fstest.c b/util/grub-fstest.c index c03c43451..f7e1eb2dd 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -55,9 +55,6 @@ grub_getkey (void) return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; - void grub_refresh (void) { diff --git a/util/grub-probe.c b/util/grub-probe.c index 948f10dcf..37b92454a 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -70,9 +70,6 @@ grub_getkey (void) return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; - void grub_refresh (void) { diff --git a/util/grub-script-check.c b/util/grub-script-check.c index 7dc400dde..722736c81 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -26,8 +26,6 @@ #include #include -#include - #define _GNU_SOURCE 1 #include @@ -232,9 +230,6 @@ main (int argc, char *argv[]) } } - /* Initialize all modules. */ - grub_init_all (); - do { input = 0; @@ -252,8 +247,6 @@ main (int argc, char *argv[]) grub_free (input); } while (script != 0); - /* Free resources. */ - grub_fini_all (); if (file) fclose (file); return (script == 0); diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 63fa8c328..989b06360 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -69,9 +69,6 @@ grub_getkey (void) return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; - void grub_refresh (void) { From c96db58ec599d1bcfb12bf345fb4988e1ef1a741 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:27:42 +0100 Subject: [PATCH 14/96] Remove grub_fs_iterate --- include/grub/fs.h | 26 ++++++++++++++++++++------ kern/fs.c | 32 +------------------------------- 2 files changed, 21 insertions(+), 37 deletions(-) diff --git a/include/grub/fs.h b/include/grub/fs.h index 45f515768..3368eb553 100644 --- a/include/grub/fs.h +++ b/include/grub/fs.h @@ -24,6 +24,8 @@ #include #include +#include + /* Forward declaration is required, because of mutual reference. */ struct grub_file; @@ -38,6 +40,9 @@ struct grub_dirhook_info /* Filesystem descriptor. */ struct grub_fs { + /* The next filesystem. */ + struct grub_fs *next; + /* My name. */ const char *name; @@ -72,9 +77,6 @@ struct grub_fs /* Whether this filesystem reserves first sector for DOS-style boot. */ int reserved_first_sector; #endif - - /* The next filesystem. */ - struct grub_fs *next; }; typedef struct grub_fs *grub_fs_t; @@ -87,10 +89,22 @@ extern struct grub_fs grub_fs_blocklist; the linked list GRUB_FS_LIST through the function grub_fs_register. */ typedef int (*grub_fs_autoload_hook_t) (void); extern grub_fs_autoload_hook_t EXPORT_VAR(grub_fs_autoload_hook); +extern grub_fs_t EXPORT_VAR (grub_fs_list); + +static inline void +grub_fs_register (grub_fs_t fs) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_fs_list), GRUB_AS_LIST (fs)); +} + +static inline void +grub_fs_unregister (grub_fs_t fs) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_fs_list), GRUB_AS_LIST (fs)); +} + +#define FOR_FILESYSTEMS(var) FOR_LIST_ELEMENTS((var), (grub_fs_list)) -void EXPORT_FUNC(grub_fs_register) (grub_fs_t fs); -void EXPORT_FUNC(grub_fs_unregister) (grub_fs_t fs); -void EXPORT_FUNC(grub_fs_iterate) (int (*hook) (const grub_fs_t fs)); grub_fs_t EXPORT_FUNC(grub_fs_probe) (grub_device_t device); #endif /* ! GRUB_FS_HEADER */ diff --git a/kern/fs.c b/kern/fs.c index 0c456377f..cf800f4cc 100644 --- a/kern/fs.c +++ b/kern/fs.c @@ -27,40 +27,10 @@ #include #include -static grub_fs_t grub_fs_list; +grub_fs_t grub_fs_list = 0; grub_fs_autoload_hook_t grub_fs_autoload_hook = 0; -void -grub_fs_register (grub_fs_t fs) -{ - fs->next = grub_fs_list; - grub_fs_list = fs; -} - -void -grub_fs_unregister (grub_fs_t fs) -{ - grub_fs_t *p, q; - - for (p = &grub_fs_list, q = *p; q; p = &(q->next), q = q->next) - if (q == fs) - { - *p = q->next; - break; - } -} - -void -grub_fs_iterate (int (*hook) (const grub_fs_t fs)) -{ - grub_fs_t p; - - for (p = grub_fs_list; p; p = p->next) - if (hook (p)) - break; -} - grub_fs_t grub_fs_probe (grub_device_t device) { From 9eade9dbd7602d4b9dbae8a09dc89a1631ab314e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:36:28 +0100 Subject: [PATCH 15/96] Remove grub_video_iterate --- include/grub/video.h | 29 +++++++++++++++++++++++------ video/video.c | 35 +---------------------------------- 2 files changed, 24 insertions(+), 40 deletions(-) diff --git a/include/grub/video.h b/include/grub/video.h index 57f2b37f2..3e8ea0e96 100644 --- a/include/grub/video.h +++ b/include/grub/video.h @@ -21,6 +21,7 @@ #include #include +#include /* Video color in hardware dependent format. Users should not assume any specific coding format. */ @@ -185,6 +186,9 @@ typedef enum grub_video_driver_id struct grub_video_adapter { + /* The next video adapter. */ + struct grub_video_adapter *next; + /* The video adapter name. */ const char *name; grub_video_driver_id_t id; @@ -253,15 +257,28 @@ struct grub_video_adapter grub_err_t (*set_active_render_target) (struct grub_video_render_target *target); grub_err_t (*get_active_render_target) (struct grub_video_render_target **target); - - /* The next video adapter. */ - struct grub_video_adapter *next; }; typedef struct grub_video_adapter *grub_video_adapter_t; -void EXPORT_FUNC (grub_video_register) (grub_video_adapter_t adapter); -void grub_video_unregister (grub_video_adapter_t adapter); -void grub_video_iterate (int (*hook) (grub_video_adapter_t adapter)); +extern grub_video_adapter_t EXPORT_VAR(grub_video_adapter_list); + +/* Register video driver. */ +static inline void +grub_video_register (grub_video_adapter_t adapter) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_video_adapter_list), + GRUB_AS_LIST (adapter)); +} + +/* Unregister video driver. */ +static inline void +grub_video_unregister (grub_video_adapter_t adapter) +{ + grub_list_remove (GRUB_AS_LIST_P (&grub_video_adapter_list), + GRUB_AS_LIST (adapter)); +} + +#define FOR_VIDEO_ADAPTERS(var) FOR_LIST_ELEMENTS((var), (grub_video_adapter_list)) grub_err_t EXPORT_FUNC (grub_video_restore) (void); diff --git a/video/video.c b/video/video.c index 42418f980..7a1a446e4 100644 --- a/video/video.c +++ b/video/video.c @@ -23,44 +23,11 @@ #include /* The list of video adapters registered to system. */ -static grub_video_adapter_t grub_video_adapter_list; +grub_video_adapter_t grub_video_adapter_list = NULL; /* Active video adapter. */ static grub_video_adapter_t grub_video_adapter_active; -/* Register video driver. */ -void -grub_video_register (grub_video_adapter_t adapter) -{ - adapter->next = grub_video_adapter_list; - grub_video_adapter_list = adapter; -} - -/* Unregister video driver. */ -void -grub_video_unregister (grub_video_adapter_t adapter) -{ - grub_video_adapter_t *p, q; - - for (p = &grub_video_adapter_list, q = *p; q; p = &(q->next), q = q->next) - if (q == adapter) - { - *p = q->next; - break; - } -} - -/* Iterate thru all registered video drivers. */ -void -grub_video_iterate (int (*hook) (grub_video_adapter_t adapter)) -{ - grub_video_adapter_t p; - - for (p = grub_video_adapter_list; p; p = p->next) - if (hook (p)) - break; -} - /* Restore back to initial mode (where applicable). */ grub_err_t grub_video_restore (void) From fcaae9ec1242c54e0bd763d80f8427e70e9f7fde Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:52:40 +0100 Subject: [PATCH 16/96] Remove grub_dl_iterate --- commands/minicmd.c | 34 ++++++++++++++------------------ include/grub/dl.h | 6 +++++- kern/dl.c | 49 ++++++++++++---------------------------------- 3 files changed, 32 insertions(+), 57 deletions(-) diff --git a/commands/minicmd.c b/commands/minicmd.c index 4ea9efead..92d262caf 100644 --- a/commands/minicmd.c +++ b/commands/minicmd.c @@ -301,27 +301,23 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused))) { - auto int print_module (grub_dl_t mod); - - int print_module (grub_dl_t mod) - { - grub_dl_dep_t dep; - - grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count); - for (dep = mod->dep; dep; dep = dep->next) - { - if (dep != mod->dep) - grub_putchar (','); - - grub_printf ("%s", dep->mod->name); - } - grub_putchar ('\n'); - - return 0; - } + grub_dl_t mod; grub_printf ("Name\tRef Count\tDependencies\n"); - grub_dl_iterate (print_module); + FOR_DL_MODULES (mod) + { + grub_dl_dep_t dep; + + grub_printf ("%s\t%d\t\t", mod->name, mod->ref_count); + for (dep = mod->dep; dep; dep = dep->next) + { + if (dep != mod->dep) + grub_putchar (','); + + grub_printf ("%s", dep->mod->name); + } + grub_putchar ('\n'); + } return 0; } diff --git a/include/grub/dl.h b/include/grub/dl.h index 17e03f400..c44e85aef 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -82,6 +82,7 @@ struct grub_dl Elf_Sym *symtab; void (*init) (struct grub_dl *mod); void (*fini) (void); + struct grub_dl *next; }; typedef struct grub_dl *grub_dl_t; @@ -113,7 +114,10 @@ grub_dl_unref (grub_dl_t mod) int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); #endif -void EXPORT_FUNC(grub_dl_iterate) (int (*hook) (grub_dl_t mod)); +extern grub_dl_t EXPORT_VAR(grub_dl_head); + +#define FOR_DL_MODULES(var) FOR_LIST_ELEMENTS ((var), (grub_dl_head)) + grub_dl_t EXPORT_FUNC(grub_dl_get) (const char *name); grub_err_t grub_dl_register_symbol (const char *name, void *addr, grub_dl_t mod); diff --git a/kern/dl.c b/kern/dl.c index 19ee13243..cf59cec30 100644 --- a/kern/dl.c +++ b/kern/dl.c @@ -39,31 +39,17 @@ -struct grub_dl_list -{ - struct grub_dl_list *next; - grub_dl_t mod; -}; -typedef struct grub_dl_list *grub_dl_list_t; - -static grub_dl_list_t grub_dl_head; +grub_dl_t grub_dl_head = 0; static grub_err_t grub_dl_add (grub_dl_t mod) { - grub_dl_list_t l; - if (grub_dl_get (mod->name)) return grub_error (GRUB_ERR_BAD_MODULE, "`%s' is already loaded", mod->name); - l = (grub_dl_list_t) grub_malloc (sizeof (*l)); - if (! l) - return grub_errno; - - l->mod = mod; - l->next = grub_dl_head; - grub_dl_head = l; + mod->next = grub_dl_head; + grub_dl_head = mod; return GRUB_ERR_NONE; } @@ -71,13 +57,12 @@ grub_dl_add (grub_dl_t mod) static void grub_dl_remove (grub_dl_t mod) { - grub_dl_list_t *p, q; + grub_dl_t *p, q; for (p = &grub_dl_head, q = *p; q; p = &q->next, q = *p) - if (q->mod == mod) + if (q == mod) { *p = q->next; - grub_free (q); return; } } @@ -85,25 +70,15 @@ grub_dl_remove (grub_dl_t mod) grub_dl_t grub_dl_get (const char *name) { - grub_dl_list_t l; + grub_dl_t l; for (l = grub_dl_head; l; l = l->next) - if (grub_strcmp (name, l->mod->name) == 0) - return l->mod; + if (grub_strcmp (name, l->name) == 0) + return l; return 0; } -void -grub_dl_iterate (int (*hook) (grub_dl_t mod)) -{ - grub_dl_list_t l; - - for (l = grub_dl_head; l; l = l->next) - if (hook (l->mod)) - break; -} - struct grub_symbol @@ -690,11 +665,11 @@ grub_dl_unload_unneeded (void) { /* Because grub_dl_remove modifies the list of modules, this implementation is tricky. */ - grub_dl_list_t p = grub_dl_head; + grub_dl_t p = grub_dl_head; while (p) { - if (grub_dl_unload (p->mod)) + if (grub_dl_unload (p)) { p = grub_dl_head; continue; @@ -710,13 +685,13 @@ grub_dl_unload_all (void) { while (grub_dl_head) { - grub_dl_list_t p; + grub_dl_t p; grub_dl_unload_unneeded (); /* Force to decrement the ref count. This will purge pre-loaded modules and manually inserted modules. */ for (p = grub_dl_head; p; p = p->next) - p->mod->ref_count--; + p->ref_count--; } } From 9cc7b8751eb717834864fc587412a4dbafa7066d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sat, 27 Mar 2010 00:58:35 +0100 Subject: [PATCH 17/96] Remove grub_script_function_iterate --- include/grub/script_sh.h | 6 +++++- script/function.c | 14 +------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index 5e85d983e..020cbb2f7 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -313,11 +313,15 @@ struct grub_script_function }; typedef struct grub_script_function *grub_script_function_t; +extern grub_script_function_t grub_script_function_list; + +#define FOR_SCRIPT_FUNCTIONS(var) for((var) = grub_script_function_list; \ + (var); (var) = (var)->next) + grub_script_function_t grub_script_function_create (struct grub_script_arg *functionname, struct grub_script *cmd); void grub_script_function_remove (const char *name); grub_script_function_t grub_script_function_find (char *functionname); -int grub_script_function_iterate (int (*iterate) (grub_script_function_t)); int grub_script_function_call (grub_script_function_t func, int argc, char **args); diff --git a/script/function.c b/script/function.c index ded470c4e..810c65233 100644 --- a/script/function.c +++ b/script/function.c @@ -21,7 +21,7 @@ #include #include -static grub_script_function_t grub_script_function_list; +grub_script_function_t grub_script_function_list; grub_script_function_t grub_script_function_create (struct grub_script_arg *functionname_arg, @@ -104,18 +104,6 @@ grub_script_function_find (char *functionname) return func; } -int -grub_script_function_iterate (int (*iterate) (grub_script_function_t)) -{ - grub_script_function_t func; - - for (func = grub_script_function_list; func; func = func->next) - if (iterate (func)) - return 1; - - return 0; -} - int grub_script_function_call (grub_script_function_t func, int argc __attribute__((unused)), From d499b1337144d3811410159d466c78ce9bd02657 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 15 Apr 2010 02:13:28 +0200 Subject: [PATCH 18/96] Remove grub/handler.h inclusion. Reported by: Giovanni Toraldo --- util/grub-editenv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/util/grub-editenv.c b/util/grub-editenv.c index f21042c97..4ea97bded 100644 --- a/util/grub-editenv.c +++ b/util/grub-editenv.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include From 4db50964ad0e96ce4bae73d589160a4b9bd0bd44 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 18 May 2010 13:01:59 +0100 Subject: [PATCH 19/96] Add btrfs probing support, currently only in the single-device case. * kern/emu/getroot.c (find_root_device_from_mountinfo): New function. (grub_guess_root_device): Call find_root_device_from_mountinfo before looking in /dev. --- ChangeLog.btrfs-probe | 8 +++++ kern/emu/getroot.c | 84 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 ChangeLog.btrfs-probe diff --git a/ChangeLog.btrfs-probe b/ChangeLog.btrfs-probe new file mode 100644 index 000000000..77c9995c8 --- /dev/null +++ b/ChangeLog.btrfs-probe @@ -0,0 +1,8 @@ +2010-05-18 Colin Watson + + Add btrfs probing support, currently only in the single-device case. + + * kern/emu/getroot.c (find_root_device_from_mountinfo): New + function. + (grub_guess_root_device): Call find_root_device_from_mountinfo + before looking in /dev. diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 6875044da..da62089fa 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -80,6 +80,84 @@ xgetcwd (void) return path; } +#ifdef __linux__ + +/* Statting something on a btrfs filesystem always returns a virtual device + major/minor pair rather than the real underlying device, because btrfs + can span multiple underlying devices (and even if it's currently only + using a single device it can be dynamically extended onto another). We + can't deal with the multiple-device case yet, but in the meantime, we can + at least cope with the single-device case by scanning + /proc/self/mountinfo. */ +static char * +find_root_device_from_mountinfo (const char *dir) +{ + FILE *fp; + char buf[1024]; /* XXX */ + char *ret = NULL; + + fp = fopen ("/proc/self/mountinfo", "r"); + if (! fp) + return NULL; /* fall through to other methods */ + + while (fgets (buf, sizeof (buf), fp)) + { + int mnt_id, parent_mnt_id; + unsigned int major, minor; + char enc_root[PATH_MAX], enc_path[PATH_MAX]; + int count; + size_t enc_path_len; + const char *sep; + char fstype[PATH_MAX], device[PATH_MAX]; + struct stat st; + + if (sscanf (buf, "%d %d %u:%u %s %s%n", + &mnt_id, &parent_mnt_id, &major, &minor, enc_root, enc_path, + &count) < 6) + continue; + + if (strcmp (enc_root, "/") != 0) + continue; /* only a subtree is mounted */ + + enc_path_len = strlen (enc_path); + if (strncmp (dir, enc_path, enc_path_len) != 0 || + (dir[enc_path_len] && dir[enc_path_len] != '/')) + continue; + + /* This is a parent of the requested directory. /proc/self/mountinfo + is in mount order, so it must be the closest parent we've + encountered so far. If it's virtual, return its device node; + otherwise, carry on to try to find something closer. */ + + free (ret); + ret = NULL; + + if (major != 0) + continue; /* not a virtual device */ + + sep = strstr (buf + count, " - "); + if (!sep) + continue; + + sep += strlen (" - "); + if (sscanf (sep, "%s %s", fstype, device) != 2) + continue; + + if (stat (device, &st) < 0) + continue; + + if (!S_ISBLK (st.st_mode)) + continue; /* not a block device */ + + ret = strdup (device); + } + + fclose (fp); + return ret; +} + +#endif /* __linux__ */ + #ifdef __MINGW32__ static char * @@ -355,6 +433,12 @@ grub_guess_root_device (const char *dir) #else /* !__GNU__ */ struct stat st; +#ifdef __linux__ + os_dev = find_root_device_from_mountinfo (dir); + if (os_dev) + return os_dev; +#endif /* __linux__ */ + if (stat (dir, &st) < 0) grub_util_error ("cannot stat `%s'", dir); From fa9d256ee45ed71ab9fc02809a0927d740adca86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Thu, 20 May 2010 02:05:43 +0200 Subject: [PATCH 20/96] Fix merge error in NetBSD code. --- ChangeLog | 6 ++++++ kern/emu/hostdisk.c | 7 ++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53a664d2f..1348c91c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-20 Grégoire Sutre + + * kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev) [__NetBSD__]: + Fix merge error in NetBSD code. + (find_partition_start) [__NetBSD__]: Likewise. + 2010-05-19 BVK Chaitanya Fix grub-mkrescue usage unit testing. diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index 0ab25ec7d..9c4697552 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -412,7 +412,8 @@ devmapper_fail: fd = open (dev, O_RDONLY); if (fd == -1) { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", dev); + grub_error (GRUB_ERR_BAD_DEVICE, + "cannot open `%s' while attempting to get disk geometry", dev); return 0; } @@ -434,9 +435,6 @@ devmapper_fail: # if !defined(__NetBSD__) return hdg.start; # else /* defined(__NetBSD__) */ - /* Since dev and convert_system_partition_to_system_disk (dev) are - * different, we know that dev is of the form /dev/r[wsc]d[0-9]+[a-z] - * and in particular it cannot be a floppy device. */ index = dev[strlen(dev) - 1] - 'a'; if (index >= label.d_npartitions) @@ -1433,7 +1431,6 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) /* Since os_dev and convert_system_partition_to_system_disk (os_dev) are * different, we know that os_dev is of the form /dev/r[wsc]d[0-9]+[a-z] * and in particular it cannot be a floppy device. */ - index = os_dev[strlen(os_dev) - 1] - 'a'; # endif /* !defined(__NetBSD__) */ start = find_partition_start (os_dev); From 96779aec8ee4e7edfcb1a09a279db528f6ae8f5e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 20 May 2010 23:16:10 +0100 Subject: [PATCH 21/96] * util/misc.c: Move inclusion of to ... * kern/emu/misc.c: ... here. Needed for canonicalize_file_name. --- ChangeLog | 5 +++++ kern/emu/misc.c | 3 +++ util/misc.c | 3 --- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1348c91c6..42b04d1c9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-20 Colin Watson + + * util/misc.c: Move inclusion of to ... + * kern/emu/misc.c: ... here. Needed for canonicalize_file_name. + 2010-05-20 Grégoire Sutre * kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev) [__NetBSD__]: diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 54c808a47..a3ccb3076 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -9,6 +9,9 @@ #include #include #include +#ifdef HAVE_LIMITS_H +#include +#endif #include #include diff --git a/util/misc.c b/util/misc.c index 46e5c6093..91bc25a55 100644 --- a/util/misc.c +++ b/util/misc.c @@ -30,9 +30,6 @@ #include #include #include -#ifdef HAVE_LIMITS_H -#include -#endif #include #include From c0f48e654daf3cc9451c267450ab4b617277baf0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 20 May 2010 23:27:15 +0100 Subject: [PATCH 22/96] * util/grub-mkrelpath.c (usage): Remove excess apostrophe. --- ChangeLog | 4 ++++ util/grub-mkrelpath.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 42b04d1c9..cdff463e4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-20 Colin Watson + + * util/grub-mkrelpath.c (usage): Remove excess apostrophe. + 2010-05-20 Colin Watson * util/misc.c: Move inclusion of to ... diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c index e771bd873..eccb49cdc 100644 --- a/util/grub-mkrelpath.c +++ b/util/grub-mkrelpath.c @@ -41,7 +41,7 @@ usage (int status) printf ("\ Usage: %s [OPTIONS] PATH\n\ \n\ -Make a system path relative to it's root.\n\ +Make a system path relative to its root.\n\ \n\ Options:\n\ -h, --help display this message and exit\n\ From 21717c8fcaa20b66568b90a296c86b99626b034b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 21 May 2010 14:17:15 +0100 Subject: [PATCH 23/96] * util/grub-mkconfig.in: Fix handling of -o so that it works when not the first option. --- ChangeLog | 5 +++++ util/grub-mkconfig.in | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index cdff463e4..02503a90f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-21 Colin Watson + + * util/grub-mkconfig.in: Fix handling of -o so that it works when + not the first option. + 2010-05-20 Colin Watson * util/grub-mkrelpath.c (usage): Remove excess apostrophe. diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 85212f8fc..d1abfa36a 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -50,7 +50,13 @@ EOF } # Check the arguments. +next_grub_cfg=false for option in "$@"; do + if $next_grub_cfg; then + grub_cfg=$option + next_grub_cfg=false + continue + fi case "$option" in -h | --help) usage @@ -59,8 +65,7 @@ for option in "$@"; do echo "$0 (GNU GRUB ${package_version})" exit 0 ;; -o) - shift - grub_cfg=$1 + next_grub_cfg=: ;; --output=*) grub_cfg=`echo "$option" | sed 's/--output=//'` @@ -72,6 +77,11 @@ for option in "$@"; do ;; esac done +if $next_grub_cfg; then + echo "Missing argument to \`-o'" 1>&2 + usage + exit 1 +fi . ${libdir}/grub/grub-mkconfig_lib From 228cfa97caf0a0c907c945bc307f07029439d629 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 21 May 2010 20:08:48 +0200 Subject: [PATCH 24/96] * kern/i386/pc/init.c (make_install_device): Fix a leftover usage of old partition naming style. --- ChangeLog | 5 +++++ kern/i386/pc/init.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 02503a90f..090cd645d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-21 Vladimir Serbinenko + + * kern/i386/pc/init.c (make_install_device): Fix a leftover usage of old + partition naming style. + 2010-05-21 Colin Watson * util/grub-mkconfig.in: Fix handling of -o so that it works when diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c index fa646df19..d81b1e117 100644 --- a/kern/i386/pc/init.c +++ b/kern/i386/pc/init.c @@ -75,8 +75,8 @@ make_install_device (void) ptr += grub_strlen (ptr); if (grub_install_bsd_part >= 0) - grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%c", - grub_install_bsd_part + 'a'); + grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%u", + grub_install_bsd_part + 1); ptr += grub_strlen (ptr); } From 39fbb79aa15e66e4516588bb2f74c1052218d8e6 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 21 May 2010 20:12:41 +0200 Subject: [PATCH 25/96] * include/grub/i18n.h: Always enable grub_gettext. --- ChangeLog | 4 ++++ include/grub/i18n.h | 14 +++----------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 090cd645d..081ea4a1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-21 Vladimir Serbinenko + + * include/grub/i18n.h: Always enable grub_gettext. + 2010-05-21 Vladimir Serbinenko * kern/i386/pc/init.c (make_install_device): Fix a leftover usage of old diff --git a/include/grub/i18n.h b/include/grub/i18n.h index 57ca1c45b..a91d73346 100644 --- a/include/grub/i18n.h +++ b/include/grub/i18n.h @@ -22,10 +22,10 @@ #include #include -extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); - /* NLS can be disabled through the configure --disable-nls option. */ -#if (defined(ENABLE_NLS) && ENABLE_NLS) +#if (defined(ENABLE_NLS) && ENABLE_NLS) || !defined (GRUB_UTIL) + +extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); # ifdef GRUB_UTIL @@ -41,19 +41,11 @@ extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s); for invalid uses of the value returned from these functions. On pre-ANSI systems without 'const', the config.h file is supposed to contain "#define const". */ -# ifdef GRUB_UTIL static inline const char * __attribute__ ((always_inline)) gettext (const char *str) { return str; } -# else -static inline const char * __attribute__ ((always_inline)) -grub_gettext (const char *str) -{ - return str; -} -# endif /* GRUB_UTIL */ #endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ From 9a25f885d3f9aaa8b4725e5fb3fbc4d410b0c39f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 21 May 2010 20:22:29 +0200 Subject: [PATCH 26/96] * kern/i386/pc/mmap.c (grub_machine_mmap_iterate): Zero-fill entry before calling BIOS. --- ChangeLog | 5 +++++ kern/i386/pc/mmap.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/ChangeLog b/ChangeLog index 081ea4a1d..02d16e835 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-21 Vladimir Serbinenko + + * kern/i386/pc/mmap.c (grub_machine_mmap_iterate): Zero-fill entry + before calling BIOS. + 2010-05-21 Vladimir Serbinenko * include/grub/i18n.h: Always enable grub_gettext. diff --git a/kern/i386/pc/mmap.c b/kern/i386/pc/mmap.c index 52d8fd597..72a6b3539 100644 --- a/kern/i386/pc/mmap.c +++ b/kern/i386/pc/mmap.c @@ -20,6 +20,7 @@ #include #include #include +#include grub_err_t grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) @@ -28,6 +29,8 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin struct grub_machine_mmap_entry *entry = (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + grub_memset (entry, 0, sizeof (entry)); + /* Check if grub_get_mmap_entry works. */ cont = grub_get_mmap_entry (entry, 0); @@ -43,6 +46,8 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin if (! cont) break; + grub_memset (entry, 0, sizeof (entry)); + cont = grub_get_mmap_entry (entry, cont); } while (entry->size); From 5f2316c1fe5ad62c3ae5815c256313041e6a559d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 13:42:16 +0200 Subject: [PATCH 27/96] * gfxmenu/gfxmenu.c (grub_gfxmenu_try): Change viewport on both buffers. * term/gfxterm.c (real_scroll): Likewise. --- ChangeLog | 5 +++++ gfxmenu/gfxmenu.c | 7 +++++++ term/gfxterm.c | 22 +++++++++++++--------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 02d16e835..cdeee7c2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-23 Vladimir Serbinenko + + * gfxmenu/gfxmenu.c (grub_gfxmenu_try): Change viewport on both buffers. + * term/gfxterm.c (real_scroll): Likewise. + 2010-05-21 Vladimir Serbinenko * kern/i386/pc/mmap.c (grub_machine_mmap_iterate): Zero-fill entry diff --git a/gfxmenu/gfxmenu.c b/gfxmenu/gfxmenu.c index a2e765156..1acab9ca7 100644 --- a/gfxmenu/gfxmenu.c +++ b/gfxmenu/gfxmenu.c @@ -110,6 +110,13 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested) view->nested = nested; view->first_timeout = -1; + grub_video_set_viewport (0, 0, mode_info.width, mode_info.height); + if (view->double_repaint) + { + grub_video_swap_buffers (); + grub_video_set_viewport (0, 0, mode_info.width, mode_info.height); + } + grub_gfxmenu_view_draw (view); instance->data = view; diff --git a/term/gfxterm.c b/term/gfxterm.c index ecfe4ff3b..c57d0f0fa 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -707,12 +707,6 @@ real_scroll (void) draw_cursor (0); grub_video_set_active_render_target (render_target); - /* Save viewport and set it to our window. */ - grub_video_get_viewport ((unsigned *) &saved_view.x, - (unsigned *) &saved_view.y, - (unsigned *) &saved_view.width, - (unsigned *) &saved_view.height); - grub_video_set_viewport (window.x, window.y, window.width, window.height); i = window.double_repaint ? 2 : 1; @@ -720,6 +714,15 @@ real_scroll (void) while (i--) { + /* Save viewport and set it to our window. */ + grub_video_get_viewport ((unsigned *) &saved_view.x, + (unsigned *) &saved_view.y, + (unsigned *) &saved_view.width, + (unsigned *) &saved_view.height); + + grub_video_set_viewport (window.x, window.y, window.width, + window.height); + /* Clear new border area. */ grub_video_fill_rect (color, virtual_screen.offset_x, @@ -735,6 +738,10 @@ real_scroll (void) grub_video_scroll (color, 0, -virtual_screen.normal_char_height * virtual_screen.total_scroll); + /* Restore saved viewport. */ + grub_video_set_viewport (saved_view.x, saved_view.y, + saved_view.width, saved_view.height); + if (i) grub_video_swap_buffers (); } @@ -746,9 +753,6 @@ real_scroll (void) grub_video_scroll (color, 0, -virtual_screen.normal_char_height * virtual_screen.total_scroll); - /* Restore saved viewport. */ - grub_video_set_viewport (saved_view.x, saved_view.y, - saved_view.width, saved_view.height); grub_video_set_active_render_target (render_target); } From 3ecb080a33a3cb3e15ca7721c00eeb96d9e8ed3e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 13:43:38 +0200 Subject: [PATCH 28/96] * gfxmenu/view.c (grub_gfxmenu_draw_terminal_box): Apply only to current buffer since gfxterm handles double repaint. --- ChangeLog | 5 +++++ gfxmenu/view.c | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index cdeee7c2b..dbf6f23eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-23 Vladimir Serbinenko + + * gfxmenu/view.c (grub_gfxmenu_draw_terminal_box): Apply only to current + buffer since gfxterm handles double repaint. + 2010-05-23 Vladimir Serbinenko * gfxmenu/gfxmenu.c (grub_gfxmenu_try): Change viewport on both buffers. diff --git a/gfxmenu/view.c b/gfxmenu/view.c index 9a5671cdd..518c3ba53 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -357,11 +357,6 @@ grub_gfxmenu_draw_terminal_box (void) term_box->draw (term_box, term_rect.x - term_box->get_left_pad (term_box), term_rect.y - term_box->get_top_pad (term_box)); - grub_video_swap_buffers (); - if (term_view->double_repaint) - term_box->draw (term_box, - term_rect.x - term_box->get_left_pad (term_box), - term_rect.y - term_box->get_top_pad (term_box)); } static void From ad603f61a5f61677406aad7b7c041ef21de8957f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 13:59:50 +0200 Subject: [PATCH 29/96] * gfxmenu/gui_list.c (draw_menu): Don't add scrollbar width to padding. Removed drawing_scrollbar argument. All users updated Fixes #29792. Reported by Jo Shields --- ChangeLog | 7 +++++++ gfxmenu/gui_list.c | 15 ++++----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index dbf6f23eb..65bd6ad03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-05-23 Vladimir Serbinenko + + * gfxmenu/gui_list.c (draw_menu): Don't add scrollbar width to padding. + Removed drawing_scrollbar argument. All users updated + Fixes #29792. + Reported by Jo Shields + 2010-05-23 Vladimir Serbinenko * gfxmenu/view.c (grub_gfxmenu_draw_terminal_box): Apply only to current diff --git a/gfxmenu/gui_list.c b/gfxmenu/gui_list.c index 0d771413f..8583a214e 100644 --- a/gfxmenu/gui_list.c +++ b/gfxmenu/gui_list.c @@ -210,8 +210,7 @@ draw_scrollbar (list_impl_t self, /* Draw the list of items. */ static void -draw_menu (list_impl_t self, int width, int drawing_scrollbar, - int num_shown_items) +draw_menu (list_impl_t self, int width, int num_shown_items) { if (! self->menu_box || ! self->selected_item_box) return; @@ -226,8 +225,6 @@ draw_menu (list_impl_t self, int width, int drawing_scrollbar, make_selected_item_visible (self); - int scrollbar_h_space = drawing_scrollbar ? self->scrollbar_width : 0; - grub_gfxmenu_box_t selbox = self->selected_item_box; int sel_leftpad = selbox->get_left_pad (selbox); int item_top = boxpad; @@ -244,12 +241,8 @@ draw_menu (list_impl_t self, int width, int drawing_scrollbar, if (is_selected) { int sel_toppad = selbox->get_top_pad (selbox); - selbox->set_content_size (selbox, - (width - 2 * boxpad - - scrollbar_h_space), - item_height); - selbox->draw (selbox, - item_left - sel_leftpad, + selbox->set_content_size (selbox, (width - 2 * boxpad), item_height); + selbox->draw (selbox, item_left - sel_leftpad, item_top - sel_toppad); } @@ -320,7 +313,7 @@ list_paint (void *vself, const grub_video_rect_t *region) box->draw (box, 0, 0); grub_gui_set_viewport (&content_rect, &vpsave2); - draw_menu (self, content_rect.width, drawing_scrollbar, num_shown_items); + draw_menu (self, content_rect.width, num_shown_items); grub_gui_restore_viewport (&vpsave2); if (drawing_scrollbar) From 76e6d0d767b295f2249b8320a719fe0cd8ea66ff Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 23 May 2010 14:11:11 +0200 Subject: [PATCH 30/96] Add default/grub support --- docs/grub.texi | 16 +++++++++++ util/grub-mkconfig.in | 4 +++ util/grub.d/00_header.in | 57 +++++++++++++++++++++++++++++++--------- 3 files changed, 65 insertions(+), 12 deletions(-) diff --git a/docs/grub.texi b/docs/grub.texi index 704f8b2a3..938fedbaf 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -80,6 +80,7 @@ This edition documents version @value{VERSION}. * Configuration:: Writing your own configuration file * Network:: Downloading OS images from a network * Serial terminal:: Using GRUB via a serial line +* Vendor power-on keys:: Changing GRUB behaviour on vendor power-on keys * Preset Menu:: Embedding a configuration file into GRUB * Images:: GRUB image files * Filesystem:: Filesystem syntax and semantics @@ -747,6 +748,21 @@ implements few VT100 escape sequences. If you specify this option then GRUB provides you with an alternative menu interface, because the normal menu requires several fancy features of your terminal. +@node Vendor power-on keys +@chapter Using GRUB with vendor power-on keys +Some laptop vendor provide an additional power-on button which boots another OS. +GRUB supports such buttons with GRUB_TIMEOUT_BUTTON, GRUB_DEFAULT_BUTTON, +GRUB_HIDDEN_TIMEOUT_BUTTON and GRUB_BUTTON_CMOS_ADDRESS variables in +default/grub. GRUB_TIMEOUT_BUTTON, GRUB_DEFAULT_BUTTON and +GRUB_HIDDEN_TIMEOUT_BUTTON are used instead of corresponding variables without +_BUTTON suffix when powered using special button. +GRUB_BUTTON_CMOS_ADDRESS is vendor specific and partially model-specific. +Values known to GRUB team are: + +@table @key +@item Dell XPS M1530 +85:3 +@end table @node Filesystem @chapter Filesystem syntax and semantics diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index d1abfa36a..0095e1ce8 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -246,6 +246,10 @@ export GRUB_DEFAULT \ GRUB_HIDDEN_TIMEOUT \ GRUB_HIDDEN_TIMEOUT_QUIET \ GRUB_TIMEOUT \ + GRUB_DEFAULT_BUTTON \ + GRUB_HIDDEN_TIMEOUT_BUTTON \ + GRUB_TIMEOUT_BUTTON \ + GRUB_BUTTON_CMOS_ADDRESS \ GRUB_DISTRIBUTOR \ GRUB_CMDLINE_LINUX \ GRUB_CMDLINE_LINUX_DEFAULT \ diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index d181fdffc..df8f5dfaa 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -38,11 +38,29 @@ if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then GRUB_DEFAULT='${saved_entry}' ; fi if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=5 ; fi if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=640x480 ; fi +if [ "x${GRUB_DEFAULT_BUTTON}" = "x" ] ; then GRUB_DEFAULT_BUTTON="$GRUB_DEFAULT" ; fi +if [ "x${GRUB_DEFAULT_BUTTON}" = "xsaved" ] ; then GRUB_DEFAULT_BUTTON='${saved_entry}' ; fi +if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT" ; fi + cat << EOF if [ -s \$prefix/grubenv ]; then load_env fi +EOF +if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then + cat < Date: Sun, 23 May 2010 14:37:28 +0200 Subject: [PATCH 31/96] * commands/usbtest.c (grub_usb_get_string): Properly support UTF-16. --- ChangeLog | 4 ++++ commands/usbtest.c | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 39a658288..01d2dbf7c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-23 Vladimir Serbinenko + + * commands/usbtest.c (grub_usb_get_string): Properly support UTF-16. + 2010-05-23 Vladimir Serbinenko cmostest support. diff --git a/commands/usbtest.c b/commands/usbtest.c index b884a93f1..191c4e4df 100644 --- a/commands/usbtest.c +++ b/commands/usbtest.c @@ -83,15 +83,24 @@ grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid, 0x06, (3 << 8) | index, langid, descstr.length, (char *) descstrp); - *string = grub_malloc (descstr.length / 2); + if (descstrp->length == 0) + { + grub_free (descstrp); + *string = grub_strdup (""); + if (! *string) + return GRUB_USB_ERR_INTERNAL; + return GRUB_USB_ERR_NONE; + } + + *string = grub_malloc (descstr.length * 2 + 1); if (! *string) { grub_free (descstrp); return GRUB_USB_ERR_INTERNAL; } - grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, descstrp->length / 2 - 1); - (*string)[descstr.length / 2 - 1] = '\0'; + *grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, + descstrp->length / 2 - 1) = 0; grub_free (descstrp); return GRUB_USB_ERR_NONE; From 7d8c0213538e9954d3b466d91c6c7c3c0f10b300 Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Tue, 25 May 2010 18:24:46 +0530 Subject: [PATCH 32/96] * INSTALL: Added flex >= 2.5.35 requirement. --- ChangeLog | 4 ++++ INSTALL | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index 01d2dbf7c..b8e66c7a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-05-25 BVK Chaitanya + + * INSTALL: Added flex >= 2.5.35 requirement. + 2010-05-23 Vladimir Serbinenko * commands/usbtest.c (grub_usb_get_string): Properly support UTF-16. diff --git a/INSTALL b/INSTALL index 0dd408bcc..7186d20db 100644 --- a/INSTALL +++ b/INSTALL @@ -16,6 +16,7 @@ configuring the GRUB. * GNU Bison 2.3 or later * GNU gettext 0.17 or later * GNU binutils 2.9.1.0.23 or later +* Flex 2.5.35 or later * Other standard GNU/Unix tools If you use a development snapshot or want to hack on GRUB you may From 95ac3c730c58a60ec8a64bf046d235eec95eb790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Wed, 26 May 2010 23:49:52 +0200 Subject: [PATCH 33/96] Fix -Wshadow warning with emu build on NetBSD. --- ChangeLog | 5 +++++ kern/emu/hostdisk.c | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index b8e66c7a2..ff7d02b44 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-26 Grégoire Sutre + + * kern/emu/hostdisk.c (find_partition_start) [__NetBSD__]: Renamed + variable index into p_index to suppress a warning with -Wshadow. + 2010-05-25 BVK Chaitanya * INSTALL: Added flex >= 2.5.35 requirement. diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index 9c4697552..ae2f7d9ad 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -338,7 +338,7 @@ find_partition_start (const char *dev) struct hd_geometry hdg; # else /* defined(__NetBSD__) */ struct disklabel label; - int index; + int p_index; # endif /* !defined(__NetBSD__) */ # ifdef HAVE_DEVICE_MAPPER @@ -435,15 +435,15 @@ devmapper_fail: # if !defined(__NetBSD__) return hdg.start; # else /* defined(__NetBSD__) */ - index = dev[strlen(dev) - 1] - 'a'; + p_index = dev[strlen(dev) - 1] - 'a'; - if (index >= label.d_npartitions) + if (p_index >= label.d_npartitions) { grub_error (GRUB_ERR_BAD_DEVICE, "no disk label entry for `%s'", dev); return 0; } - return (grub_disk_addr_t) label.d_partitions[index].p_offset; + return (grub_disk_addr_t) label.d_partitions[p_index].p_offset; # endif /* !defined(__NetBSD__) */ } #endif /* __linux__ || __CYGWIN__ */ From d1d368e426d3a0554ec28f52dafbd644fd21816e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 27 May 2010 12:43:22 +0100 Subject: [PATCH 34/96] * util/grub-mkrescue.in: Initialise override_dir rather than assuming that it's unset or empty in the environment. --- ChangeLog | 5 +++++ util/grub-mkrescue.in | 1 + 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index ff7d02b44..22005fbb9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-27 Colin Watson + + * util/grub-mkrescue.in: Initialise override_dir rather than + assuming that it's unset or empty in the environment. + 2010-05-26 Grégoire Sutre * kern/emu/hostdisk.c (find_partition_start) [__NetBSD__]: Renamed diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 7e7253006..99b10de7b 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -37,6 +37,7 @@ pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-pc efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi rom_directory= +override_dir= grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` # Usage: usage From 5fdba519bb35c64a2c90221f069863cc36e00387 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Thu, 27 May 2010 16:38:16 +0200 Subject: [PATCH 35/96] 2010-05-27 Robert Millan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Insert partmap module to handle cross-partmap setups. Reported by Orestes Mas. Gràcies! --- ChangeLog | 6 ++++++ util/grub-mkconfig_lib.in | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/ChangeLog b/ChangeLog index 22005fbb9..18c2abeac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-27 Robert Millan + + * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Insert + partmap module to handle cross-partmap setups. + Reported by Orestes Mas. Gràcies! + 2010-05-27 Colin Watson * util/grub-mkrescue.in: Initialise override_dir rather than diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index f4674b257..7ec8cb5be 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -105,6 +105,11 @@ prepare_grub_to_access_device () echo "insmod ${module}" done + partmap="`${grub_probe} --device ${device} --target=partmap`" + for module in ${partmap} ; do + echo "insmod ${module}" + done + fs="`${grub_probe} --device ${device} --target=fs`" for module in ${fs} ; do echo "insmod ${module}" From db2102a0468e15c76bb369eef728622a9e51683e Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 27 May 2010 15:45:41 +0100 Subject: [PATCH 36/96] * kern/emu/misc.c (canonicalize_file_name): realpath can still return NULL for various reasons even if it has a maximum-length buffer: for example, there might be a symlink loop, or the path might exceed PATH_MAX. If this happens, return NULL. --- ChangeLog | 7 +++++++ kern/emu/misc.c | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 18c2abeac..34bc31bf9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-05-27 Colin Watson + + * kern/emu/misc.c (canonicalize_file_name): realpath can still + return NULL for various reasons even if it has a maximum-length + buffer: for example, there might be a symlink loop, or the path + might exceed PATH_MAX. If this happens, return NULL. + 2010-05-27 Robert Millan * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Insert diff --git a/kern/emu/misc.c b/kern/emu/misc.c index a3ccb3076..9437169e0 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -185,7 +185,8 @@ canonicalize_file_name (const char *path) char *ret; #ifdef PATH_MAX ret = xmalloc (PATH_MAX); - (void) realpath (path, ret); + if (!realpath (path, ret)) + return NULL; #else ret = realpath (path, NULL); #endif From d870813427f6e58ddc6877a578ae5b882f6f0898 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 27 May 2010 15:54:18 +0100 Subject: [PATCH 37/96] * util/grub-script-check.c (main): Ensure defined behaviour on empty input files (in which case exit zero). --- ChangeLog | 5 +++++ util/grub-script-check.c | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 34bc31bf9..a8e3e5284 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-27 Colin Watson + + * util/grub-script-check.c (main): Ensure defined behaviour on empty + input files (in which case exit zero). + 2010-05-27 Colin Watson * kern/emu/misc.c (canonicalize_file_name): realpath can still diff --git a/util/grub-script-check.c b/util/grub-script-check.c index dc732aa01..e69f787f5 100644 --- a/util/grub-script-check.c +++ b/util/grub-script-check.c @@ -145,7 +145,8 @@ main (int argc, char *argv[]) char *input; FILE *file = 0; int verbose = 0; - struct grub_script *script; + int found_input = 0; + struct grub_script *script = NULL; auto grub_err_t get_config_line (char **line, int cont); grub_err_t get_config_line (char **line, int cont __attribute__ ((unused))) @@ -247,6 +248,7 @@ main (int argc, char *argv[]) get_config_line(&input, 0); if (! input) break; + found_input = 1; script = grub_script_parse (input, get_config_line); if (script) @@ -262,5 +264,5 @@ main (int argc, char *argv[]) grub_fini_all (); if (file) fclose (file); - return (script == 0); + return (found_input && script == 0); } From 15fb2ae896e6aad4ba947a5b4828f938575c9877 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 28 May 2010 11:51:50 +0100 Subject: [PATCH 38/96] Make grub-probe work with symbolic links under /dev/mapper as well as with real block devices. The Linux world seems to be (at best) in transition here, and GRUB shouldn't get caught in the middle. * kern/emu/getroot.c (find_root_device): Follow symbolic links under /dev/mapper. --- ChangeLog.mapper-symlink | 8 ++++++++ kern/emu/getroot.c | 15 +++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 ChangeLog.mapper-symlink diff --git a/ChangeLog.mapper-symlink b/ChangeLog.mapper-symlink new file mode 100644 index 000000000..afcfc6479 --- /dev/null +++ b/ChangeLog.mapper-symlink @@ -0,0 +1,8 @@ +2010-05-28 Colin Watson + + Make grub-probe work with symbolic links under /dev/mapper as well + as with real block devices. The Linux world seems to be (at best) + in transition here, and GRUB shouldn't get caught in the middle. + + * kern/emu/getroot.c (find_root_device): Follow symbolic links under + /dev/mapper. diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index 6875044da..e62abe089 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -126,9 +126,20 @@ find_root_device (const char *dir, dev_t dev) /* Ignore any error. */ continue; - if (S_ISLNK (st.st_mode)) - /* Don't follow symbolic links. */ + if (S_ISLNK (st.st_mode)) { +#ifdef __linux__ + if (strcmp (dir, "mapper") == 0) { + /* Follow symbolic links under /dev/mapper/; the canonical name + may be something like /dev/dm-0, but the names under + /dev/mapper/ are more human-readable and so we prefer them if + we can get them. */ + if (stat (ent->d_name, &st) < 0) + continue; + } else +#endif /* __linux__ */ + /* Don't follow other symbolic links. */ continue; + } if (S_ISDIR (st.st_mode)) { From fa4b84900afa71ad9fcf498d509e8f0e8abbb6dc Mon Sep 17 00:00:00 2001 From: BVK Chaitanya Date: Fri, 28 May 2010 19:18:45 +0530 Subject: [PATCH 39/96] Fix grub-emu issues on NetBSD, with gcc 4.1.3. * conf/any-emu.rmk: Remove unnecessary COMMON_CFLAGS. * include/grub/emu/misc.h (canonicalize_file_name): New Prototype. * kern/misc.c (__enable_execute_stack): Disable on GRUB_MACHINE_EMU. --- ChangeLog | 9 +++++++++ conf/any-emu.rmk | 2 -- include/grub/emu/misc.h | 1 + kern/misc.c | 3 ++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 965848669..e3fb344aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2010-05-28 BVK Chaitanya + + Fix grub-emu issues on NetBSD, with gcc 4.1.3. + + * conf/any-emu.rmk: Remove unnecessary COMMON_CFLAGS. + * include/grub/emu/misc.h (canonicalize_file_name): New Prototype. + * kern/misc.c (__enable_execute_stack): Disable on + GRUB_MACHINE_EMU. + 2010-05-28 Colin Watson Make grub-probe work with symbolic links under /dev/mapper as well diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 3f0df06aa..000996172 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -1,7 +1,5 @@ # -*- makefile -*- -COMMON_CFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include) - kernel_img_RELOCATABLE = yes pkglib_PROGRAMS = kernel.img kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index e037e6be7..0e6ace0e8 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -46,5 +46,6 @@ int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...); #endif char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); +extern char * canonicalize_file_name (const char *path); #endif /* GRUB_EMU_MISC_H */ diff --git a/kern/misc.c b/kern/misc.c index ccc01d43f..2ba34f235 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -1058,7 +1058,7 @@ grub_abort (void) void abort (void) __attribute__ ((alias ("grub_abort"))); #endif -#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) +#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) && !defined(GRUB_MACHINE_EMU) /* Some gcc versions generate a call to this function in trampolines for nested functions. */ void __enable_execute_stack (void *addr __attribute__ ((unused))) @@ -1075,3 +1075,4 @@ void __deregister_frame_info (void) { } #endif + From c7c75cf4cb568889432527f94efc0d971e2cc3b0 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 28 May 2010 18:13:48 +0100 Subject: [PATCH 40/96] * configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not to the empty string. --- ChangeLog | 5 +++++ configure.ac | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e3fb344aa..5072a6026 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-28 Colin Watson + + * configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not + to the empty string. + 2010-05-28 BVK Chaitanya Fix grub-emu issues on NetBSD, with gcc 4.1.3. diff --git a/configure.ac b/configure.ac index ace6bd81d..31b179d46 100644 --- a/configure.ac +++ b/configure.ac @@ -192,7 +192,7 @@ AC_PROG_LEX AC_PROG_MAKE_SET AC_PROG_MKDIR_P -if test "x$LEX" = x; then +if test "x$LEX" = "x:"; then AC_MSG_ERROR([flex is not found]) else version=`$LEX --version | $AWK '{ split($NF,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'` From 8b1cf5e87f603a30dbc0e0d13c44c3628d67b2bf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 13:58:18 +0200 Subject: [PATCH 41/96] Dedicated DMA allocation functions. CS5536 OHCI support. --- bus/cs5536.c | 215 +++++++++++++++++++++++++++++++ bus/pci.c | 53 ++++++++ bus/usb/ohci.c | 175 +++++++++++++++++-------- bus/usb/uhci.c | 6 +- bus/usb/usbtrans.c | 91 ++++++++++--- conf/i386.rmk | 6 + conf/mips-yeeloong.rmk | 34 ++++- include/grub/cs5536.h | 190 +++++++++++++++++++++++++++ include/grub/i386/pci.h | 2 +- include/grub/mips/yeeloong/pci.h | 32 +++-- include/grub/pci.h | 26 ++++ include/grub/smbus.h | 70 ++++++++++ include/grub/usbtrans.h | 2 +- 13 files changed, 817 insertions(+), 85 deletions(-) create mode 100644 bus/cs5536.c create mode 100644 include/grub/cs5536.h create mode 100644 include/grub/smbus.h diff --git a/bus/cs5536.c b/bus/cs5536.c new file mode 100644 index 000000000..61b0646b4 --- /dev/null +++ b/bus/cs5536.c @@ -0,0 +1,215 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +int +grub_cs5536_find (grub_pci_device_t *devp) +{ + int found = 0; + auto int NESTED_FUNC_ATTR hook (grub_pci_device_t dev, + grub_pci_id_t pciid); + + int NESTED_FUNC_ATTR hook (grub_pci_device_t dev, + grub_pci_id_t pciid) + { + if (pciid == GRUB_CS5536_PCIID) + { + *devp = dev; + found = 1; + return 1; + } + return 0; + } + + grub_pci_iterate (hook); + + return found; +} + +grub_uint64_t +grub_cs5536_read_msr (grub_pci_device_t dev, grub_uint32_t addr) +{ + grub_uint64_t ret = 0; + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_ADDR), + addr); + ret = (grub_uint64_t) + grub_pci_read (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0)); + ret |= (((grub_uint64_t) + grub_pci_read (grub_pci_make_address (dev, + GRUB_CS5536_MSR_MAILBOX_DATA1))) + << 32); + return ret; +} + +void +grub_cs5536_write_msr (grub_pci_device_t dev, grub_uint32_t addr, + grub_uint64_t val) +{ + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_ADDR), + addr); + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0), + val & 0xffffffff); + grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA1), + val >> 32); +} + +grub_err_t +grub_cs5536_smbus_wait (grub_port_t smbbase) +{ + grub_uint64_t start = grub_get_time_ms (); + while (1) + { + grub_uint8_t status; + status = grub_inb (smbbase + GRUB_CS5536_SMB_REG_STATUS); + if (status & GRUB_CS5536_SMB_REG_STATUS_SDAST) + return GRUB_ERR_NONE; + if (status & GRUB_CS5536_SMB_REG_STATUS_BER) + return grub_error (GRUB_ERR_IO, "SM bus error"); + if (status & GRUB_CS5536_SMB_REG_STATUS_NACK) + return grub_error (GRUB_ERR_IO, "NACK received"); + if (grub_get_time_ms () > start + 40) + return grub_error (GRUB_ERR_IO, "SM stalled"); + } + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev, + grub_uint8_t addr, grub_uint8_t *res) +{ + grub_err_t err; + + /* Send START. */ + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_START, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Send device address. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (dev << 1, smbbase + GRUB_CS5536_SMB_REG_DATA); + + /* Send ACK. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_ACK, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Send byte address. */ + grub_outb (addr, smbbase + GRUB_CS5536_SMB_REG_DATA); + + /* Send START. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_START, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Send device address. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb ((dev << 1) | 1, smbbase + GRUB_CS5536_SMB_REG_DATA); + + /* Send STOP. */ + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1) + | GRUB_CS5536_SMB_REG_CTRL1_STOP, + smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + err = grub_cs5536_smbus_wait (smbbase); + if (err) + return err; + *res = grub_inb (smbbase + GRUB_CS5536_SMB_REG_DATA); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_cs5536_init_smbus (grub_pci_device_t dev, grub_uint16_t divisor, + grub_port_t *smbbase) +{ + grub_uint64_t smbbar; + + smbbar = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_SMB_BAR); + + /* FIXME */ + if (!(smbbar & GRUB_CS5536_LBAR_ENABLE)) + return grub_error(GRUB_ERR_IO, "SMB controller not enabled\n"); + *smbbase = (smbbar & GRUB_CS5536_LBAR_ADDR_MASK) + GRUB_MACHINE_PCI_IO_BASE; + + if (divisor < 8) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid divisor"); + + /* Disable SMB. */ + grub_outb (0, *smbbase + GRUB_CS5536_SMB_REG_CTRL2); + + /* Disable interrupts. */ + grub_outb (0, *smbbase + GRUB_CS5536_SMB_REG_CTRL1); + + /* Set as master. */ + grub_outb (GRUB_CS5536_SMB_REG_ADDR_MASTER, + *smbbase + GRUB_CS5536_SMB_REG_ADDR); + + /* Launch. */ + grub_outb (((divisor >> 7) & 0xff), *smbbase + GRUB_CS5536_SMB_REG_CTRL3); + grub_outb (((divisor << 1) & 0xfe) | GRUB_CS5536_SMB_REG_CTRL2_ENABLE, + *smbbase + GRUB_CS5536_SMB_REG_CTRL2); + + return GRUB_ERR_NONE; +} + +grub_err_t +grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev, + struct grub_smbus_spd *res) +{ + grub_err_t err; + grub_size_t size; + grub_uint8_t b; + grub_size_t ptr; + + err = grub_cs5536_read_spd_byte (smbbase, dev, 0, &b); + if (err) + return err; + if (b == 0) + return grub_error (GRUB_ERR_IO, "no SPD found"); + size = b; + + ((grub_uint8_t *) res)[0] = b; + for (ptr = 1; ptr < size; ptr++) + { + err = grub_cs5536_read_spd_byte (smbbase, dev, ptr, + &((grub_uint8_t *) res)[ptr]); + if (err) + return err; + } + return GRUB_ERR_NONE; +} + diff --git a/bus/pci.c b/bus/pci.c index a08e53446..3e2126962 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -19,6 +19,49 @@ #include #include +#include + +#if GRUB_TARGET_SIZEOF_VOID_P == 4 +struct grub_pci_dma_chunk * +grub_memalign_dma32 (grub_size_t align, grub_size_t size) +{ + return grub_memalign (align, size); +} + +void +grub_dma_free (struct grub_pci_dma_chunk *ch) +{ + grub_free (ch); +} +#endif + +#ifdef GRUB_MACHINE_MIPS_YEELOONG +volatile void * +grub_dma_get_virt (struct grub_pci_dma_chunk *ch) +{ + return (void *) ((((grub_uint32_t) ch) & 0x1fffffff) | 0xa0000000); +} + +grub_uint32_t +grub_dma_get_phys (struct grub_pci_dma_chunk *ch) +{ + return (((grub_uint32_t) ch) & 0x1fffffff) | 0x80000000; +} +#else + +volatile void * +grub_dma_get_virt (struct grub_pci_dma_chunk *ch) +{ + return (void *) ch; +} + +grub_uint32_t +grub_dma_get_phys (struct grub_pci_dma_chunk *ch) +{ + return (grub_uint32_t) ch; +} + +#endif grub_pci_address_t grub_pci_make_address (grub_pci_device_t dev, int reg) @@ -48,6 +91,16 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook) if (id >> 16 == 0xFFFF) continue; +#ifdef GRUB_MACHINE_MIPS_YEELOONG + /* Skip ghosts. */ + if (id == GRUB_YEELOONG_OHCI_PCIID + && dev.function == GRUB_YEELOONG_OHCI_GHOST_FUNCTION) + continue; + if (id == GRUB_YEELOONG_EHCI_PCIID + && dev.function == GRUB_YEELOONG_EHCI_GHOST_FUNCTION) + continue; +#endif + if (hook (dev, id)) return; diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 6d185bc7f..7294fe537 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -24,8 +24,9 @@ #include #include #include -#include +#include #include +#include struct grub_ohci_hcca { @@ -63,13 +64,15 @@ struct grub_ohci_td grub_uint32_t buffer_end; } __attribute__((packed)); -typedef struct grub_ohci_td *grub_ohci_td_t; -typedef struct grub_ohci_ed *grub_ohci_ed_t; +typedef volatile struct grub_ohci_td *grub_ohci_td_t; +typedef volatile struct grub_ohci_ed *grub_ohci_ed_t; struct grub_ohci { volatile grub_uint32_t *iobase; volatile struct grub_ohci_hcca *hcca; + grub_uint32_t hcca_addr; + struct grub_pci_dma_chunk *hcca_chunk; struct grub_ohci *next; }; @@ -91,10 +94,23 @@ typedef enum GRUB_OHCI_REG_BULKCURR, GRUB_OHCI_REG_DONEHEAD, GRUB_OHCI_REG_FRAME_INTERVAL, + GRUB_OHCI_REG_PERIODIC_START = 16, GRUB_OHCI_REG_RHUBA = 18, GRUB_OHCI_REG_RHUBPORT = 21 } grub_ohci_reg_t; +#define GRUB_OHCI_RHUB_PORT_POWER_MASK 0x300 +#define GRUB_OHCI_RHUB_PORT_ALL_POWERED 0x200 + +#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK 0x8fff0000 +#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT 16 +#define GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT 0 + +/* XXX: Is this choice of timings sane? */ +#define GRUB_OHCI_FSMPS 0x2778 +#define GRUB_OHCI_PERIODIC_START 0x257f +#define GRUB_OHCI_FRAME_INTERVAL 0x2edf + static grub_uint32_t grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg) { @@ -114,51 +130,81 @@ grub_ohci_writereg32 (struct grub_ohci *o, controller. If this is the case, initialize it. */ static int NESTED_FUNC_ATTR grub_ohci_pci_iter (grub_pci_device_t dev, - grub_pci_id_t pciid __attribute__((unused))) + grub_pci_id_t pciid) { - grub_uint32_t class_code; - grub_uint32_t class; - grub_uint32_t subclass; grub_uint32_t interf; grub_uint32_t base; grub_pci_address_t addr; struct grub_ohci *o; grub_uint32_t revision; - grub_uint32_t frame_interval; - - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - class_code = grub_pci_read (addr) >> 8; - - interf = class_code & 0xFF; - subclass = (class_code >> 8) & 0xFF; - class = class_code >> 16; - - /* If this is not an OHCI controller, just return. */ - if (class != 0x0c || subclass != 0x03 || interf != 0x10) - return 0; + int cs5536; /* Determine IO base address. */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - base = grub_pci_read (addr); + grub_dprintf ("ohci", "pciid = %x\n", pciid); + + if (pciid == GRUB_CS5536_PCIID) + { + grub_uint64_t basereg; + + cs5536 = 1; + basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE); + if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE)) + { + /* Shouldn't happen. */ + grub_dprintf ("ohci", "No OHCI address is assigned\n"); + return 0; + } + base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK); + basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER; + basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED; + basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS; + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE, basereg); + } + else + { + grub_uint32_t class_code; + grub_uint32_t class; + grub_uint32_t subclass; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class_code = grub_pci_read (addr) >> 8; + + interf = class_code & 0xFF; + subclass = (class_code >> 8) & 0xFF; + class = class_code >> 16; + + /* If this is not an OHCI controller, just return. */ + if (class != 0x0c || subclass != 0x03 || interf != 0x10) + return 0; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + base = grub_pci_read (addr); #if 0 - /* Stop if there is no IO space base address defined. */ - if (! (base & 1)) - return 0; + /* Stop if there is no IO space base address defined. */ + if (! (base & 1)) + return 0; #endif + grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x\n", + class, subclass, interf); + } + /* Allocate memory for the controller and register it. */ o = grub_malloc (sizeof (*o)); if (! o) return 1; - o->iobase = (grub_uint32_t *) base; + o->iobase = grub_pci_device_map_range (dev, base, 0x100); + + grub_dprintf ("ohci", "base=%p\n", o->iobase); /* Reserve memory for the HCCA. */ - o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256); - - grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x base=%p\n", - class, subclass, interf, o->iobase); + o->hcca_chunk = grub_memalign_dma32 (256, 256); + if (! o->hcca_chunk) + return 1; + o->hcca = grub_dma_get_virt (o->hcca_chunk); + o->hcca_addr = grub_dma_get_phys (o->hcca_chunk); /* Check if the OHCI revision is actually 1.0 as supported. */ revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION); @@ -166,19 +212,27 @@ grub_ohci_pci_iter (grub_pci_device_t dev, if ((revision & 0xFF) != 0x10) goto fail; - /* Backup the frame interval register. */ - frame_interval = grub_ohci_readreg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBA, + (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) + & ~GRUB_OHCI_RHUB_PORT_POWER_MASK) + | GRUB_OHCI_RHUB_PORT_ALL_POWERED); /* Suspend the OHCI by issuing a reset. */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */ grub_millisleep (1); grub_dprintf ("ohci", "OHCI reset\n"); - /* Restore the frame interval register. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, frame_interval); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, + (GRUB_OHCI_FSMPS + << GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT) + | (GRUB_OHCI_FRAME_INTERVAL + << GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT)); + + grub_ohci_writereg32 (o, GRUB_OHCI_REG_PERIODIC_START, + GRUB_OHCI_PERIODIC_START); /* Setup the HCCA. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr); grub_dprintf ("ohci", "OHCI HCCA\n"); /* Enable the OHCI. */ @@ -194,11 +248,13 @@ grub_ohci_pci_iter (grub_pci_device_t dev, return 0; fail: +#ifndef GRUB_MACHINE_MIPS_YEELOONG if (o) grub_free ((void *) o->hcca); +#endif grub_free (o); - return 1; + return 0; } @@ -229,7 +285,7 @@ grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev)) static void grub_ohci_transaction (grub_ohci_td_t td, grub_transfer_type_t type, unsigned int toggle, - grub_size_t size, char *data) + grub_size_t size, grub_uint32_t data) { grub_uint32_t token; grub_uint32_t buffer; @@ -261,7 +317,7 @@ grub_ohci_transaction (grub_ohci_td_t td, token |= toggle << 24; token |= 1 << 25; - buffer = (grub_uint32_t) data; + buffer = data; buffer_end = buffer + size - 1; td->token = grub_cpu_to_le32 (token); @@ -276,7 +332,10 @@ grub_ohci_transfer (grub_usb_controller_t dev, { struct grub_ohci *o = (struct grub_ohci *) dev->data; grub_ohci_ed_t ed; + grub_uint32_t ed_addr; + struct grub_pci_dma_chunk *ed_chunk, *td_list_chunk; grub_ohci_td_t td_list; + grub_uint32_t td_list_addr; grub_uint32_t target; grub_uint32_t td_tail; grub_uint32_t td_head; @@ -286,18 +345,23 @@ grub_ohci_transfer (grub_usb_controller_t dev, int i; /* Allocate an Endpoint Descriptor. */ - ed = grub_memalign (16, sizeof (*ed)); - if (! ed) + ed_chunk = grub_memalign_dma32 (256, sizeof (*ed)); + if (! ed_chunk) return GRUB_USB_ERR_INTERNAL; + ed = grub_dma_get_virt (ed_chunk); + ed_addr = grub_dma_get_phys (ed_chunk); - td_list = grub_memalign (16, sizeof (*td_list) * (transfer->transcnt + 1)); - if (! td_list) + td_list_chunk = grub_memalign_dma32 (256, sizeof (*td_list) + * (transfer->transcnt + 1)); + if (! td_list_chunk) { - grub_free ((void *) ed); + grub_dma_free (ed_chunk); return GRUB_USB_ERR_INTERNAL; } + td_list = grub_dma_get_virt (td_list_chunk); + td_list_addr = grub_dma_get_phys (td_list_chunk); - grub_dprintf ("ohci", "alloc=%p\n", td_list); + grub_dprintf ("ohci", "alloc=%p/0x%x\n", td_list, td_list_addr); /* Setup all Transfer Descriptors. */ for (i = 0; i < transfer->transcnt; i++) @@ -307,7 +371,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_transaction (&td_list[i], tr->pid, tr->toggle, tr->size, tr->data); - td_list[i].next_td = grub_cpu_to_le32 (&td_list[i + 1]); + td_list[i].next_td = grub_cpu_to_le32 (td_list_addr + + (i + 1) * sizeof (td_list[0])); } /* Setup the Endpoint Descriptor. */ @@ -324,9 +389,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Set the maximum packet size. */ target |= transfer->max << 16; - td_head = (grub_uint32_t) td_list; + td_head = td_list_addr; - td_tail = (grub_uint32_t) &td_list[transfer->transcnt]; + td_tail = td_list_addr + transfer->transcnt * sizeof (*td_list); ed->target = grub_cpu_to_le32 (target); ed->td_head = grub_cpu_to_le32 (td_head); @@ -353,7 +418,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, status &= ~(1 << 2); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, (grub_uint32_t) ed); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, ed_addr); /* Enable the Bulk list. */ control |= 1 << 5; @@ -380,10 +445,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, status &= ~(1 << 1); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, - (grub_uint32_t) ed); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, ed_addr); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1, - (grub_uint32_t) ed); + ed_addr); /* Enable the Control list. */ control |= 1 << 4; @@ -424,9 +488,12 @@ grub_ohci_transfer (grub_usb_controller_t dev, { grub_uint8_t errcode; grub_ohci_td_t tderr; + grub_uint32_t td_err_addr; - tderr = (grub_ohci_td_t) grub_ohci_readreg32 (o, - GRUB_OHCI_REG_DONEHEAD); + td_err_addr = grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD); + + tderr = (grub_ohci_td_t) ((char *) td_list + + (td_err_addr - td_list_addr)); errcode = tderr->token >> 28; switch (errcode) @@ -519,8 +586,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); /* XXX */ - grub_free (td_list); - grub_free (ed); + grub_dma_free (td_list_chunk); + grub_dma_free (ed_chunk); return err; } diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 947f2367b..6e47c38ef 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -380,7 +380,7 @@ static grub_uhci_td_t grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, grub_transfer_type_t type, unsigned int addr, unsigned int toggle, grub_size_t size, - char *data) + grub_uint32_t data) { grub_uhci_td_t td; static const unsigned int tf[] = { 0x69, 0xE1, 0x2D }; @@ -398,7 +398,7 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, } grub_dprintf ("uhci", - "transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=%p td=%p\n", + "transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=0x%x td=%p\n", endp, type, addr, toggle, size, data, td); /* Don't point to any TD, just terminate. */ @@ -418,7 +418,7 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, td->token = ((size << 21) | (toggle << 19) | (endp << 15) | (addr << 8) | tf[type]); - td->buffer = (grub_uint32_t) data; + td->buffer = data; return td; } diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index 09e7af83e..f6d3d30f9 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -29,30 +30,59 @@ grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t request, grub_uint16_t value, grub_uint16_t index, - grub_size_t size, char *data) + grub_size_t size0, char *data_in) { int i; grub_usb_transfer_t transfer; int datablocks; - struct grub_usb_packet_setup setupdata; + volatile struct grub_usb_packet_setup *setupdata; + grub_uint32_t setupdata_addr; grub_usb_err_t err; unsigned int max; + struct grub_pci_dma_chunk *data_chunk, *setupdata_chunk; + volatile char *data; + grub_uint32_t data_addr; + grub_size_t size = size0; + + /* FIXME: avoid allocation any kind of buffer in a first place. */ + data_chunk = grub_memalign_dma32 (128, size ? : 16); + if (!data_chunk) + return GRUB_USB_ERR_INTERNAL; + data = grub_dma_get_virt (data_chunk); + data_addr = grub_dma_get_phys (data_chunk); + grub_memcpy ((char *) data, data_in, size); grub_dprintf ("usb", "control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%d\n", reqtype, request, value, index, size); /* Create a transfer. */ - transfer = grub_malloc (sizeof (struct grub_usb_transfer)); + transfer = grub_malloc (sizeof (*transfer)); if (! transfer) - return grub_errno; + { + grub_dma_free (data_chunk); + return grub_errno; + } + + setupdata_chunk = grub_memalign_dma32 (32, sizeof (*setupdata)); + if (! setupdata_chunk) + { + grub_free (transfer); + grub_dma_free (data_chunk); + return grub_errno; + } + + setupdata = grub_dma_get_virt (setupdata_chunk); + setupdata_addr = grub_dma_get_phys (setupdata_chunk); /* Determine the maximum packet size. */ - if (dev->initialized) + if (dev->initialized && dev->descdev.maxsize0) max = dev->descdev.maxsize0; else max = 64; + grub_dprintf ("usb", "transfer = %p, dev = %p\n", transfer, dev); + datablocks = (size + max - 1) / max; /* XXX: Discriminate between different types of control @@ -71,18 +101,20 @@ grub_usb_control_msg (grub_usb_device_t dev, if (! transfer->transactions) { grub_free (transfer); + grub_dma_free (setupdata_chunk); + grub_dma_free (data_chunk); return grub_errno; } /* Build a Setup packet. XXX: Endianness. */ - setupdata.reqtype = reqtype; - setupdata.request = request; - setupdata.value = value; - setupdata.index = index; - setupdata.length = size; - transfer->transactions[0].size = sizeof (setupdata); + setupdata->reqtype = reqtype; + setupdata->request = request; + setupdata->value = value; + setupdata->index = index; + setupdata->length = size; + transfer->transactions[0].size = sizeof (*setupdata); transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP; - transfer->transactions[0].data = (char *) &setupdata; + transfer->transactions[0].data = setupdata_addr; transfer->transactions[0].toggle = 0; /* Now the data... XXX: Is this the right way to transfer control @@ -99,13 +131,13 @@ grub_usb_control_msg (grub_usb_device_t dev, tr->pid = GRUB_USB_TRANSFER_TYPE_IN; else tr->pid = GRUB_USB_TRANSFER_TYPE_OUT; - tr->data = &data[i * max]; + tr->data = data_addr + i * max; size -= max; } /* End with an empty OUT transaction. */ transfer->transactions[datablocks + 1].size = 0; - transfer->transactions[datablocks + 1].data = NULL; + transfer->transactions[datablocks + 1].data = 0; if (reqtype & 128) transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT; else @@ -117,13 +149,17 @@ grub_usb_control_msg (grub_usb_device_t dev, grub_free (transfer->transactions); grub_free (transfer); + grub_dma_free (data_chunk); + grub_dma_free (setupdata_chunk); + + grub_memcpy (data_in, (char *) data, size0); return err; } static grub_usb_err_t grub_usb_bulk_readwrite (grub_usb_device_t dev, - int endpoint, grub_size_t size, char *data, + int endpoint, grub_size_t size0, char *data_in, grub_transfer_type_t type) { int i; @@ -132,6 +168,19 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, unsigned int max; grub_usb_err_t err; int toggle = dev->toggle[endpoint]; + volatile char *data; + grub_uint32_t data_addr; + struct grub_pci_dma_chunk *data_chunk; + grub_size_t size = size0; + + /* FIXME: avoid allocation any kind of buffer in a first place. */ + data_chunk = grub_memalign_dma32 (128, size); + if (!data_chunk) + return GRUB_USB_ERR_INTERNAL; + data = grub_dma_get_virt (data_chunk); + data_addr = grub_dma_get_phys (data_chunk); + if (type == GRUB_USB_TRANSFER_TYPE_OUT) + grub_memcpy ((char *) data, data_in, size); /* Use the maximum packet size given in the endpoint descriptor. */ if (dev->initialized) @@ -150,7 +199,10 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, /* Create a transfer. */ transfer = grub_malloc (sizeof (struct grub_usb_transfer)); if (! transfer) - return grub_errno; + { + grub_dma_free (data_chunk); + return grub_errno; + } datablocks = ((size + max - 1) / max); transfer->transcnt = datablocks; @@ -167,6 +219,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, if (! transfer->transactions) { grub_free (transfer); + grub_dma_free (data_chunk); return grub_errno; } @@ -181,7 +234,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, tr->toggle = toggle; toggle = toggle ? 0 : 1; tr->pid = type; - tr->data = &data[i * max]; + tr->data = data_addr + i * max; size -= tr->size; } @@ -191,6 +244,10 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, grub_free (transfer->transactions); grub_free (transfer); + grub_dma_free (data_chunk); + + if (type == GRUB_USB_TRANSFER_TYPE_IN) + grub_memcpy (data_in, (char *) data, size0); return err; } diff --git a/conf/i386.rmk b/conf/i386.rmk index 02ce39817..73e818f9e 100644 --- a/conf/i386.rmk +++ b/conf/i386.rmk @@ -56,6 +56,12 @@ pci_mod_SOURCES = bus/pci.c pci_mod_CFLAGS = $(COMMON_CFLAGS) pci_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For cs5536.mod +pkglib_MODULES += cs5536.mod +cs5536_mod_SOURCES = bus/cs5536.c +cs5536_mod_CFLAGS = $(COMMON_CFLAGS) +cs5536_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For lspci.mod pkglib_MODULES += lspci.mod lspci_mod_SOURCES = commands/lspci.c diff --git a/conf/mips-yeeloong.rmk b/conf/mips-yeeloong.rmk index 5ce8ede9d..2468985c5 100644 --- a/conf/mips-yeeloong.rmk +++ b/conf/mips-yeeloong.rmk @@ -4,7 +4,8 @@ target_machine=yeeloong COMMON_CFLAGS += -march=mips3 COMMON_ASFLAGS += -march=mips3 -kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h bitmap_scale.h bufio.h +kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h \ + bitmap_scale.h bufio.h cs5536.h machine/pci.h include $(srcdir)/conf/mips.mk @@ -26,6 +27,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \ video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \ video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \ term/gfxterm.c commands/extcmd.c lib/arg.c \ + bus/cs5536.c \ symlist.c kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK kernel_img_ASFLAGS = $(COMMON_ASFLAGS) @@ -69,5 +71,35 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS) linux_mod_ASFLAGS = $(COMMON_ASFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For usb.mod +pkglib_MODULES += usb.mod +usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c +usb_mod_CFLAGS = $(COMMON_CFLAGS) +usb_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbtest.mod +pkglib_MODULES += usbtest.mod +usbtest_mod_SOURCES = commands/usbtest.c +usbtest_mod_CFLAGS = $(COMMON_CFLAGS) +usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For ohci.mod +pkglib_MODULES += ohci.mod +ohci_mod_SOURCES = bus/usb/ohci.c +ohci_mod_CFLAGS = $(COMMON_CFLAGS) +ohci_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usbms.mod +pkglib_MODULES += usbms.mod +usbms_mod_SOURCES = disk/usbms.c +usbms_mod_CFLAGS = $(COMMON_CFLAGS) +usbms_mod_LDFLAGS = $(COMMON_LDFLAGS) + +# For usb_keyboard.mod +pkglib_MODULES += usb_keyboard.mod +usb_keyboard_mod_SOURCES = term/usb_keyboard.c +usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS) +usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS) + sbin_SCRIPTS += grub-install grub_install_SOURCES = util/grub-install.in diff --git a/include/grub/cs5536.h b/include/grub/cs5536.h new file mode 100644 index 000000000..cd17e11fc --- /dev/null +++ b/include/grub/cs5536.h @@ -0,0 +1,190 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CS5536_HEADER +#define GRUB_CS5536_HEADER 1 + +#ifndef ASM_FILE +#include +#include +#include +#endif + +#define GRUB_CS5536_PCIID 0x208f1022 +#define GRUB_CS5536_MSR_MAILBOX_ADDR 0xf4 +#define GRUB_CS5536_MSR_MAILBOX_DATA0 0xf8 +#define GRUB_CS5536_MSR_MAILBOX_DATA1 0xfc +#define GRUB_CS5536_MSR_IRQ_MAP_BAR 0x80000008 +#define GRUB_CS5536_MSR_SMB_BAR 0x8000000b + +#define GRUB_CS5536_SMBUS_REGS_SIZE 8 +#define GRUB_CS5536_GPIO_REGS_SIZE 256 +#define GRUB_CS5536_MFGPT_REGS_SIZE 64 +#define GRUB_CS5536_IRQ_MAP_REGS_SIZE 32 +#define GRUB_CS5536_PM_REGS_SIZE 128 +#define GRUB_CS5536_ACPI_REGS_SIZE 32 + +#define GRUB_CS5536_USB_OPTION_REGS_SIZE 0x1c +#define GRUB_CS5536_USB_OPTION_REG_UOCMUX 1 +#define GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_MASK 0x03 +#define GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_HC 0x02 + +#define GRUB_CS5536_DESTINATION_GLIU 0 +#define GRUB_CS5536_DESTINATION_GLPCI_SB 1 +#define GRUB_CS5536_DESTINATION_USB 2 +#define GRUB_CS5536_DESTINATION_IDE 3 +#define GRUB_CS5536_DESTINATION_DD 4 +#define GRUB_CS5536_DESTINATION_ACC 5 +#define GRUB_CS5536_DESTINATION_GLCP 7 + +#define GRUB_CS5536_P2D_DEST_SHIFT 61 +#define GRUB_CS5536_P2D_LOG_ALIGN 12 +#define GRUB_CS5536_P2D_ALIGN (1 << GRUB_CS5536_P2D_LOG_ALIGN) +#define GRUB_CS5536_P2D_BASE_SHIFT 20 +#define GRUB_CS5536_P2D_MASK_SHIFT 0 + +#define GRUB_CS5536_MSR_GL_IOD_START 0x000100e0 +#define GRUB_CS5536_IOD_DEST_SHIFT 61 +#define GRUB_CS5536_IOD_BASE_SHIFT 20 +#define GRUB_CS5536_IOD_MASK_SHIFT 0 +#define GRUB_CS5536_IOD_ADDR_MASK 0xfffff + +#define GRUB_CS5536_MSR_GPIO_BAR 0x8000000c +#define GRUB_CS5536_MSR_MFGPT_BAR 0x8000000d +#define GRUB_CS5536_MSR_ACPI_BAR 0x8000000e +#define GRUB_CS5536_MSR_PM_BAR 0x8000000f +#define GRUB_CS5536_MSR_DIVIL_LEG_IO 0x80000014 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 0x00000001 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1 0x00000002 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 0x10000000 +#define GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP 0x04000000 +#define GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK 0x80000024 +#define GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK 0x80000025 +#define GRUB_CS5536_DIVIL_LPC_INTERRUPTS 0x1002 +#define GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL 0x8000004e +#define GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE 0x80 + +#define GRUB_CS5536_MSR_USB_OHCI_BASE 0x40000008 +#define GRUB_CS5536_MSR_USB_EHCI_BASE 0x40000009 +#define GRUB_CS5536_MSR_USB_CONTROLLER_BASE 0x4000000a +#define GRUB_CS5536_MSR_USB_OPTION_CONTROLLER_BASE 0x4000000b +#define GRUB_CS5536_MSR_USB_BASE_ADDR_MASK 0x00ffffff00ULL +#define GRUB_CS5536_MSR_USB_BASE_BUS_MASTER 0x0400000000ULL +#define GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE 0x0200000000ULL +#define GRUB_CS5536_MSR_USB_BASE_PME_ENABLED 0x0800000000ULL +#define GRUB_CS5536_MSR_USB_BASE_PME_STATUS 0x1000000000ULL +#define GRUB_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT 40 + +#define GRUB_CS5536_MSR_IDE_IO_BAR 0x60000008 +#define GRUB_CS5536_MSR_IDE_IO_BAR_UNITS 1 +#define GRUB_CS5536_MSR_IDE_IO_BAR_ADDR_MASK 0xfffffff0 +#define GRUB_CS5536_MSR_IDE_CFG 0x60000010 +#define GRUB_CS5536_MSR_IDE_CFG_CHANNEL_ENABLE 2 +#define GRUB_CS5536_MSR_IDE_TIMING 0x60000012 +#define GRUB_CS5536_MSR_IDE_TIMING_PIO0 0x98 +#define GRUB_CS5536_MSR_IDE_TIMING_DRIVE0_SHIFT 24 +#define GRUB_CS5536_MSR_IDE_TIMING_DRIVE1_SHIFT 16 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING 0x60000013 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_PIO0 0x99 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_SHIFT 24 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE0_SHIFT 6 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE1_SHIFT 4 +#define GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 2 + +#define GRUB_CS5536_MSR_GL_PCI_CTRL 0x00000010 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_MEMORY_ENABLE 1 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_IO_ENABLE 2 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_LATENCY_SHIFT 35 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_OUT_THR_SHIFT 60 +#define GRUB_CS5536_MSR_GL_PCI_CTRL_IN_THR_SHIFT 56 + +#define GRUB_CS5536_MSR_GL_REGIONS_START 0x00000020 +#define GRUB_CS5536_MSR_GL_REGIONS_NUM 16 +#define GRUB_CS5536_MSR_GL_REGION_ENABLE 1 +#define GRUB_CS5536_MSR_GL_REGION_IO 0x100000000ULL +#define GRUB_CS5536_MSR_GL_REGION_BASE_MASK 0xfffff000ULL +#define GRUB_CS5536_MSR_GL_REGION_IO_BASE_SHIFT 12 +#define GRUB_CS5536_MSR_GL_REGION_TOP_MASK 0xfffff00000000000ULL +#define GRUB_CS5536_MSR_GL_REGION_IO_TOP_SHIFT 44 + +#define GRUB_CS5536_MSR_GL_P2D_START 0x00010020 + +#define GRUB_CS5536_SMB_REG_DATA 0x0 +#define GRUB_CS5536_SMB_REG_STATUS 0x1 +#define GRUB_CS5536_SMB_REG_STATUS_SDAST (1 << 6) +#define GRUB_CS5536_SMB_REG_STATUS_BER (1 << 5) +#define GRUB_CS5536_SMB_REG_STATUS_NACK (1 << 4) +#define GRUB_CS5536_SMB_REG_CTRL1 0x3 +#define GRUB_CS5536_SMB_REG_CTRL1_START 0x01 +#define GRUB_CS5536_SMB_REG_CTRL1_STOP 0x02 +#define GRUB_CS5536_SMB_REG_CTRL1_ACK 0x10 +#define GRUB_CS5536_SMB_REG_ADDR 0x4 +#define GRUB_CS5536_SMB_REG_ADDR_MASTER 0x0 +#define GRUB_CS5536_SMB_REG_CTRL2 0x5 +#define GRUB_CS5536_SMB_REG_CTRL2_ENABLE 0x1 +#define GRUB_CS5536_SMB_REG_CTRL3 0x6 + +#ifdef ASM_FILE +#define GRUB_ULL(x) x +#else +#define GRUB_ULL(x) x ## ULL +#endif + +#define GRUB_CS5536_LBAR_ADDR_MASK GRUB_ULL (0x000000000000fff8) +#define GRUB_CS5536_LBAR_ENABLE GRUB_ULL (0x0000000100000000) +#define GRUB_CS5536_LBAR_MASK_MASK GRUB_ULL (0x0000f00000000000) +#define GRUB_CS5536_LBAR_TURN_ON (GRUB_CS5536_LBAR_ENABLE | GRUB_CS5536_LBAR_MASK_MASK) + +/* PMON-compatible LBARs. */ +#define GRUB_CS5536_LBAR_GPIO 0xb000 +#define GRUB_CS5536_LBAR_ACC 0xb200 +#define GRUB_CS5536_LBAR_PM 0xb280 +#define GRUB_CS5536_LBAR_MFGPT 0xb300 +#define GRUB_CS5536_LBAR_ACPI 0xb340 +#define GRUB_CS5536_LBAR_IRQ_MAP 0xb360 +#define GRUB_CS5536_LBAR_IDE 0xb380 +#define GRUB_CS5536_LBAR_SMBUS 0xb390 + +#define GRUB_GPIO_SMBUS_PINS ((1 << 14) | (1 << 15)) +#define GRUB_GPIO_REG_OUT_EN 0x4 +#define GRUB_GPIO_REG_OUT_AUX1 0x10 +#define GRUB_GPIO_REG_IN_EN 0x20 +#define GRUB_GPIO_REG_IN_AUX1 0x34 + +#ifndef ASM_FILE +int EXPORT_FUNC (grub_cs5536_find) (grub_pci_device_t *devp); + +grub_uint64_t EXPORT_FUNC (grub_cs5536_read_msr) (grub_pci_device_t dev, + grub_uint32_t addr); +void EXPORT_FUNC (grub_cs5536_write_msr) (grub_pci_device_t dev, + grub_uint32_t addr, + grub_uint64_t val); +grub_err_t grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev, + grub_uint8_t addr, grub_uint8_t *res); +grub_err_t EXPORT_FUNC (grub_cs5536_read_spd) (grub_port_t smbbase, + grub_uint8_t dev, + struct grub_smbus_spd *res); +grub_err_t grub_cs5536_smbus_wait (grub_port_t smbbase); +grub_err_t EXPORT_FUNC (grub_cs5536_init_smbus) (grub_pci_device_t dev, + grub_uint16_t divisor, + grub_port_t *smbbase); + +void grub_cs5536_init_geode (grub_pci_device_t dev); +#endif + +#endif diff --git a/include/grub/i386/pci.h b/include/grub/i386/pci.h index bab42adb6..795dec58b 100644 --- a/include/grub/i386/pci.h +++ b/include/grub/i386/pci.h @@ -80,7 +80,7 @@ grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), static inline void grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), - void *mem __attribute__ ((unused)), + volatile void *mem __attribute__ ((unused)), grub_size_t size __attribute__ ((unused))) { } diff --git a/include/grub/mips/yeeloong/pci.h b/include/grub/mips/yeeloong/pci.h index c7bd31d4f..199bac048 100644 --- a/include/grub/mips/yeeloong/pci.h +++ b/include/grub/mips/yeeloong/pci.h @@ -19,16 +19,30 @@ #ifndef GRUB_MACHINE_PCI_H #define GRUB_MACHINE_PCI_H 1 +#ifndef ASM_FILE #include #include +#endif + +#define GRUB_YEELOONG_OHCI_PCIID 0x00351033 +#define GRUB_YEELOONG_EHCI_PCIID 0x00e01033 +#define GRUB_YEELOONG_OHCI_GHOST_FUNCTION 4 +#define GRUB_YEELOONG_EHCI_GHOST_FUNCTION 5 #define GRUB_PCI_NUM_BUS 1 #define GRUB_PCI_NUM_DEVICES 16 -#define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000 -#define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000 -#define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00118) +#define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000 +#define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000 +#define GRUB_MACHINE_PCI_CONTROLLER_HEADER 0xbfe00000 + +#define GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR 0xbfe00118 + +#ifndef ASM_FILE +#define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) \ + GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR) #define GRUB_MACHINE_PCI_IO_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00110) +#endif #define GRUB_MACHINE_PCI_WIN_MASK_SIZE 6 #define GRUB_MACHINE_PCI_WIN_MASK ((1 << GRUB_MACHINE_PCI_WIN_MASK_SIZE) - 1) @@ -46,6 +60,7 @@ #define GRUB_MACHINE_PCI_WIN2_ADDR 0xb4000000 #define GRUB_MACHINE_PCI_WIN3_ADDR 0xb8000000 +#ifndef ASM_FILE static inline grub_uint32_t grub_pci_read (grub_pci_address_t addr) { @@ -95,11 +110,12 @@ grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data) } volatile void * -grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), - grub_addr_t base, grub_size_t size); +EXPORT_FUNC (grub_pci_device_map_range) (grub_pci_device_t dev, + grub_addr_t base, grub_size_t size); void -grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), - volatile void *mem, - grub_size_t size __attribute__ ((unused))); +EXPORT_FUNC (grub_pci_device_unmap_range) (grub_pci_device_t dev, + volatile void *mem, + grub_size_t size); +#endif #endif /* GRUB_MACHINE_PCI_H */ diff --git a/include/grub/pci.h b/include/grub/pci.h index 89bd1034a..e6d6488f0 100644 --- a/include/grub/pci.h +++ b/include/grub/pci.h @@ -19,8 +19,10 @@ #ifndef GRUB_PCI_H #define GRUB_PCI_H 1 +#ifndef ASM_FILE #include #include +#endif #define GRUB_PCI_ADDR_SPACE_MASK 0x01 #define GRUB_PCI_ADDR_SPACE_MEMORY 0x00 @@ -66,6 +68,20 @@ #define GRUB_PCI_REG_MIN_GNT 0x3e #define GRUB_PCI_REG_MAX_LAT 0x3f +#define GRUB_PCI_COMMAND_IO_ENABLED 0x0001 +#define GRUB_PCI_COMMAND_MEM_ENABLED 0x0002 +#define GRUB_PCI_COMMAND_BUS_MASTER 0x0004 +#define GRUB_PCI_COMMAND_PARITY_ERROR 0x0040 +#define GRUB_PCI_COMMAND_SERR_ENABLE 0x0100 + +#define GRUB_PCI_STATUS_CAPABILITIES 0x0010 +#define GRUB_PCI_STATUS_66MHZ_CAPABLE 0x0020 +#define GRUB_PCI_STATUS_FAST_B2B_CAPABLE 0x0080 + +#define GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT 9 +#define GRUB_PCI_STATUS_DEVSEL_TIMING_MASK 0x0600 + +#ifndef ASM_FILE typedef grub_uint32_t grub_pci_id_t; #ifdef GRUB_MACHINE_EMU @@ -107,4 +123,14 @@ grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev, void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook); +struct grub_pci_dma_chunk; + +struct grub_pci_dma_chunk *EXPORT_FUNC(grub_memalign_dma32) (grub_size_t align, + grub_size_t size); +void EXPORT_FUNC(grub_dma_free) (struct grub_pci_dma_chunk *ch); +volatile void *EXPORT_FUNC(grub_dma_get_virt) (struct grub_pci_dma_chunk *ch); +grub_uint32_t EXPORT_FUNC(grub_dma_get_phys) (struct grub_pci_dma_chunk *ch); + +#endif + #endif /* GRUB_PCI_H */ diff --git a/include/grub/smbus.h b/include/grub/smbus.h new file mode 100644 index 000000000..0b8e6718f --- /dev/null +++ b/include/grub/smbus.h @@ -0,0 +1,70 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_SMBUS_HEADER +#define GRUB_SMBUS_HEADER 1 + +#define GRUB_SMB_RAM_START_ADDR 0x50 +#define GRUB_SMB_RAM_NUM_MAX 0x08 + +#define GRUB_SMBUS_SPD_MEMORY_TYPE_ADDR 2 +#define GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2 8 +#define GRUB_SMBUS_SPD_MEMORY_NUM_BANKS_ADDR 17 +#define GRUB_SMBUS_SPD_MEMORY_NUM_ROWS_ADDR 3 +#define GRUB_SMBUS_SPD_MEMORY_NUM_COLUMNS_ADDR 4 +#define GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_ADDR 5 +#define GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_MASK 0x7 +#define GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_ADDR 18 +#define GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE 5 +#define GRUB_SMBUS_SPD_MEMORY_TRAS_ADDR 30 +#define GRUB_SMBUS_SPD_MEMORY_TRTP_ADDR 38 + +#ifndef ASM_FILE + +struct grub_smbus_spd +{ + grub_uint8_t written_size; + grub_uint8_t log_total_flash_size; + grub_uint8_t memory_type; + union + { + grub_uint8_t unknown[253]; + struct { + grub_uint8_t num_rows; + grub_uint8_t num_columns; + grub_uint8_t num_of_ranks; + grub_uint8_t unused1[12]; + grub_uint8_t num_of_banks; + grub_uint8_t unused2[2]; + grub_uint8_t cas_latency; + grub_uint8_t unused3[9]; + grub_uint8_t rank_capacity; + grub_uint8_t unused4[1]; + grub_uint8_t tras; + grub_uint8_t unused5[7]; + grub_uint8_t trtp; + grub_uint8_t unused6[31]; + grub_uint8_t part_number[18]; + grub_uint8_t unused7[165]; + } ddr2; + }; +}; + +#endif + +#endif diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index 7e4a9d7ee..8c739684e 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -37,7 +37,7 @@ struct grub_usb_transaction int size; int toggle; grub_transfer_type_t pid; - char *data; + grub_uint32_t data; }; typedef struct grub_usb_transaction *grub_usb_transaction_t; From 7fd08f56ae0d5f76e5f5c7a184414ae8e0e36a91 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 14:01:38 +0200 Subject: [PATCH 42/96] Shut down OHCI on booting --- bus/usb/ohci.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 7294fe537..29ab5332a 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -654,6 +654,39 @@ grub_ohci_hubports (grub_usb_controller_t dev) return portinfo & 0xFF; } +static grub_err_t +grub_ohci_fini_hw (int noreturn __attribute__ ((unused))) +{ + struct grub_ohci *o; + + for (o = ohci; o; o = o->next) + { + int i, nports = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) & 0xff; + for (i = 0; i < nports; i++) + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + i, + GRUB_OHCI_CLEAR_PORT_ENABLE); + + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_DONEHEAD, 0); + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_ohci_restore_hw (void) +{ + struct grub_ohci *o; + + for (o = ohci; o; o = o->next) + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr); + + return GRUB_ERR_NONE; +} static struct grub_usb_controller_dev usb_controller = @@ -670,9 +703,12 @@ GRUB_MOD_INIT(ohci) { grub_ohci_inithw (); grub_usb_controller_dev_register (&usb_controller); + grub_loader_register_preboot_hook (grub_ohci_fini_hw, grub_ohci_restore_hw, + GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); } GRUB_MOD_FINI(ohci) { + grub_ohci_fini_hw (0); grub_usb_controller_dev_unregister (&usb_controller); } From 778ff32476c08a69d99e56fbfe9e7494e0c26bdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Nesrsta?= Date: Mon, 31 May 2010 14:11:41 +0200 Subject: [PATCH 43/96] Fix a bunch of problems with USB. --- bus/usb/ohci.c | 342 +++++++++++++++++++++++++++++++--------- bus/usb/uhci.c | 17 +- bus/usb/usb.c | 12 +- bus/usb/usbtrans.c | 5 +- commands/usbtest.c | 2 + disk/scsi.c | 183 +++++++++++++++++++-- disk/usbms.c | 166 ++++++++++++------- include/grub/scsicmd.h | 62 ++++++-- include/grub/usb.h | 9 +- include/grub/usbtrans.h | 6 +- 10 files changed, 637 insertions(+), 167 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 29ab5332a..03768d39e 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -27,6 +27,7 @@ #include #include #include +#include struct grub_ohci_hcca { @@ -96,7 +97,11 @@ typedef enum GRUB_OHCI_REG_FRAME_INTERVAL, GRUB_OHCI_REG_PERIODIC_START = 16, GRUB_OHCI_REG_RHUBA = 18, - GRUB_OHCI_REG_RHUBPORT = 21 + GRUB_OHCI_REG_RHUBPORT = 21, + GRUB_OHCI_REG_LEGACY_CONTROL = 0x100, + GRUB_OHCI_REG_LEGACY_INPUT = 0x104, + GRUB_OHCI_REG_LEGACY_OUTPUT = 0x108, + GRUB_OHCI_REG_LEGACY_STATUS = 0x10c } grub_ohci_reg_t; #define GRUB_OHCI_RHUB_PORT_POWER_MASK 0x300 @@ -195,7 +200,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, if (! o) return 1; - o->iobase = grub_pci_device_map_range (dev, base, 0x100); + o->iobase = grub_pci_device_map_range (dev, base, 0x800); grub_dprintf ("ohci", "base=%p\n", o->iobase); @@ -212,10 +217,48 @@ grub_ohci_pci_iter (grub_pci_device_t dev, if ((revision & 0xFF) != 0x10) goto fail; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBA, - (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) - & ~GRUB_OHCI_RHUB_PORT_POWER_MASK) - | GRUB_OHCI_RHUB_PORT_ALL_POWERED); + + { + grub_uint32_t control; + /* Check SMM/BIOS ownership of OHCI (SMM = USB Legacy Support driver for BIOS) */ + control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); + if ((control & 0x100) != 0) + { + unsigned i; + grub_dprintf("ohci", "OHCI is owned by SMM\n"); + /* Do change of ownership */ + /* Ownership change request */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, (1<<3)); /* XXX: Magic. */ + /* Waiting for SMM deactivation */ + for (i=0; i < 10; i++) + { + if ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & 0x100) == 0) + { + grub_dprintf("ohci", "Ownership changed normally.\n"); + break; + } + grub_millisleep (100); + } + if (i >= 10) + { + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & ~0x100); + grub_dprintf("ohci", "Ownership changing timeout, change forced !\n"); + } + } + else if (((control & 0x100) == 0) && + ((control & 0xc0) != 0)) /* Not owned by SMM nor reset */ + { + grub_dprintf("ohci", "OHCI is owned by BIOS\n"); + /* Do change of ownership - not implemented yet... */ + /* In fact we probably need to do nothing ...? */ + } + else + { + grub_dprintf("ohci", "OHCI is not owned by SMM nor BIOS\n"); + /* We can setup OHCI. */ + } + } /* Suspend the OHCI by issuing a reset. */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */ @@ -232,15 +275,58 @@ grub_ohci_pci_iter (grub_pci_device_t dev, GRUB_OHCI_PERIODIC_START); /* Setup the HCCA. */ + o->hcca->donehead = 0; grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr); grub_dprintf ("ohci", "OHCI HCCA\n"); + /* Misc. pre-sets. */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + + /* Check OHCI Legacy Support */ + if ((revision & 0x100) != 0) + { + grub_dprintf ("ohci", "Legacy Support registers detected\n"); + grub_dprintf ("ohci", "Current state of legacy control reg.: 0x%04x\n", + grub_ohci_readreg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL)); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL, + (grub_ohci_readreg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL)) & ~1); + grub_dprintf ("ohci", "OHCI Legacy Support disabled.\n"); + } + /* Enable the OHCI. */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, (2 << 6)); grub_dprintf ("ohci", "OHCI enable: 0x%02x\n", (grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) >> 6) & 3); + /* Power on all ports */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBA, + (grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) + & ~GRUB_OHCI_RHUB_PORT_POWER_MASK) + | GRUB_OHCI_RHUB_PORT_ALL_POWERED); + /* Wait for stable power (100ms) and stable attachment (100ms) */ + /* I.e. minimum wait time should be probably 200ms. */ + /* We assume that device is attached when ohci is loaded. */ + /* Some devices take long time to power-on or indicate attach. */ + /* Here is some experimental value which should probably mostly work. */ + /* Cameras with manual USB mode selection and maybe some other similar + * devices will not work in some cases - they are repowered during + * ownership change and then they are starting slowly and mostly they + * are wanting select proper mode again... + * The same situation can be on computers where BIOS not set-up OHCI + * to be at least powered USB bus (maybe it is Yeelong case...?) + * Possible workaround could be for example some prompt + * for user with confirmation of proper USB device connection. + * Another workaround - "rmmod usbms", "rmmod ohci", proper start + * and configuration of USB device and then "insmod ohci" + * and "insmod usbms". */ + grub_millisleep (500); + /* Link to ohci now that initialisation is successful. */ o->next = ohci; ohci = o; @@ -317,13 +403,29 @@ grub_ohci_transaction (grub_ohci_td_t td, token |= toggle << 24; token |= 1 << 25; + /* Set "Not accessed" error code */ + token |= 15 << 28; + buffer = data; buffer_end = buffer + size - 1; + /* Set correct buffer values in TD if zero transfer occurs */ + if (size) + { + buffer = (grub_uint32_t) data; + buffer_end = buffer + size - 1; + td->buffer = grub_cpu_to_le32 (buffer); + td->buffer_end = grub_cpu_to_le32 (buffer_end); + } + else + { + td->buffer = 0; + td->buffer_end = 0; + } + + /* Set the rest of TD */ td->token = grub_cpu_to_le32 (token); - td->buffer = grub_cpu_to_le32 (buffer); td->next_td = 0; - td->buffer_end = grub_cpu_to_le32 (buffer_end); } static grub_usb_err_t @@ -342,7 +444,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_uint32_t status; grub_uint32_t control; grub_usb_err_t err; - int i; + int i, j; + grub_uint64_t maxtime; + int err_timeout = 0; /* Allocate an Endpoint Descriptor. */ ed_chunk = grub_memalign_dma32 (256, sizeof (*ed)); @@ -375,13 +479,25 @@ grub_ohci_transfer (grub_usb_controller_t dev, + (i + 1) * sizeof (td_list[0])); } + /* The last-1 TD token we should change to enable interrupt when TD finishes. + * As OHCI interrupts are disabled, it does only setting of WDH bit in + * HcInterruptStatus register - and that is what we want to safely detect + * normal end of all transactions. */ + td_list[transfer->transcnt - 1].token &= ~(7 << 21); + + td_list[transfer->transcnt].token = 0; + td_list[transfer->transcnt].buffer = 0; + td_list[transfer->transcnt].buffer_end = 0; + td_list[transfer->transcnt].next_td = + (grub_uint32_t) &td_list[transfer->transcnt]; + /* Setup the Endpoint Descriptor. */ /* Set the device address. */ target = transfer->devaddr; - /* Set the endpoint. */ - target |= transfer->endpoint << 7; + /* Set the endpoint. It should be masked, we need 4 bits only. */ + target |= (transfer->endpoint & 15) << 7; /* Set the device speed. */ target |= (transfer->dev->speed == GRUB_USB_SPEED_LOW) << 13; @@ -400,6 +516,30 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_dprintf ("ohci", "program OHCI\n"); + /* Disable the Control and Bulk lists. */ + control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); + control &= ~(3 << 4); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); + + /* Clear BulkListFilled and ControlListFilled. */ + status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); + status &= ~(3 << 1); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); + + /* Now we should wait for start of next frame. Because we are not using + * interrupt, we reset SF bit and wait when it goes to 1. */ + /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); + /* Wait for new SOF */ + while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); + /* Now it should be safe to change CONTROL and BULK lists. */ + + /* This we do for safety's sake - it should be done in previous call + * of grub_ohci_transfer and nobody should change it in meantime... + * It should be done before start of control or bulk OHCI list. */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */ + /* Program the OHCI to actually transfer. */ switch (transfer->type) { @@ -407,24 +547,17 @@ grub_ohci_transfer (grub_usb_controller_t dev, { grub_dprintf ("ohci", "add to bulk list\n"); - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); - control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); - - /* Disable the Control and Bulk lists. */ - control &= ~(3 << 4); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); - - /* Clear BulkListFilled. */ - status &= ~(1 << 2); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - + /* Set BulkList Head and Current */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, ed_addr); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); /* Enable the Bulk list. */ + control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); control |= 1 << 5; grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); /* Set BulkListFilled. */ + status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); status |= 1 << 2; grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); @@ -433,21 +566,9 @@ grub_ohci_transfer (grub_usb_controller_t dev, case GRUB_USB_TRANSACTION_TYPE_CONTROL: { - grub_dprintf ("ohci", "add to control list\n"); - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); - control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); - - /* Disable the Control and Bulk lists. */ - control &= ~(3 << 4); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); - - /* Clear ControlListFilled. */ - status &= ~(1 << 1); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - + /* Set ControlList Head and Current */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, ed_addr); - grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1, - ed_addr); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); /* Enable the Control list. */ control |= 1 << 4; @@ -465,36 +586,77 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); + /* Safety measure to avoid a hang. */ + maxtime = grub_get_time_ms () + 1000; + /* Wait until the transfer is completed or STALLs. */ - while ((ed->td_head & ~0xf) != (ed->td_tail & ~0xf)) + do { grub_cpu_idle (); - grub_dprintf ("ohci", "head=0x%02x tail=0x%02x\n", ed->td_head, ed->td_tail); + /* Detected a HALT. */ + if (grub_le_to_cpu32 (ed->td_head) & 1) + break; + + if ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x2) != 0) + { + if ((grub_le_to_cpu32 (o->hcca->donehead) & ~0xf) + == td_list_addr + (transfer->transcnt - 1) * sizeof (td_list[0])) + break; - /* Detected a STALL. */ - if (ed->td_head & 1) + /* Done Head can be updated on some another place if ED is halted. */ + if (grub_le_to_cpu32 (ed->td_head) & 1) + break; + + /* If there is not HALT in ED, it is not correct, so debug it, reset + * donehead and WDH and continue waiting. */ + grub_dprintf ("ohci", "Incorrect HccaDoneHead=0x%08x\n", + o->hcca->donehead); + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); + continue; + } + /* Timeout ? */ + if (grub_get_time_ms () > maxtime) + { + /* Disable the Control and Bulk lists. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & ~(3 << 4)); + err_timeout = 1; + break; + } + + if ((ed->td_head & ~0xf) == (ed->td_tail & ~0xf)) break; } + while (1); - grub_dprintf ("ohci", "complete\n"); - -/* if (ed->td_head & 1) */ -/* err = GRUB_USB_ERR_STALL; */ -/* else if (ed->td */ - - - if (ed->td_head & 1) + if (err_timeout) + { + err = GRUB_ERR_TIMEOUT; + grub_dprintf("ohci", "Timeout, target=%08x, head=%08x\n\t\ttail=%08x, next=%08x\n", + grub_le_to_cpu32(ed->target), + grub_le_to_cpu32(ed->td_head), + grub_le_to_cpu32(ed->td_tail), + grub_le_to_cpu32(ed->next_ed)); + } + else if (grub_le_to_cpu32 (ed->td_head) & 1) { - grub_uint8_t errcode; - grub_ohci_td_t tderr; grub_uint32_t td_err_addr; + grub_uint8_t errcode; + grub_ohci_td_t tderr = NULL; - td_err_addr = grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD); + td_err_addr = (grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD) & ~0xf); + if (td_err_addr == 0) + /* If DONEHEAD==0 it means that correct address is in HCCA. + * It should be always now! */ + td_err_addr = (grub_le_to_cpu32 (o->hcca->donehead) & ~0xf); tderr = (grub_ohci_td_t) ((char *) td_list + (td_err_addr - td_list_addr)); - errcode = tderr->token >> 28; + + errcode = grub_le_to_cpu32 (tderr->token) >> 28; + grub_dprintf ("ohci", "OHCI errcode=0x%02x\n", errcode); switch (errcode) { @@ -540,11 +702,17 @@ grub_ohci_transfer (grub_usb_controller_t dev, case 8: /* XXX: Data overrun error. */ err = GRUB_USB_ERR_DATA; + j = ((grub_uint32_t)tderr - (grub_uint32_t)td_list) / sizeof (*td_list); + grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n", tderr, j); break; case 9: /* XXX: Data underrun error. */ err = GRUB_USB_ERR_DATA; + grub_dprintf ("ohci", "Underrun, number of not transferred bytes: %d\n", + 1 + grub_le_to_cpu32 (tderr->buffer_end) - grub_le_to_cpu32 (tderr->buffer)); + j = ((grub_uint32_t)tderr - (grub_uint32_t)td_list) / sizeof (*td_list); + grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n", tderr, j); break; case 10: @@ -582,43 +750,73 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Clear BulkListFilled and ControlListFilled. */ status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); - status &= ~((1 << 2) | (1 << 3)); + status &= ~(3 << 1); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); - - /* XXX */ + + /* Set ED to be skipped - for safety */ + ed->target |= grub_cpu_to_le32 (1 << 14); + + /* Now we should wait for start of next frame. + * It is necessary because we will invalidate pointer to ED and it + * can be on OHCI active till SOF! + * Because we are not using interrupt, we reset SF bit and wait when + * it goes to 1. */ + /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); + /* Wait for new SOF */ + while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); + /* Now it should be safe to change CONTROL and BULK lists. */ + + /* Important cleaning. */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + + grub_dprintf ("ohci", "OHCI finished, freeing, err=0x%02x\n", err); + grub_dma_free (td_list_chunk); grub_dma_free (ed_chunk); return err; } +#define GRUB_OHCI_SET_PORT_ENABLE (1 << 1) +#define GRUB_OHCI_CLEAR_PORT_ENABLE (1 << 0) +#define GRUB_OHCI_SET_PORT_RESET (1 << 4) +#define GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE (1 << 20) + static grub_err_t grub_ohci_portstatus (grub_usb_controller_t dev, unsigned int port, unsigned int enable) { struct grub_ohci *o = (struct grub_ohci *) dev->data; - grub_uint32_t status; - /* Reset the port. */ - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); - status |= (1 << 4); /* XXX: Magic. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status); - grub_millisleep (100); + grub_dprintf ("ohci", "begin of portstatus=0x%02x\n", + grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)); - /* End the reset signaling. */ - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); - status |= (1 << 20); /* XXX: Magic. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_SET_PORT_RESET); + grub_millisleep (50); /* For root hub should be nominaly 50ms */ + + /* End the reset signaling. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE); grub_millisleep (10); - /* Enable the port. */ - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); - status |= (enable << 1); /* XXX: Magic. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status); - - status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); - grub_dprintf ("ohci", "portstatus=0x%02x\n", status); + if (enable) + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_SET_PORT_ENABLE); + else + grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, + GRUB_OHCI_CLEAR_PORT_ENABLE); + grub_millisleep (10); + grub_dprintf ("ohci", "end of portstatus=0x%02x\n", + grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port)); + return GRUB_ERR_NONE; } diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 6e47c38ef..eb533c926 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -174,14 +174,15 @@ grub_uhci_pci_iter (grub_pci_device_t dev, return 1; u->iobase = base & GRUB_UHCI_IOMASK; - grub_dprintf ("uhci", "class=0x%02x 0x%02x interface 0x%02x base=0x%x\n", - class, subclass, interf, u->iobase); /* Reserve a page for the frame list. */ u->framelist = grub_memalign (4096, 4096); if (! u->framelist) goto fail; + grub_dprintf ("uhci", "class=0x%02x 0x%02x interface 0x%02x base=0x%x framelist=%p\n", + class, subclass, interf, u->iobase, u->framelist); + /* The framelist pointer of UHCI is only 32 bits, make sure this code works on on 64 bits architectures. */ #if GRUB_CPU_SIZEOF_VOID_P == 8 @@ -221,6 +222,9 @@ grub_uhci_pci_iter (grub_pci_device_t dev, } #endif + grub_dprintf ("uhci", "QH=%p, TD=%p\n", + u->qh, u->td); + /* Link all Transfer Descriptors in a list of available Transfer Descriptors. */ for (i = 0; i < 256; i++) @@ -441,6 +445,8 @@ grub_uhci_transfer (grub_usb_controller_t dev, if (! qh) return grub_errno; + grub_dprintf ("uhci", "transfer, iobase:%08x\n", u->iobase); + for (i = 0; i < transfer->transcnt; i++) { grub_usb_transaction_t tr = &transfer->transactions[i]; @@ -548,7 +554,8 @@ grub_uhci_transfer (grub_usb_controller_t dev, fail: - grub_dprintf ("uhci", "transaction failed\n"); + if (err != GRUB_USB_ERR_NONE) + grub_dprintf ("uhci", "transaction failed\n"); /* Place the QH back in the free list and deallocate the associated TDs. */ @@ -583,6 +590,8 @@ grub_uhci_portstatus (grub_usb_controller_t dev, unsigned int status; grub_uint64_t endtime; + grub_dprintf ("uhci", "portstatus, iobase:%08x\n", u->iobase); + grub_dprintf ("uhci", "enable=%d port=%d\n", enable, port); if (port == 0) @@ -631,6 +640,8 @@ grub_uhci_detect_dev (grub_usb_controller_t dev, int port) int reg; unsigned int status; + grub_dprintf ("uhci", "detect_dev, iobase:%08x\n", u->iobase); + if (port == 0) reg = GRUB_UHCI_REG_PORTSC1; else if (port == 1) diff --git a/bus/usb/usb.c b/bus/usb/usb.c index 8289185da..7df148333 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -107,7 +107,7 @@ grub_usb_set_configuration (grub_usb_device_t dev, int configuration) { int i; - for (i = 0; i < 16; i++) + for (i = 0; i < 256; i++) dev->toggle[i] = 0; return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT @@ -163,6 +163,16 @@ grub_usb_device_initialize (grub_usb_device_t dev) grub_usb_err_t err; int i; + /* First we have to read first 8 bytes only and determine + * max. size of packet */ + dev->descdev.maxsize0 = 0; /* invalidating, for safety only, can be removed if it is sure it is zero here */ + err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE, + 0, 8, (char *) &dev->descdev); + if (err) + return err; + + /* Now we have valid value in dev->descdev.maxsize0, + * so we can read whole device descriptor */ err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE, 0, sizeof (struct grub_usb_desc_device), (char *) &dev->descdev); diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index f6d3d30f9..0bf5ee6de 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -138,7 +138,7 @@ grub_usb_control_msg (grub_usb_device_t dev, /* End with an empty OUT transaction. */ transfer->transactions[datablocks + 1].size = 0; transfer->transactions[datablocks + 1].data = 0; - if (reqtype & 128) + if ((reqtype & 128) && datablocks) transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT; else transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_IN; @@ -148,6 +148,7 @@ grub_usb_control_msg (grub_usb_device_t dev, err = dev->controller.dev->transfer (&dev->controller, transfer); grub_free (transfer->transactions); + grub_free (transfer); grub_dma_free (data_chunk); grub_dma_free (setupdata_chunk); @@ -207,7 +208,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, datablocks = ((size + max - 1) / max); transfer->transcnt = datablocks; transfer->size = size - 1; - transfer->endpoint = endpoint; + transfer->endpoint = endpoint & 15; transfer->devaddr = dev->addr; transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK; transfer->max = max; diff --git a/commands/usbtest.c b/commands/usbtest.c index 191c4e4df..7d1f85cfd 100644 --- a/commands/usbtest.c +++ b/commands/usbtest.c @@ -148,6 +148,8 @@ usb_iterate (grub_usb_device_t dev) grub_printf ("%s speed device\n", usb_devspeed[dev->speed]); + return 0; + for (i = 0; i < descdev->configcnt; i++) { struct grub_usb_desc_config *config; diff --git a/disk/scsi.c b/disk/scsi.c index eba237287..e8bfb6a3f 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -25,6 +25,7 @@ #include #include #include +#include static grub_scsi_dev_t grub_scsi_dev_list; @@ -50,7 +51,62 @@ grub_scsi_dev_unregister (grub_scsi_dev_t dev) } -/* Determine the the device is removable and the type of the device +/* Check result of previous operation. */ +static grub_err_t +grub_scsi_request_sense (grub_scsi_t scsi) +{ + struct grub_scsi_request_sense rs; + struct grub_scsi_request_sense_data rsd; + grub_err_t err; + + rs.opcode = grub_scsi_cmd_request_sense; + rs.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + rs.reserved1 = 0; + rs.reserved2 = 0; + rs.alloc_length = 0x12; /* XXX: Hardcoded for now */ + rs.control = 0; + grub_memset (rs.pad, 0, sizeof(rs.pad)); + + err = scsi->dev->read (scsi, sizeof (rs), (char *) &rs, + sizeof (rsd), (char *) &rsd); + if (err) + return err; + + return GRUB_ERR_NONE; +} +/* Self commenting... */ +static grub_err_t +grub_scsi_test_unit_ready (grub_scsi_t scsi) +{ + struct grub_scsi_test_unit_ready tur; + grub_err_t err; + grub_err_t err_sense; + + tur.opcode = grub_scsi_cmd_test_unit_ready; + tur.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + tur.reserved1 = 0; + tur.reserved2 = 0; + tur.reserved3 = 0; + tur.control = 0; + grub_memset (tur.pad, 0, sizeof(tur.pad)); + + err = scsi->dev->read (scsi, sizeof (tur), (char *) &tur, + 0, NULL); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + if (err) + return err; + + return GRUB_ERR_NONE; +} + +/* Determine if the device is removable and the type of the device SCSI. */ static grub_err_t grub_scsi_inquiry (grub_scsi_t scsi) @@ -58,15 +114,26 @@ grub_scsi_inquiry (grub_scsi_t scsi) struct grub_scsi_inquiry iq; struct grub_scsi_inquiry_data iqd; grub_err_t err; + grub_err_t err_sense; iq.opcode = grub_scsi_cmd_inquiry; iq.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + iq.page = 0; iq.reserved = 0; iq.alloc_length = 0x24; /* XXX: Hardcoded for now */ - iq.reserved2 = 0; + iq.control = 0; + grub_memset (iq.pad, 0, sizeof(iq.pad)); err = scsi->dev->read (scsi, sizeof (iq), (char *) &iq, sizeof (iqd), (char *) &iqd); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + if (err) return err; @@ -83,13 +150,27 @@ grub_scsi_read_capacity (grub_scsi_t scsi) struct grub_scsi_read_capacity rc; struct grub_scsi_read_capacity_data rcd; grub_err_t err; + grub_err_t err_sense; rc.opcode = grub_scsi_cmd_read_capacity; rc.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; - grub_memset (rc.reserved, 0, sizeof (rc.reserved)); - + rc.logical_block_addr = 0; + rc.reserved1 = 0; + rc.reserved2 = 0; + rc.PMI = 0; + rc.control = 0; + rc.pad = 0; + err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc, sizeof (rcd), (char *) &rcd); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; +/* err_sense is ignored for now and Request Sense Data also... */ + if (err) return err; @@ -107,6 +188,8 @@ grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector, { grub_scsi_t scsi; struct grub_scsi_read10 rd; + grub_err_t err; + grub_err_t err_sense; scsi = disk->data; @@ -118,7 +201,16 @@ grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector, rd.reserved2 = 0; rd.pad = 0; - return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); + err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + return err; } /* Send a SCSI request for DISK: read SIZE sectors starting with @@ -129,6 +221,8 @@ grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector, { grub_scsi_t scsi; struct grub_scsi_read12 rd; + grub_err_t err; + grub_err_t err_sense; scsi = disk->data; @@ -139,7 +233,16 @@ grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector, rd.reserved = 0; rd.control = 0; - return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); + err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + return err; } #if 0 @@ -151,6 +254,8 @@ grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector, { grub_scsi_t scsi; struct grub_scsi_write10 wr; + grub_err_t err; + grub_err_t err_sense; scsi = disk->data; @@ -162,7 +267,16 @@ grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector, wr.reserved2 = 0; wr.pad = 0; - return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); + err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + return err; } /* Send a SCSI request for DISK: write the data stored in BUF to SIZE @@ -172,7 +286,9 @@ grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t size, char *buf) { grub_scsi_t scsi; - struct grub_scsi_write10 wr; + struct grub_scsi_write12 wr; + grub_err_t err; + grub_err_t err_sense; scsi = disk->data; @@ -181,9 +297,18 @@ grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector, wr.lba = grub_cpu_to_be32 (sector); wr.size = grub_cpu_to_be32 (size); wr.reserved = 0; - wr.pad = 0; + wr.control = 0; - return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); + err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); + + /* Each SCSI command should be followed by Request Sense. + If not so, many devices STALLs or definitely freezes. */ + err_sense = grub_scsi_request_sense (scsi); + if (err_sense != GRUB_ERR_NONE) + grub_errno = err; + /* err_sense is ignored for now and Request Sense Data also... */ + + return err; } #endif @@ -235,6 +360,7 @@ grub_scsi_open (const char *name, grub_disk_t disk) grub_err_t err; int len; int lun; + grub_uint64_t maxtime; scsi = grub_malloc (sizeof (*scsi)); if (! scsi) @@ -292,6 +418,31 @@ grub_scsi_open (const char *name, grub_disk_t disk) else disk->has_partitions = 1; + + /* According to USB MS tests specification, issue Test Unit Ready + * until OK */ + maxtime = grub_get_time_ms () + 1000; + do + { + /* Timeout is necessary - for example in case when we have + * universal card reader with more LUNs and we have only + * one card inserted (or none), so only one LUN (or none) + * will be ready - and we want not to hang... */ + if (grub_get_time_ms () > maxtime) + { + err = GRUB_ERR_READ_ERROR; + grub_free (scsi); + grub_dprintf ("scsi", "LUN is not ready - timeout\n"); + return err; + } + err = grub_scsi_test_unit_ready (scsi); + } + while (err == GRUB_ERR_READ_ERROR); + /* Reset grub_errno ! + * It is set to some error code in loop before... */ + grub_errno = GRUB_ERR_NONE; + + /* Read capacity of media */ err = grub_scsi_read_capacity (scsi); if (err) { @@ -302,12 +453,14 @@ grub_scsi_open (const char *name, grub_disk_t disk) /* SCSI blocks can be something else than 512, although GRUB wants 512 byte blocks. */ - disk->total_sectors = ((scsi->size * scsi->blocksize) - << GRUB_DISK_SECTOR_BITS); + disk->total_sectors = ((grub_uint64_t)scsi->size + * (grub_uint64_t)scsi->blocksize) + >> GRUB_DISK_SECTOR_BITS; - grub_dprintf ("scsi", "capacity=%llu, blksize=%d\n", - (unsigned long long) disk->total_sectors, - scsi->blocksize); + grub_dprintf ("scsi", "blocks=%u, blocksize=%u\n", + scsi->size, scsi->blocksize); + grub_dprintf ("scsi", "Disk total 512 sectors = %llu\n", + disk->total_sectors); return GRUB_ERR_NONE; } diff --git a/disk/usbms.c b/disk/usbms.c index 8554b224f..7b719fb84 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -84,7 +84,8 @@ grub_usbms_finddevs (void) struct grub_usb_desc_device *descdev = &usbdev->descdev; int i; - if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0) + if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0 + || descdev->configcnt == 0) return 0; /* XXX: Just check configuration 0 for now. */ @@ -93,19 +94,31 @@ grub_usbms_finddevs (void) struct grub_usbms_dev *usbms; struct grub_usb_desc_if *interf; int j; - grub_uint8_t luns; + grub_uint8_t luns = 0; + + grub_dprintf ("usbms", "alive\n"); interf = usbdev->config[0].interf[i].descif; /* If this is not a USB Mass Storage device with a supported protocol, just skip it. */ + grub_dprintf ("usbms", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n", + i, interf->class, interf->subclass, interf->protocol); + if (interf->class != GRUB_USB_CLASS_MASS_STORAGE - || interf->subclass != GRUB_USBMS_SUBCLASS_BULK + || ( interf->subclass != GRUB_USBMS_SUBCLASS_BULK && + /* Experimental support of RBC, MMC-2, UFI, SFF-8070i devices */ + interf->subclass != GRUB_USBMS_SUBCLASS_RBC && + interf->subclass != GRUB_USBMS_SUBCLASS_MMC2 && + interf->subclass != GRUB_USBMS_SUBCLASS_UFI && + interf->subclass != GRUB_USBMS_SUBCLASS_SFF8070 ) || interf->protocol != GRUB_USBMS_PROTOCOL_BULK) { continue; } + grub_dprintf ("usbms", "alive\n"); + devcnt++; usbms = grub_zalloc (sizeof (struct grub_usbms_dev)); if (! usbms) @@ -114,6 +127,8 @@ grub_usbms_finddevs (void) usbms->dev = usbdev; usbms->interface = i; + grub_dprintf ("usbms", "alive\n"); + /* Iterate over all endpoints of this interface, at least a IN and OUT bulk endpoint are required. */ for (j = 0; j < interf->endpointcnt; j++) @@ -125,14 +140,16 @@ grub_usbms_finddevs (void) { /* Bulk IN endpoint. */ usbms->in = endp; - grub_usb_clear_halt (usbdev, endp->endp_addr & 128); + /* Clear Halt is not possible yet! */ + /* grub_usb_clear_halt (usbdev, endp->endp_addr); */ usbms->in_maxsz = endp->maxpacket; } else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2) { /* Bulk OUT endpoint. */ usbms->out = endp; - grub_usb_clear_halt (usbdev, endp->endp_addr & 128); + /* Clear Halt is not possible yet! */ + /* grub_usb_clear_halt (usbdev, endp->endp_addr); */ usbms->out_maxsz = endp->maxpacket; } } @@ -143,51 +160,63 @@ grub_usbms_finddevs (void) return 0; } + grub_dprintf ("usbms", "alive\n"); + + /* XXX: Activate the first configuration. */ + grub_usb_set_configuration (usbdev, 1); + /* Query the amount of LUNs. */ err = grub_usb_control_msg (usbdev, 0xA1, 254, 0, i, 1, (char *) &luns); + if (err) { /* In case of a stall, clear the stall. */ if (err == GRUB_USB_ERR_STALL) { - grub_usb_clear_halt (usbdev, usbms->in->endp_addr & 3); - grub_usb_clear_halt (usbdev, usbms->out->endp_addr & 3); + grub_usb_clear_halt (usbdev, usbms->in->endp_addr); + grub_usb_clear_halt (usbdev, usbms->out->endp_addr); } - /* Just set the amount of LUNs to one. */ grub_errno = GRUB_ERR_NONE; usbms->luns = 1; } else - usbms->luns = luns; + /* luns = 0 means one LUN with ID 0 present ! */ + /* We get from device not number of LUNs but highest + * LUN number. LUNs are numbered from 0, + * i.e. number of LUNs is luns+1 ! */ + usbms->luns = luns + 1; - /* XXX: Check the magic values, does this really make - sense? */ - grub_usb_control_msg (usbdev, (1 << 6) | 1, 255, - 0, i, 0, 0); - - /* XXX: To make Qemu work? */ - if (usbms->luns == 0) - usbms->luns = 1; + grub_dprintf ("usbms", "alive\n"); usbms->next = grub_usbms_dev_list; grub_usbms_dev_list = usbms; - /* XXX: Activate the first configuration. */ - grub_usb_set_configuration (usbdev, 1); - +#if 0 /* All this part should be probably deleted. + * This make trouble on some devices if they are not in + * Phase Error state - and there they should be not in such state... + * Bulk only mass storage reset procedure should be used only + * on place and in time when it is really necessary. */ + /* Reset recovery procedure */ /* Bulk-Only Mass Storage Reset, after the reset commands will be accepted. */ grub_usbms_reset (usbdev, i); + grub_usb_clear_halt (usbdev, usbms->in->endp_addr); + grub_usb_clear_halt (usbdev, usbms->out->endp_addr); +#endif return 0; } + grub_dprintf ("usbms", "alive\n"); return 0; } + grub_dprintf ("usbms", "alive\n"); grub_usb_iterate (usb_iterate); + grub_dprintf ("usbms", "alive\n"); + } @@ -225,6 +254,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, static grub_uint32_t tag = 0; grub_usb_err_t err = GRUB_USB_ERR_NONE; int retrycnt = 3 + 1; + grub_size_t i; retry: retrycnt--; @@ -237,73 +267,89 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, cbw.tag = tag++; cbw.transfer_length = grub_cpu_to_le32 (size); cbw.flags = (!read_write) << GRUB_USBMS_DIRECTION_BIT; - cbw.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; + cbw.lun = scsi->lun; /* In USB MS CBW are LUN bits on another place than in SCSI CDB, both should be set correctly. */ cbw.length = cmdsize; grub_memcpy (cbw.cbwcb, cmd, cmdsize); + + /* Debug print of CBW content. */ + grub_dprintf ("usb", "CBW: sign=0x%08x tag=0x%08x len=0x%08x\n", + cbw.signature, cbw.tag, cbw.transfer_length); + grub_dprintf ("usb", "CBW: flags=0x%02x lun=0x%02x CB_len=0x%02x\n", + cbw.flags, cbw.lun, cbw.length); + grub_dprintf ("usb", "CBW: cmd:\n %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", + cbw.cbwcb[ 0], cbw.cbwcb[ 1], cbw.cbwcb[ 2], cbw.cbwcb[ 3], + cbw.cbwcb[ 4], cbw.cbwcb[ 5], cbw.cbwcb[ 6], cbw.cbwcb[ 7], + cbw.cbwcb[ 8], cbw.cbwcb[ 9], cbw.cbwcb[10], cbw.cbwcb[11], + cbw.cbwcb[12], cbw.cbwcb[13], cbw.cbwcb[14], cbw.cbwcb[15]); - /* Write the request. */ - err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr & 15, + /* Write the request. + * XXX: Error recovery is maybe still not fully correct. */ + err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, sizeof (cbw), (char *) &cbw); if (err) { if (err == GRUB_USB_ERR_STALL) { + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); grub_usb_clear_halt (dev->dev, dev->out->endp_addr); goto retry; } return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed"); } - /* Read/write the data. */ - if (read_write == 0) + /* Read/write the data, (maybe) according to specification. */ + if (size && (read_write == 0)) { - err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15, size, buf); - grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL); - if (err) - { - if (err == GRUB_USB_ERR_STALL) - { - grub_usb_clear_halt (dev->dev, dev->in->endp_addr); - goto retry; - } - return grub_error (GRUB_ERR_READ_ERROR, - "can't read from USB Mass Storage device"); - } + err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, size, buf); + grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL); + if (err) goto CheckCSW; + /* Debug print of received data. */ + grub_dprintf ("usb", "buf:\n"); + if (size <= 64) + for (i=0; idev, dev->in->endp_addr & 15, size, buf); + err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, size, buf); grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL); - if (err) - { - if (err == GRUB_USB_ERR_STALL) - { - grub_usb_clear_halt (dev->dev, dev->out->endp_addr); - goto retry; - } - return grub_error (GRUB_ERR_WRITE_ERROR, - "can't write to USB Mass Storage device"); - } + grub_dprintf ("usb", "buf:\n"); + /* Debug print of sent data. */ + if (size <= 256) + for (i=0; idev, dev->in->endp_addr & 15, - sizeof (status), (char *) &status); + /* Read the status - (maybe) according to specification. */ +CheckCSW: + err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, + sizeof (status), (char *) &status); if (err) { - if (err == GRUB_USB_ERR_STALL) - { - grub_usb_clear_halt (dev->dev, dev->in->endp_addr); + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); + err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, + sizeof (status), (char *) &status); + if (err) + { /* Bulk-only reset device. */ + grub_usbms_reset (dev->dev, dev->interface); + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); + grub_usb_clear_halt (dev->dev, dev->out->endp_addr); goto retry; - } - return grub_error (GRUB_ERR_READ_ERROR, - "can't read status from USB Mass Storage device"); + } } - /* XXX: Magic and check this code. */ + /* Debug print of CSW content. */ + grub_dprintf ("usb", "CSW: sign=0x%08x tag=0x%08x resid=0x%08x\n", + status.signature, status.tag, status.residue); + grub_dprintf ("usb", "CSW: status=0x%02x\n", status.status); + + /* If phase error, do bulk-only reset device. */ if (status.status == 2) { - /* XXX: Phase error, reset device. */ grub_usbms_reset (dev->dev, dev->interface); grub_usb_clear_halt (dev->dev, dev->in->endp_addr); grub_usb_clear_halt (dev->dev, dev->out->endp_addr); diff --git a/include/grub/scsicmd.h b/include/grub/scsicmd.h index 40f237a17..f9a7cb200 100644 --- a/include/grub/scsicmd.h +++ b/include/grub/scsicmd.h @@ -25,14 +25,26 @@ #define GRUB_SCSI_REMOVABLE_BIT 7 #define GRUB_SCSI_LUN_SHIFT 5 +struct grub_scsi_test_unit_ready +{ + grub_uint8_t opcode; + grub_uint8_t lun; /* 7-5 LUN, 4-0 reserved */ + grub_uint8_t reserved1; + grub_uint8_t reserved2; + grub_uint8_t reserved3; + grub_uint8_t control; + grub_uint8_t pad[6]; /* To be ATAPI compatible */ +} __attribute__((packed)); + struct grub_scsi_inquiry { grub_uint8_t opcode; - grub_uint8_t lun; - grub_uint16_t reserved; - grub_uint16_t alloc_length; - grub_uint8_t reserved2; - grub_uint8_t pad[5]; + grub_uint8_t lun; /* 7-5 LUN, 4-1 reserved, 0 EVPD */ + grub_uint8_t page; /* page code if EVPD=1 */ + grub_uint8_t reserved; + grub_uint8_t alloc_length; + grub_uint8_t control; + grub_uint8_t pad[6]; /* To be ATAPI compatible */ } __attribute__((packed)); struct grub_scsi_inquiry_data @@ -47,12 +59,42 @@ struct grub_scsi_inquiry_data char prodrev[4]; } __attribute__((packed)); +struct grub_scsi_request_sense +{ + grub_uint8_t opcode; + grub_uint8_t lun; /* 7-5 LUN, 4-0 reserved */ + grub_uint8_t reserved1; + grub_uint8_t reserved2; + grub_uint8_t alloc_length; + grub_uint8_t control; + grub_uint8_t pad[6]; /* To be ATAPI compatible */ +} __attribute__((packed)); + +struct grub_scsi_request_sense_data +{ + grub_uint8_t error_code; /* 7 Valid, 6-0 Err. code */ + grub_uint8_t segment_number; + grub_uint8_t sense_key; /*7 FileMark, 6 EndOfMedia, 5 ILI, 4-0 sense key */ + grub_uint32_t information; + grub_uint8_t additional_sense_length; + grub_uint32_t cmd_specific_info; + grub_uint8_t additional_sense_code; + grub_uint8_t additional_sense_code_qualifier; + grub_uint8_t field_replaceable_unit_code; + grub_uint8_t sense_key_specific[3]; + /* there can be additional sense field */ +} __attribute__((packed)); + struct grub_scsi_read_capacity { grub_uint8_t opcode; - grub_uint8_t lun; - grub_uint8_t reserved[8]; - grub_uint8_t pad[2]; + grub_uint8_t lun; /* 7-5 LUN, 4-1 reserved, 0 reserved */ + grub_uint32_t logical_block_addr; /* only if PMI=1 */ + grub_uint8_t reserved1; + grub_uint8_t reserved2; + grub_uint8_t PMI; + grub_uint8_t control; + grub_uint16_t pad; /* To be ATAPI compatible */ } __attribute__((packed)); struct grub_scsi_read_capacity_data @@ -106,11 +148,13 @@ struct grub_scsi_write12 typedef enum { grub_scsi_cmd_inquiry = 0x12, + grub_scsi_cmd_test_unit_ready = 0x00, grub_scsi_cmd_read_capacity = 0x25, grub_scsi_cmd_read10 = 0x28, grub_scsi_cmd_write10 = 0x2a, grub_scsi_cmd_read12 = 0xa8, - grub_scsi_cmd_write12 = 0xaa + grub_scsi_cmd_write12 = 0xaa, + grub_scsi_cmd_request_sense = 0x03 } grub_scsi_cmd_t; typedef enum diff --git a/include/grub/usb.h b/include/grub/usb.h index dc90e7879..cbbc39303 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -156,7 +156,7 @@ struct grub_usb_device int initialized; /* Data toggle values (used for bulk transfers only). */ - int toggle[16]; + int toggle[256]; /* Device-specific data. */ void *data; @@ -184,7 +184,12 @@ typedef enum typedef enum { - GRUB_USBMS_SUBCLASS_BULK = 0x06 + GRUB_USBMS_SUBCLASS_BULK = 0x06, + /* Experimental support for non-pure SCSI devices */ + GRUB_USBMS_SUBCLASS_RBC = 0x01, + GRUB_USBMS_SUBCLASS_MMC2 = 0x02, + GRUB_USBMS_SUBCLASS_UFI = 0x04, + GRUB_USBMS_SUBCLASS_SFF8070 = 0x05 } grub_usbms_subclass_t; typedef enum diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index 8c739684e..cd818e1fc 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -86,9 +86,9 @@ typedef struct grub_usb_transfer *grub_usb_transfer_t; #define GRUB_USB_REQ_HUB_GET_PORT_STATUS 0x00 -#define GRUB_USB_FEATURE_ENDP_HALT 0x01 -#define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x02 -#define GRUB_USB_FEATURE_TEST_MODE 0x04 +#define GRUB_USB_FEATURE_ENDP_HALT 0x00 +#define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x01 +#define GRUB_USB_FEATURE_TEST_MODE 0x02 #define GRUB_USB_HUB_STATUS_CONNECTED (1 << 0) #define GRUB_USB_HUB_STATUS_LOWSPEED (1 << 9) From c837af3f38882470ea30d4392427d17c5132cdea Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 20:23:51 +0200 Subject: [PATCH 44/96] * loader/multiboot_elfxx.c (grub_multiboot_load_elfXX) [__mips]: Check 64-bit address as signed on MIPS. --- ChangeLog | 5 +++++ loader/multiboot_elfxx.c | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5072a6026..c6edd3ac3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-31 Vladimir Serbinenko + + * loader/multiboot_elfxx.c (grub_multiboot_load_elfXX) [__mips]: Check + 64-bit address as signed on MIPS. + 2010-05-28 Colin Watson * configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not diff --git a/loader/multiboot_elfxx.c b/loader/multiboot_elfxx.c index 92a52d3a8..78b7c542c 100644 --- a/loader/multiboot_elfxx.c +++ b/loader/multiboot_elfxx.c @@ -74,7 +74,11 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer) if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH) return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset"); -#ifdef MULTIBOOT_LOAD_ELF64 +#if defined (MULTIBOOT_LOAD_ELF64) && defined (__mips) + /* We still in 32-bit mode. */ + if (ehdr->e_entry < 0xffffffff80000000ULL) + return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64"); +#else /* We still in 32-bit mode. */ if (ehdr->e_entry > 0xffffffff) return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64"); From 7620e7debd2a54cb29bab9f74c49f45ec76dcf9d Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 20:40:42 +0200 Subject: [PATCH 45/96] * commands/setpci.c (grub_setpci_iter): Fix an incorrect function check. Reported by: Seth Goldberg. --- ChangeLog | 5 +++++ commands/setpci.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c6edd3ac3..5bbb1c12f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-31 Vladimir Serbinenko + + * commands/setpci.c (grub_setpci_iter): Fix an incorrect function check. + Reported by: Seth Goldberg. + 2010-05-31 Vladimir Serbinenko * loader/multiboot_elfxx.c (grub_multiboot_load_elfXX) [__mips]: Check diff --git a/commands/setpci.c b/commands/setpci.c index fbc7c214e..aa09f5bbb 100644 --- a/commands/setpci.c +++ b/commands/setpci.c @@ -96,7 +96,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid) if (check_device && grub_pci_get_device (dev) != device) return 0; - if (check_function && grub_pci_get_function (dev) != device) + if (check_function && grub_pci_get_function (dev) != function) return 0; addr = grub_pci_make_address (dev, regaddr); From 5629316656a33304ac15364bf09b6f1d6800b447 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 20:43:28 +0200 Subject: [PATCH 46/96] * loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix incorrect addition of dest. Reported by: Seth Goldberg. --- ChangeLog | 6 ++++++ loader/multiboot_mbi2.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5bbb1c12f..aa9363dd7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-31 Vladimir Serbinenko + + * loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix incorrect + addition of dest. + Reported by: Seth Goldberg. + 2010-05-31 Vladimir Serbinenko * commands/setpci.c (grub_setpci_iter): Fix an incorrect function check. diff --git a/loader/multiboot_mbi2.c b/loader/multiboot_mbi2.c index 7e9cebe49..c9e52e51f 100644 --- a/loader/multiboot_mbi2.c +++ b/loader/multiboot_mbi2.c @@ -496,7 +496,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off, = (struct multiboot_tag_module *) ptrorig; tag->type = MULTIBOOT_TAG_TYPE_MODULE; tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size; - tag->mod_start = dest + cur->start; + tag->mod_start = cur->start; tag->mod_end = tag->mod_start + cur->size; grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size); ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); From c2ffc8e956be5df59fd2fa96c4102e02a78f1799 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 20:46:16 +0200 Subject: [PATCH 47/96] * normal/main.c (grub_normal_add_menu_entry): Avoid going out of args. Reported by: Seth Goldberg. --- ChangeLog | 5 +++++ normal/main.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index aa9363dd7..2d9015cfb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-05-31 Vladimir Serbinenko + + * normal/main.c (grub_normal_add_menu_entry): Avoid going out of args. + Reported by: Seth Goldberg. + 2010-05-31 Vladimir Serbinenko * loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix incorrect diff --git a/normal/main.c b/normal/main.c index 4ed17e82c..14a25032f 100644 --- a/normal/main.c +++ b/normal/main.c @@ -204,7 +204,7 @@ grub_normal_add_menu_entry (int argc, const char **args, for (i = 0; i < argc; i++) { /* Capture arguments. */ - if (grub_strncmp ("--", args[i], 2) == 0) + if (grub_strncmp ("--", args[i], 2) == 0 && i + 1 < argc) { const char *arg = &args[i][2]; From dfbfe00473ad0edb62cc3d0958949578d4a8ecd3 Mon Sep 17 00:00:00 2001 From: Jiro SEKIBA Date: Mon, 31 May 2010 20:49:42 +0200 Subject: [PATCH 48/96] * include/grub/disk.h (GRUB_DISK_SIZE_UNKNOWN): New macro. * fs/nilfs.c: Support 2nd super block in case 1st one is accidently corrupted or not synced properly. --- ChangeLog | 6 ++++ fs/nilfs2.c | 67 +++++++++++++++++++++++++++++++++++++-------- include/grub/disk.h | 3 ++ 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2d9015cfb..a35843554 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-31 Jiro SEKIBA + + * include/grub/disk.h (GRUB_DISK_SIZE_UNKNOWN): New macro. + * fs/nilfs.c: Support 2nd super block in case 1st one is accidently + corrupted or not synced properly. + 2010-05-31 Vladimir Serbinenko * normal/main.c (grub_normal_add_menu_entry): Avoid going out of args. diff --git a/fs/nilfs2.c b/fs/nilfs2.c index 7e0415d12..5d32f5f88 100644 --- a/fs/nilfs2.c +++ b/fs/nilfs2.c @@ -49,6 +49,13 @@ #define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1) #define NILFS_BTREE_LEVEL_MAX 14 +/* nilfs 1st super block posission from beginning of the partition + in 512 block size */ +#define NILFS_1ST_SUPER_BLOCK 2 +/* nilfs 2nd super block posission from end of the partition + in 512 block size */ +#define NILFS_2ND_SUPER_BLOCK 8 + struct grub_nilfs2_inode { grub_uint64_t i_blocks; @@ -703,6 +710,52 @@ grub_nilfs2_valid_sb (struct grub_nilfs2_super_block *sbp) return 1; } +static grub_err_t +grub_nilfs2_load_sb (struct grub_nilfs2_data *data) +{ + grub_disk_t disk = data->disk; + struct grub_nilfs2_super_block sb2; + grub_uint64_t partition_size; + int valid[2]; + int swp = 0; + + /* Read first super block. */ + grub_disk_read (disk, NILFS_1ST_SUPER_BLOCK, 0, + sizeof (struct grub_nilfs2_super_block), &data->sblock); + /* Make sure if 1st super block is valid. */ + valid[0] = grub_nilfs2_valid_sb (&data->sblock); + + partition_size = grub_disk_get_size (disk); + if (partition_size != GRUB_DISK_SIZE_UNKNOWN) + { + /* Read second super block. */ + grub_disk_read (disk, partition_size - NILFS_2ND_SUPER_BLOCK, 0, + sizeof (struct grub_nilfs2_super_block), &sb2); + /* Make sure if 2nd super block is valid. */ + valid[1] = grub_nilfs2_valid_sb (&sb2); + } + else + /* 2nd super block may not exist, so it's invalid. */ + valid[1] = 0; + + + + if (!valid[0] && !valid[1]) + return grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); + + swp = valid[1] && (!valid[0] || + grub_le_to_cpu64 (data->sblock.s_last_cno) < + grub_le_to_cpu64 (sb2.s_last_cno)); + + /* swap if first super block is invalid or older than second one. */ + if (swp) + grub_memcpy (&data->sblock, &sb2, + sizeof (struct grub_nilfs2_super_block)); + + grub_errno = GRUB_ERR_NONE; + return grub_errno; +} + static struct grub_nilfs2_data * grub_nilfs2_mount (grub_disk_t disk) { @@ -717,19 +770,13 @@ grub_nilfs2_mount (grub_disk_t disk) if (!data) return 0; + data->disk = disk; + /* Read the superblock. */ - grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block), - &data->sblock); + grub_nilfs2_load_sb (data); if (grub_errno) goto fail; - /* Make sure this is an nilfs2 filesystem. */ - if (!grub_nilfs2_valid_sb (&data->sblock)) - { - grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); - goto fail; - } - nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); /* Read the last segment summary. */ @@ -748,8 +795,6 @@ grub_nilfs2_mount (grub_disk_t disk) if (grub_errno) goto fail; - data->disk = disk; - grub_nilfs2_read_last_checkpoint (data, &last_checkpoint); if (grub_errno) diff --git a/include/grub/disk.h b/include/grub/disk.h index e60b1f3de..e7f807e0e 100644 --- a/include/grub/disk.h +++ b/include/grub/disk.h @@ -138,6 +138,9 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t; #define GRUB_DISK_CACHE_SIZE 8 #define GRUB_DISK_CACHE_BITS 3 +/* Return value of grub_disk_get_size() in case disk size is unknown. */ +#define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL + /* This is called from the memory manager. */ void grub_disk_cache_invalidate_all (void); From b1d17e10e031a9d3dbbfb2e227509cf8137015bf Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Mon, 31 May 2010 21:01:01 +0200 Subject: [PATCH 49/96] * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Use GRUB_DISK_SIZE_UNKNOWN. * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Likewise. --- ChangeLog | 6 ++++++ disk/i386/pc/biosdisk.c | 3 ++- disk/ieee1275/ofdisk.c | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a35843554..c388ebd27 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-05-31 Vladimir Serbinenko + + * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Use + GRUB_DISK_SIZE_UNKNOWN. + * disk/ieee1275/ofdisk.c (grub_ofdisk_open): Likewise. + 2010-05-31 Jiro SEKIBA * include/grub/disk.h (GRUB_DISK_SIZE_UNKNOWN): New macro. diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c index 94d0e3708..f82f91ff0 100644 --- a/disk/i386/pc/biosdisk.c +++ b/disk/i386/pc/biosdisk.c @@ -120,7 +120,8 @@ grub_biosdisk_open (const char *name, grub_disk_t disk) { data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM; data->sectors = 32; - total_sectors = GRUB_ULONG_MAX; /* TODO: get the correct size. */ + /* TODO: get the correct size. */ + total_sectors = GRUB_DISK_SIZE_UNKNOWN; } else if (drive & 0x80) { diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c index e5a4a67fa..d0d9e894f 100644 --- a/disk/ieee1275/ofdisk.c +++ b/disk/ieee1275/ofdisk.c @@ -204,7 +204,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) /* XXX: There is no property to read the number of blocks. There should be a property `#blocks', but it is not there. Perhaps it is possible to use seek for this. */ - disk->total_sectors = 0xFFFFFFFFUL; + disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN; disk->id = (unsigned long) op; From 7d4873c26a80e0d05c0952aa45f4bda59e1e3f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Nesrsta?= Date: Tue, 1 Jun 2010 02:10:19 +0200 Subject: [PATCH 50/96] =?UTF-8?q?Merge=20Ale=C5=A1'=20latest=20patch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bus/usb/ohci.c | 156 ++++++++++++++++++++++++++++++---------- bus/usb/uhci.c | 19 +++-- bus/usb/usbtrans.c | 8 +++ disk/scsi.c | 33 ++++++++- disk/usbms.c | 40 ++++++++--- include/grub/usb.h | 3 +- include/grub/usbtrans.h | 3 + term/usb_keyboard.c | 1 - 8 files changed, 206 insertions(+), 57 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 03768d39e..ac6f61ee8 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -116,6 +116,11 @@ typedef enum #define GRUB_OHCI_PERIODIC_START 0x257f #define GRUB_OHCI_FRAME_INTERVAL 0x2edf +#define GRUB_OHCI_SET_PORT_ENABLE (1 << 1) +#define GRUB_OHCI_CLEAR_PORT_ENABLE (1 << 0) +#define GRUB_OHCI_SET_PORT_RESET (1 << 4) +#define GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE (1 << 20) + static grub_uint32_t grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg) { @@ -281,7 +286,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, /* Misc. pre-sets. */ o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); @@ -396,8 +401,10 @@ grub_ohci_transaction (grub_ohci_td_t td, break; } +#if 0 /* Always generate interrupt */ /* Generate no interrupts. */ token |= 7 << 21; +#endif /* Set the token. */ token |= toggle << 24; @@ -444,9 +451,12 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_uint32_t status; grub_uint32_t control; grub_usb_err_t err; - int i, j; + int i; grub_uint64_t maxtime; int err_timeout = 0; + int err_unrec = 0; + grub_uint32_t intstatus; + grub_uint32_t tderr_addr = 0; /* Allocate an Endpoint Descriptor. */ ed_chunk = grub_memalign_dma32 (256, sizeof (*ed)); @@ -479,11 +489,13 @@ grub_ohci_transfer (grub_usb_controller_t dev, + (i + 1) * sizeof (td_list[0])); } +#if 0 /* Better will be enable interrupt on all TDs. */ /* The last-1 TD token we should change to enable interrupt when TD finishes. * As OHCI interrupts are disabled, it does only setting of WDH bit in * HcInterruptStatus register - and that is what we want to safely detect * normal end of all transactions. */ td_list[transfer->transcnt - 1].token &= ~(7 << 21); +#endif td_list[transfer->transcnt].token = 0; td_list[transfer->transcnt].buffer = 0; @@ -582,9 +594,11 @@ grub_ohci_transfer (grub_usb_controller_t dev, } grub_dprintf ("ohci", "wait for completion\n"); - grub_dprintf ("ohci", "control=0x%02x status=0x%02x\n", + grub_dprintf ("ohci", + "begin: control=0x%02x status=0x%02x\n\t\t intstatus=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS)); /* Safety measure to avoid a hang. */ maxtime = grub_get_time_ms () + 1000; @@ -592,30 +606,34 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Wait until the transfer is completed or STALLs. */ do { - grub_cpu_idle (); + /* Check transfer status */ + intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS); + if ((intstatus & 0x2) != 0) + { + grub_dprintf ("ohci", "Current HccaDoneHead=0x%08x\n", + o->hcca->donehead); + /* Remember last successful TD */ + tderr_addr = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf; + /* Reset DoneHead */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); + /* if TD is last, finish */ + if (tderr_addr == td_list_addr + + sizeof (td_list[0]) * (transfer->transcnt - 1)) + break; + continue; + } + + if ((intstatus & 0x10) != 0) + { /* Unrecoverable error - only reset can help...! */ + err_unrec = 1; + break; + } /* Detected a HALT. */ if (grub_le_to_cpu32 (ed->td_head) & 1) break; - - if ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x2) != 0) - { - if ((grub_le_to_cpu32 (o->hcca->donehead) & ~0xf) - == td_list_addr + (transfer->transcnt - 1) * sizeof (td_list[0])) - break; - /* Done Head can be updated on some another place if ED is halted. */ - if (grub_le_to_cpu32 (ed->td_head) & 1) - break; - - /* If there is not HALT in ED, it is not correct, so debug it, reset - * donehead and WDH and continue waiting. */ - grub_dprintf ("ohci", "Incorrect HccaDoneHead=0x%08x\n", - o->hcca->donehead); - o->hcca->donehead = 0; - grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); - continue; - } /* Timeout ? */ if (grub_get_time_ms () > maxtime) { @@ -628,9 +646,45 @@ grub_ohci_transfer (grub_usb_controller_t dev, if ((ed->td_head & ~0xf) == (ed->td_tail & ~0xf)) break; + + grub_cpu_idle (); } while (1); + grub_dprintf ("ohci", "end: control=0x%02x status=0x%02x\n\t\t intstatus=0x%02x\n", + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS)); + + if (!tderr_addr) + { + /* It means that something wrong happened, + * it could be: + * - timeout and no TD processed + * - some or unrecoverable error and no TD processed + * - something unexpected... :-( */ + /* Try look into DONEHEAD reg., but there should be also zero */ + grub_dprintf("ohci", "HCCA DoneHead is zero, something is bad!\n"); + tderr_addr = grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD) & ~0xf; + } + + /* Remember last processed transaction (TD) - it is necessary for + * proper setting of toggle bit in next transaction. */ + transfer->last_trans = (tderr_addr - td_list_addr) / sizeof (*td_list); + + /* Check correct value in last_trans */ + /* It could happen if timeout happens and no TD was retired */ + if (transfer->last_trans >= transfer->transcnt || !tderr_addr) + { + grub_dprintf("ohci", "tder==0 or out of TDs range!\n"); + grub_dprintf("ohci", "tderr_addr=0x%x, td_list=%p,\n\t\t last_trans=%d, transcnt=%d\n", + tderr_addr, td_list, transfer->last_trans, transfer->transcnt); + /* We should set something valid... */ + transfer->last_trans = -1; /* Probably no TD done */ + tderr_addr = td_list_addr; + } + + /* In case of timeout do not detect error from TD */ if (err_timeout) { err = GRUB_ERR_TIMEOUT; @@ -640,20 +694,25 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_le_to_cpu32(ed->td_tail), grub_le_to_cpu32(ed->next_ed)); } + /* In case of unrecoverable error do not detect error from TD */ + else if (err_unrec) + { + err = GRUB_USB_ERR_UNRECOVERABLE; + grub_dprintf("ohci", + "Unrecoverable error, target=%08x, head=%08x\n" + "\t\ttail=%08x, next=%08x\n", + grub_le_to_cpu32(ed->target), + grub_le_to_cpu32(ed->td_head), + grub_le_to_cpu32(ed->td_tail), + grub_le_to_cpu32(ed->next_ed)); + } else if (grub_le_to_cpu32 (ed->td_head) & 1) { - grub_uint32_t td_err_addr; grub_uint8_t errcode; grub_ohci_td_t tderr = NULL; - td_err_addr = (grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD) & ~0xf); - if (td_err_addr == 0) - /* If DONEHEAD==0 it means that correct address is in HCCA. - * It should be always now! */ - td_err_addr = (grub_le_to_cpu32 (o->hcca->donehead) & ~0xf); - tderr = (grub_ohci_td_t) ((char *) td_list - + (td_err_addr - td_list_addr)); + + (tderr_addr - td_list_addr)); errcode = grub_le_to_cpu32 (tderr->token) >> 28; grub_dprintf ("ohci", "OHCI errcode=0x%02x\n", errcode); @@ -702,17 +761,17 @@ grub_ohci_transfer (grub_usb_controller_t dev, case 8: /* XXX: Data overrun error. */ err = GRUB_USB_ERR_DATA; - j = ((grub_uint32_t)tderr - (grub_uint32_t)td_list) / sizeof (*td_list); - grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n", tderr, j); + grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n", + tderr, transfer->last_trans); break; case 9: /* XXX: Data underrun error. */ err = GRUB_USB_ERR_DATA; + grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n", + tderr, transfer->last_trans); grub_dprintf ("ohci", "Underrun, number of not transferred bytes: %d\n", 1 + grub_le_to_cpu32 (tderr->buffer_end) - grub_le_to_cpu32 (tderr->buffer)); - j = ((grub_uint32_t)tderr - (grub_uint32_t)td_list) / sizeof (*td_list); - grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n", tderr, j); break; case 10: @@ -764,7 +823,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2)); /* Wait for new SOF */ - while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0); + while (((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0) + && !err_unrec); /* Now it should be safe to change CONTROL and BULK lists. */ /* Important cleaning. */ @@ -774,7 +834,29 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); - + + if (err_unrec) + { + /* Do OHCI reset in case of unrecoverable error - maybe we will need + * do more - re-enumerate bus etc. (?) */ + + /* Suspend the OHCI by issuing a reset. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */ + grub_millisleep (1); + grub_dprintf ("ohci", "Unrecoverable error - OHCI reset\n"); + + /* Misc. resets. */ + o->hcca->donehead = 0; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); + + /* Enable the OHCI. */ + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, (2 << 6)); + } + grub_dprintf ("ohci", "OHCI finished, freeing, err=0x%02x\n", err); grub_dma_free (td_list_chunk); diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index eb533c926..1510f98e8 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -332,13 +332,20 @@ grub_free_td (struct grub_uhci *u, grub_uhci_td_t td) } static void -grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td) +grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td, + grub_usb_transfer_t transfer) { - /* Free the TDs in this queue. */ - while (td) + int i; /* Index of TD in transfer */ + + /* Free the TDs in this queue and set last_trans. */ + for (i=0; td; i++) { grub_uhci_td_t tdprev; + /* Check state of TD and possibly set last_trans */ + if (transfer && (td->linkptr & 1)) + transfer->last_trans = i; + /* Unlink the queue. */ tdprev = td; td = (grub_uhci_td_t) td->linkptr2; @@ -461,7 +468,7 @@ grub_uhci_transfer (grub_usb_controller_t dev, td_prev->linkptr = 1; if (td_first) - grub_free_queue (u, td_first); + grub_free_queue (u, td_first, NULL); return GRUB_USB_ERR_INTERNAL; } @@ -560,7 +567,7 @@ grub_uhci_transfer (grub_usb_controller_t dev, /* Place the QH back in the free list and deallocate the associated TDs. */ qh->elinkptr = 1; - grub_free_queue (u, td_first); + grub_free_queue (u, td_first, transfer); return err; } @@ -609,7 +616,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev, grub_uhci_writereg16 (u, reg, enable << 9); /* Wait for the reset to complete. XXX: How long exactly? */ - grub_millisleep (10); + grub_millisleep (50); /* For root hub should be nominaly 50ms */ status = grub_uhci_readreg16 (u, reg); grub_uhci_writereg16 (u, reg, status & ~(1 << 9)); grub_dprintf ("uhci", "reset completed\n"); diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index 0bf5ee6de..b3ee167a1 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -213,6 +213,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK; transfer->max = max; transfer->dev = dev; + transfer->last_trans = -1; /* Reset index of last processed transaction (TD) */ /* Allocate an array of transfer data structures. */ transfer->transactions = grub_malloc (transfer->transcnt @@ -240,6 +241,13 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, } err = dev->controller.dev->transfer (&dev->controller, transfer); + /* We must remember proper toggle value even if some transactions + * were not processed - correct value should be inversion of last + * processed transaction (TD). */ + if (transfer->last_trans >= 0) + toggle = transfer->transactions[transfer->last_trans].toggle ? 0 : 1; + else + toggle = dev->toggle[endpoint]; /* Nothing done, take original */ grub_dprintf ("usb", "toggle=%d\n", toggle); dev->toggle[endpoint] = toggle; diff --git a/disk/scsi.c b/disk/scsi.c index e8bfb6a3f..dffabc26e 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -421,7 +421,7 @@ grub_scsi_open (const char *name, grub_disk_t disk) /* According to USB MS tests specification, issue Test Unit Ready * until OK */ - maxtime = grub_get_time_ms () + 1000; + maxtime = grub_get_time_ms () + 5000; /* It is safer value */ do { /* Timeout is necessary - for example in case when we have @@ -519,6 +519,37 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector, /* XXX: Never reached. */ return GRUB_ERR_NONE; + +#if 0 /* Workaround - it works - but very slowly, from some reason + * unknown to me (specially on OHCI). Do not use it. */ + /* Split transfer requests to device sector size because */ + /* some devices are not able to transfer more than 512-1024 bytes */ + grub_err_t err = GRUB_ERR_NONE; + + for ( ; size; size--) + { + /* Depending on the type, select a read function. */ + switch (scsi->devtype) + { + case grub_scsi_devtype_direct: + err = grub_scsi_read10 (disk, sector, 1, buf); + break; + + case grub_scsi_devtype_cdrom: + err = grub_scsi_read12 (disk, sector, 1, buf); + break; + + default: /* This should not happen */ + return GRUB_ERR_READ_ERROR; + } + if (err) + return err; + sector++; + buf += scsi->blocksize; + } + + return err; +#endif } static grub_err_t diff --git a/disk/usbms.c b/disk/usbms.c index 7b719fb84..a49b30e7e 100644 --- a/disk/usbms.c +++ b/disk/usbms.c @@ -253,6 +253,7 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, struct grub_usbms_csw status; static grub_uint32_t tag = 0; grub_usb_err_t err = GRUB_USB_ERR_NONE; + grub_usb_err_t errCSW = GRUB_USB_ERR_NONE; int retrycnt = 3 + 1; grub_size_t i; @@ -290,9 +291,8 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, { if (err == GRUB_USB_ERR_STALL) { - grub_usb_clear_halt (dev->dev, dev->in->endp_addr); grub_usb_clear_halt (dev->dev, dev->out->endp_addr); - goto retry; + goto CheckCSW; } return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed"); } @@ -302,7 +302,12 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, { err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, size, buf); grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL); - if (err) goto CheckCSW; + if (err) + { + if (err == GRUB_USB_ERR_STALL) + grub_usb_clear_halt (dev->dev, dev->in->endp_addr); + goto CheckCSW; + } /* Debug print of received data. */ grub_dprintf ("usb", "buf:\n"); if (size <= 64) @@ -316,6 +321,12 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd, err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, size, buf); grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL); grub_dprintf ("usb", "buf:\n"); + if (err) + { + if (err == GRUB_USB_ERR_STALL) + grub_usb_clear_halt (dev->dev, dev->out->endp_addr); + goto CheckCSW; + } /* Debug print of sent data. */ if (size <= 256) for (i=0; idev, dev->in->endp_addr, + errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, sizeof (status), (char *) &status); - if (err) + if (errCSW) { grub_usb_clear_halt (dev->dev, dev->in->endp_addr); - err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, + errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, sizeof (status), (char *) &status); - if (err) + if (errCSW) { /* Bulk-only reset device. */ + grub_dprintf ("usb", "Bulk-only reset device - errCSW\n"); grub_usbms_reset (dev->dev, dev->interface); grub_usb_clear_halt (dev->dev, dev->in->endp_addr); grub_usb_clear_halt (dev->dev, dev->out->endp_addr); @@ -347,9 +359,11 @@ CheckCSW: status.signature, status.tag, status.residue); grub_dprintf ("usb", "CSW: status=0x%02x\n", status.status); - /* If phase error, do bulk-only reset device. */ - if (status.status == 2) - { + /* If phase error or not valid signature, do bulk-only reset device. */ + if ((status.status == 2) || + (status.signature != grub_cpu_to_le32(0x53425355))) + { /* Bulk-only reset device. */ + grub_dprintf ("usb", "Bulk-only reset device - bad status\n"); grub_usbms_reset (dev->dev, dev->interface); grub_usb_clear_halt (dev->dev, dev->in->endp_addr); grub_usb_clear_halt (dev->dev, dev->out->endp_addr); @@ -357,9 +371,13 @@ CheckCSW: goto retry; } - if (status.status) + /* If "command failed" status or data transfer failed -> error */ + if ((status.status || err) && !read_write) return grub_error (GRUB_ERR_READ_ERROR, "error communication with USB Mass Storage device"); + else if ((status.status || err) && read_write) + return grub_error (GRUB_ERR_WRITE_ERROR, + "error communication with USB Mass Storage device"); return GRUB_ERR_NONE; } diff --git a/include/grub/usb.h b/include/grub/usb.h index cbbc39303..64dc78d61 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -35,7 +35,8 @@ typedef enum GRUB_USB_ERR_NAK, GRUB_USB_ERR_BABBLE, GRUB_USB_ERR_TIMEOUT, - GRUB_USB_ERR_BITSTUFF + GRUB_USB_ERR_BITSTUFF, + GRUB_USB_ERR_UNRECOVERABLE } grub_usb_err_t; typedef enum diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h index cd818e1fc..40fc0dd5f 100644 --- a/include/grub/usbtrans.h +++ b/include/grub/usbtrans.h @@ -58,6 +58,9 @@ struct grub_usb_transfer struct grub_usb_device *dev; struct grub_usb_transaction *transactions; + + int last_trans; + /* Index of last processed transaction in OHCI/UHCI driver. */ }; typedef struct grub_usb_transfer *grub_usb_transfer_t; diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 5d76c5e02..69d5709b6 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -18,7 +18,6 @@ */ #include -#include #include #include #include From 0d9ff59345a63087e02bb2415a62ae6cd50a6f42 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 1 Jun 2010 18:05:29 +0100 Subject: [PATCH 51/96] * kern/emu/getroot.c (find_root_device_from_mountinfo): Use getline instead of fgets into a static buffer. Use sizeof instead of strlen on a constant string. Thanks to Vladimir for review. --- ChangeLog.btrfs-probe | 2 +- kern/emu/getroot.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ChangeLog.btrfs-probe b/ChangeLog.btrfs-probe index 77c9995c8..c79e6b6a4 100644 --- a/ChangeLog.btrfs-probe +++ b/ChangeLog.btrfs-probe @@ -1,4 +1,4 @@ -2010-05-18 Colin Watson +2010-06-01 Colin Watson Add btrfs probing support, currently only in the single-device case. diff --git a/kern/emu/getroot.c b/kern/emu/getroot.c index da62089fa..97c24115b 100644 --- a/kern/emu/getroot.c +++ b/kern/emu/getroot.c @@ -93,14 +93,15 @@ static char * find_root_device_from_mountinfo (const char *dir) { FILE *fp; - char buf[1024]; /* XXX */ + char *buf = NULL; + size_t len = 0; char *ret = NULL; fp = fopen ("/proc/self/mountinfo", "r"); if (! fp) return NULL; /* fall through to other methods */ - while (fgets (buf, sizeof (buf), fp)) + while (getline (&buf, &len, fp) > 0) { int mnt_id, parent_mnt_id; unsigned int major, minor; @@ -139,7 +140,7 @@ find_root_device_from_mountinfo (const char *dir) if (!sep) continue; - sep += strlen (" - "); + sep += sizeof (" - ") - 1; if (sscanf (sep, "%s %s", fstype, device) != 2) continue; @@ -152,6 +153,7 @@ find_root_device_from_mountinfo (const char *dir) ret = strdup (device); } + free (buf); fclose (fp); return ret; } From 390b0676c482abcc47c70a530b2bf4edb10f7479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Nesrsta?= Date: Wed, 2 Jun 2010 02:04:45 +0200 Subject: [PATCH 52/96] Use dev->descdev.maxsize0 even if dev->initialized isn't set --- bus/usb/usbtrans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index b3ee167a1..e1b9097e6 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -76,7 +76,7 @@ grub_usb_control_msg (grub_usb_device_t dev, setupdata_addr = grub_dma_get_phys (setupdata_chunk); /* Determine the maximum packet size. */ - if (dev->initialized && dev->descdev.maxsize0) + if (dev->descdev.maxsize0) max = dev->descdev.maxsize0; else max = 64; From ab6316112cc0ea4149168972c47f75b57a7b9eeb Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 01:23:34 +0100 Subject: [PATCH 53/96] * conf/any-emu.rmk (kernel_img_SOURCES) [!x86]: Include kern/$(target_cpu)/cache.S even if TARGET_NO_MODULES = yes. --- ChangeLog | 5 +++++ conf/any-emu.rmk | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index de0b62f08..d88c510eb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-02 Colin Watson + + * conf/any-emu.rmk (kernel_img_SOURCES) [!x86]: Include + kern/$(target_cpu)/cache.S even if TARGET_NO_MODULES = yes. + 2010-06-01 Colin Watson Add btrfs probing support, currently only in the single-device case. diff --git a/conf/any-emu.rmk b/conf/any-emu.rmk index 000996172..21e139a32 100644 --- a/conf/any-emu.rmk +++ b/conf/any-emu.rmk @@ -20,14 +20,14 @@ TARGET_NO_STRIP = yes ifneq ($(TARGET_NO_MODULES), yes) kernel_img_SOURCES += symlist.c kern/$(target_cpu)/dl.c +else +kernel_img_SOURCES += grub_emu_init.c +endif ifneq ($(target_cpu), i386) ifneq ($(target_cpu), x86_64) kernel_img_SOURCES += kern/$(target_cpu)/cache.S endif endif -else -kernel_img_SOURCES += grub_emu_init.c -endif # For halt.mod. pkglib_MODULES += halt.mod From 9121567e16cf77ccd1f4a148580718436101c247 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 02:37:55 +0100 Subject: [PATCH 54/96] * commands/gptsync.c (grub_cmd_gptsync): Fix typos. (GRUB_MOD_INIT): Fix capitalisation. * docs/grub.texi (Command-line and menu entry commands): Document gettext and gptsync commands. --- ChangeLog | 7 +++++++ commands/gptsync.c | 8 ++++---- docs/grub.texi | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index d88c510eb..9c11b2fa9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-02 Colin Watson + + * commands/gptsync.c (grub_cmd_gptsync): Fix typos. + (GRUB_MOD_INIT): Fix capitalisation. + * docs/grub.texi (Command-line and menu entry commands): Document + gettext and gptsync commands. + 2010-06-02 Colin Watson * conf/any-emu.rmk (kernel_img_SOURCES) [!x86]: Include diff --git a/commands/gptsync.c b/commands/gptsync.c index d217b5d5c..6364c13f7 100644 --- a/commands/gptsync.c +++ b/commands/gptsync.c @@ -138,8 +138,8 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)), { grub_device_close (dev); return grub_error (GRUB_ERR_OUT_OF_RANGE, - "only partitions resding in the first 2TB " - "can be presen in hybrid MBR"); + "only partitions residing in the first 2TB " + "can be present in hybrid MBR"); } @@ -243,8 +243,8 @@ GRUB_MOD_INIT(gptsync) cmd = grub_register_command ("gptsync", grub_cmd_gptsync, N_("DEVICE [PARTITION[+/-[TYPE]]] ..."), N_("Fill hybrid MBR of GPT drive DEVICE. " - "specified partitions will be a part " - "of hybrid mbr. Up to 3 partitions are " + "Specified partitions will be a part " + "of hybrid MBR. Up to 3 partitions are " "allowed. TYPE is an MBR type. " "+ means that partition is active. " "Only one partition can be active.")); diff --git a/docs/grub.texi b/docs/grub.texi index bcc05c1f8..52aca3fbd 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1139,6 +1139,8 @@ you forget a command, you can run the command @command{help} * date:: Display or set current date and time * echo:: Display a line of text * export:: Export an environment variable +* gettext:: Translate a string +* gptsync:: Fill an MBR based on GPT entries * halt:: Shut down your computer * help:: Show help messages * insmod:: Insert a module @@ -1320,6 +1322,38 @@ to subsidiary configuration files loaded using @command{configfile}. @end deffn +@node gettext +@subsection gettext + +@deffn Command gettext string +Translate @var{string} into the current language. + +The current language code is stored in the @samp{lang} variable in GRUB's +environment. Translation files in MO format are read from +@samp{locale_dir}, usually @file{/boot/grub/locale}. +@end deffn + + +@node gptsync +@subsection gptsync + +@deffn Command gptsync device [partition[+/-[type]]] @dots{} +Disks using the GUID Partition Table (GPT) also have a legacy Master Boot +Record (MBR) partition table for compatibility with the BIOS and with older +operating systems. The legacy MBR can only represent a limited subset of +GPT partition entries. + +This command populates the legacy MBR with the specified @var{partition} +entries on @var{device}. Up to three partitions may be used. + +@var{type} is an MBR partition type code; prefix with @samp{0x} if you want +to enter this in hexadecimal. The separator between @var{partition} and +@var{type} may be @samp{+} to make the partition active, or @samp{-} to make +it inactive; only one partition may be active. If both the separator and +type are omitted, then the partition will be inactive. +@end deffn + + @node halt @subsection halt From 34c9f0e949cfadddd88a8229f4d10184f3263646 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 02:50:04 +0100 Subject: [PATCH 55/96] * docs/grub.texi (direntry): Remove grub-terminfo reference. (GNU GRUB manual): Likewise. (General commands): Update description of `terminfo' for GRUB 2. --- ChangeLog | 6 ++++++ docs/grub.texi | 21 +++++++++------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9c11b2fa9..8a6f98be1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (direntry): Remove grub-terminfo reference. + (GNU GRUB manual): Likewise. + (General commands): Update description of `terminfo' for GRUB 2. + 2010-06-02 Colin Watson * commands/gptsync.c (grub_cmd_gptsync): Fix typos. diff --git a/docs/grub.texi b/docs/grub.texi index 52aca3fbd..657a5d146 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -34,9 +34,6 @@ Invariant Sections. @direntry * GRUB: (grub). The GRand Unified Bootloader * grub-install: (grub)Invoking grub-install. Install GRUB on your drive -* grub-terminfo: (grub)Invoking grub-terminfo. Generate a terminfo - command from a - terminfo name @end direntry @setchapternewpage odd @@ -89,7 +86,6 @@ This edition documents version @value{VERSION}. * Troubleshooting:: Error messages produced by GRUB * Invoking the grub shell:: How to use the grub shell * Invoking grub-install:: How to use the GRUB installer -* Invoking grub-terminfo:: How to generate a terminfo command * Obtaining and Building GRUB:: How to obtain and build GRUB * Reporting bugs:: Where you should send a bug report * Future:: Some future plans on GRUB @@ -1076,7 +1072,7 @@ Commands usable anywhere in the menu and in the command-line. @menu * serial:: Set up a serial device -* terminfo:: Define escape sequences for a terminal +* terminfo:: Define terminal type @end menu @@ -1108,15 +1104,16 @@ support. See also @ref{Serial terminal}. @node terminfo @subsection terminfo -@deffn Command terminfo @option{--name=name} @option{--cursor-address=seq} [@option{--clear-screen=seq}] [@option{--enter-standout-mode=seq}] [@option{--exit-standout-mode=seq}] -Define the capabilities of your terminal. Use this command to define -escape sequences, if it is not vt100-compatible. You may use @samp{\e} -for @key{ESC} and @samp{^X} for a control character. +@deffn Command terminfo [term] +Define the capabilities of your terminal by giving the name of an entry in +the terminfo database, which should correspond roughly to a @samp{TERM} +environment variable in Unix. -You can use the utility @command{grub-terminfo} to generate -appropriate arguments to this command. @xref{Invoking grub-terminfo}. +At the moment, only @samp{vt100} is supported in GRUB 2. If you need other +terminal types, please contact us to discuss the best way to include support +for these in GRUB. -If no option is specified, the current settings are printed. +If no option is specified, the current terminal type is printed. @end deffn From a18c78347304d00b521556ccc76d4c8564d417b0 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 04:51:35 +0200 Subject: [PATCH 56/96] Fewstylistic fixes --- bus/usb/ohci.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index ac6f61ee8..de0a4e7ac 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -594,10 +594,10 @@ grub_ohci_transfer (grub_usb_controller_t dev, } grub_dprintf ("ohci", "wait for completion\n"); - grub_dprintf ("ohci", - "begin: control=0x%02x status=0x%02x\n\t\t intstatus=0x%02x\n", + grub_dprintf ("ohci", "begin: control=0x%02x status=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); + grub_dprintf ("ohci","intstatus=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS)); /* Safety measure to avoid a hang. */ @@ -621,7 +621,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, if (tderr_addr == td_list_addr + sizeof (td_list[0]) * (transfer->transcnt - 1)) break; - continue; + continue; } if ((intstatus & 0x10) != 0) @@ -651,9 +651,10 @@ grub_ohci_transfer (grub_usb_controller_t dev, } while (1); - grub_dprintf ("ohci", "end: control=0x%02x status=0x%02x\n\t\t intstatus=0x%02x\n", + grub_dprintf ("ohci", "end: control=0x%02x status=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), - grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS), + grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); + grub_dprintf ("ohci", "intstatus=0x%02x\n", grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS)); if (!tderr_addr) @@ -688,21 +689,22 @@ grub_ohci_transfer (grub_usb_controller_t dev, if (err_timeout) { err = GRUB_ERR_TIMEOUT; - grub_dprintf("ohci", "Timeout, target=%08x, head=%08x\n\t\ttail=%08x, next=%08x\n", - grub_le_to_cpu32(ed->target), - grub_le_to_cpu32(ed->td_head), - grub_le_to_cpu32(ed->td_tail), - grub_le_to_cpu32(ed->next_ed)); + grub_dprintf("ohci", "Timeout, target=%08x, head=%08x\n", + grub_le_to_cpu32(ed->target), + grub_le_to_cpu32(ed->td_head)); + grub_dprintf("ohci", "tail=%08x, next=%08x\n", + grub_le_to_cpu32(ed->td_tail), + grub_le_to_cpu32(ed->next_ed)); } /* In case of unrecoverable error do not detect error from TD */ else if (err_unrec) { err = GRUB_USB_ERR_UNRECOVERABLE; grub_dprintf("ohci", - "Unrecoverable error, target=%08x, head=%08x\n" - "\t\ttail=%08x, next=%08x\n", + "Unrecoverable error, target=%08x, head=%08x\n", grub_le_to_cpu32(ed->target), - grub_le_to_cpu32(ed->td_head), + grub_le_to_cpu32(ed->td_head)); + grub_dprintf("ohci", "tail=%08x, next=%08x\n", grub_le_to_cpu32(ed->td_tail), grub_le_to_cpu32(ed->next_ed)); } From 2325800310ce4ac9a5088f5c3fca68e44155e145 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 04:52:35 +0200 Subject: [PATCH 57/96] Fix last_trans determination --- bus/usb/ohci.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index de0a4e7ac..4d66df0bc 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -671,15 +671,21 @@ grub_ohci_transfer (grub_usb_controller_t dev, /* Remember last processed transaction (TD) - it is necessary for * proper setting of toggle bit in next transaction. */ - transfer->last_trans = (tderr_addr - td_list_addr) / sizeof (*td_list); - + transfer->last_trans = ((tderr_addr - td_list_addr) / sizeof (*td_list)); + grub_dprintf("ohci", "tderr_addr=0x%x, td_list_addr=0x%x,\n", + tderr_addr, td_list_addr); + + if ((ed->td_head & ~0xf) == (ed->td_tail & ~0xf)) + transfer->last_trans = transfer->transcnt - 1; + /* Check correct value in last_trans */ /* It could happen if timeout happens and no TD was retired */ if (transfer->last_trans >= transfer->transcnt || !tderr_addr) { - grub_dprintf("ohci", "tder==0 or out of TDs range!\n"); - grub_dprintf("ohci", "tderr_addr=0x%x, td_list=%p,\n\t\t last_trans=%d, transcnt=%d\n", - tderr_addr, td_list, transfer->last_trans, transfer->transcnt); + grub_dprintf("ohci", "tderr==0 or out of TDs range!\n"); + grub_dprintf("ohci", "last_trans=%d, transcnt=%d\n", + transfer->last_trans, transfer->transcnt); + /* We should set something valid... */ transfer->last_trans = -1; /* Probably no TD done */ tderr_addr = td_list_addr; @@ -713,6 +719,8 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_uint8_t errcode; grub_ohci_td_t tderr = NULL; + transfer->last_trans--; + tderr = (grub_ohci_td_t) ((char *) td_list + (tderr_addr - td_list_addr)); From f1cb760c99f77795f1c91f11f8157d6984f4593f Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 04:52:52 +0200 Subject: [PATCH 58/96] Disable unused list --- bus/usb/ohci.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 4d66df0bc..fd378cc8d 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -563,9 +563,14 @@ grub_ohci_transfer (grub_usb_controller_t dev, grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, ed_addr); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); +#define GRUB_OHCI_REG_CONTROL_BULK_ENABLE (1 << 5) +#define GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE (1 << 4) + /* Enable the Bulk list. */ control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); - control |= 1 << 5; + control |= GRUB_OHCI_REG_CONTROL_BULK_ENABLE; + control &= ~GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE; + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); /* Set BulkListFilled. */ @@ -578,12 +583,15 @@ grub_ohci_transfer (grub_usb_controller_t dev, case GRUB_USB_TRANSACTION_TYPE_CONTROL: { + grub_dprintf ("ohci", "add to control list\n"); + /* Set ControlList Head and Current */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, ed_addr); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0); /* Enable the Control list. */ - control |= 1 << 4; + control |= GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE; + control &= ~GRUB_OHCI_REG_CONTROL_BULK_ENABLE; grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); /* Set ControlListFilled. */ From d4955444976a90377d0ff9d8140bb906c2c36f46 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 05:00:54 +0200 Subject: [PATCH 59/96] Shut down PHCI controller harder --- bus/usb/ohci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index fd378cc8d..a42d9fee1 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -970,7 +970,10 @@ grub_ohci_fini_hw (int noreturn __attribute__ ((unused))) grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0); grub_ohci_writereg32 (o, GRUB_OHCI_REG_DONEHEAD, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, 0); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); } + grub_millisleep (10); return GRUB_ERR_NONE; } From 288dd6ed3d88420e4fcc28a7aeeef0916c673cd5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 11:14:02 +0100 Subject: [PATCH 60/96] * docs/grub.texi (Configuration): New section, documenting configuration file generation using grub-mkconfig. I've left a slot for documenting the full shell scripting format but have not yet started on writing that up. (Invoking grub-mkconfig): New section. --- ChangeLog | 8 ++ docs/grub.texi | 221 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 228 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8a6f98be1..214be173c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (Configuration): New section, documenting + configuration file generation using grub-mkconfig. I've left a slot + for documenting the full shell scripting format but have not yet + started on writing that up. + (Invoking grub-mkconfig): New section. + 2010-06-02 Colin Watson * docs/grub.texi (direntry): Remove grub-terminfo reference. diff --git a/docs/grub.texi b/docs/grub.texi index 657a5d146..77f151cfc 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -20,7 +20,7 @@ This manual is for GNU GRUB (version @value{VERSION}, @value{UPDATED}). -Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009 Free Software Foundation, Inc. +Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009,2010 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document @@ -34,6 +34,7 @@ Invariant Sections. @direntry * GRUB: (grub). The GRand Unified Bootloader * grub-install: (grub)Invoking grub-install. Install GRUB on your drive +* grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration @end direntry @setchapternewpage odd @@ -86,6 +87,7 @@ This edition documents version @value{VERSION}. * Troubleshooting:: Error messages produced by GRUB * Invoking the grub shell:: How to use the grub shell * Invoking grub-install:: How to use the GRUB installer +* Invoking grub-mkconfig:: Generate a GRUB configuration file * Obtaining and Building GRUB:: How to obtain and build GRUB * Reporting bugs:: Where you should send a bug report * Future:: Some future plans on GRUB @@ -694,6 +696,197 @@ the size, run the command @command{uppermem} @emph{before} loading the kernel. @xref{uppermem}, for more information. +@node Configuration +@chapter Writing your own configuration file + +GRUB is configured using @file{grub.cfg}, usually located under +@file{/boot/grub}. This file is quite flexible, but most users will not +need to write the whole thing by hand. + +@menu +* Simple configuration:: Recommended for most users +* Shell-like scripting:: For power users and developers +@end menu + + +@node Simple configuration +@section Simple configuration handling + +The program @command{grub-mkconfig} (@pxref{Invoking grub-mkconfig}) +generates @file{grub.cfg} files suitable for most cases. It is suitable for +use when upgrading a distribution, and will discover available kernels and +attempt to generate menu entries for them. + +The file @file{/etc/default/grub} controls the operation of +@command{grub-mkconfig}. It is sourced by a shell script, and so must be +valid POSIX shell input; normally, it will just be a sequence of +@samp{KEY=value} lines, but if the value contains spaces or other special +characters then it must be quoted. For example: + +@example +GRUB_TERMINAL_INPUT="console serial" +@end example + +Valid keys in @file{/etc/default/grub} are as follows: + +@table @samp +@item GRUB_DEFAULT +The default menu entry. This may be a number, in which case it identifies +the Nth entry in the generated menu counted from zero, or the full name of a +menu entry, or the special string @samp{saved}. Using the full name may be +useful if you want to set a menu entry as the default even though there may +be a variable number of entries before it. + +If you set this to @samp{saved}, then the default menu entry will be that +saved by @samp{GRUB_SAVEDEFAULT}, @command{grub-set-default}, or +@command{grub-reboot}. + +The default is @samp{0}. + +@item GRUB_SAVEDEFAULT +If this option is set to @samp{true}, then, when an entry is selected, save +it as a new default entry for use by future runs of GRUB. This is only +useful if @samp{GRUB_DEFAULT=saved}; it is a separate option because +@samp{GRUB_DEFAULT=saved} is useful without this option, in conjunction with +@command{grub-set-default} or @command{grub-reboot}. Unset by default. + +@item GRUB_TIMEOUT +Boot the default entry this many seconds after the menu is displayed, unless +a key is pressed. The default is @samp{5}. Set to @samp{0} to boot +immediately without displaying the menu, or to @samp{-1} to wait +indefinitely. + +@item GRUB_HIDDEN_TIMEOUT +Wait this many seconds for a key to be pressed before displaying the menu. +If no key is pressed during that time, boot immediately. Unset by default. + +@item GRUB_HIDDEN_TIMEOUT_QUIET +In conjunction with @samp{GRUB_HIDDEN_TIMEOUT}, set this to @samp{true} to +suppress the verbose countdown while waiting for a key to be pressed before +displaying the menu. Unset by default. + +@item GRUB_DEFAULT_BUTTON +@itemx GRUB_TIMEOUT_BUTTON +@itemx GRUB_HIDDEN_TIMEOUT_BUTTON +@itemx GRUB_BUTTON_CMOS_ADDRESS +Variants of the corresponding variables without the @samp{_BUTTON} suffix, +used to support vendor-specific power buttons. @xref{Vendor power-on keys}. + +@item GRUB_DISTRIBUTOR +Set by distributors of GRUB to their identifying name. This is used to +generate more informative menu entry titles. + +@item GRUB_TERMINAL_INPUT +Select the terminal input device. You may select multiple devices here, +separated by spaces. + +Valid terminal input names depend on the platform, but may include +@samp{console} (PC BIOS and EFI consoles), @samp{serial} (serial terminal), +@samp{ofconsole} (Open Firmware console), @samp{at_keyboard} (PC AT +keyboard, mainly useful with Coreboot), or @samp{usb_keyboard} (USB keyboard +using the HID Boot Protocol, for cases where the firmware does not handle +this). + +The default is to use the platform's native terminal input. + +@item GRUB_TERMINAL_OUTPUT +Select the terminal output device. You may select multiple devices here, +separated by spaces. + +Valid terminal output names depend on the platform, but may include +@samp{console} (PC BIOS and EFI consoles), @samp{serial} (serial terminal), +@samp{gfxterm} (graphics-mode output), @samp{ofconsole} (Open Firmware +console), or @samp{vga_text} (VGA text output, mainly useful with Coreboot). + +The default is to use the platform's native terminal input. + +@item GRUB_TERMINAL +If this option is set, it overrides both @samp{GRUB_TERMINAL_INPUT} and +@samp{GRUB_TERMINAL_OUTPUT} to the same value. + +@item GRUB_SERIAL_COMMAND +A command to configure the serial port when using the serial console. +@xref{serial}. Defaults to @samp{serial}. + +@item GRUB_CMDLINE_LINUX +Command-line arguments to add to menu entries for the Linux kernel. + +@item GRUB_CMDLINE_LINUX_DEFAULT +Unless @samp{GRUB_DISABLE_LINUX_RECOVERY} is set, two menu entries will be +generated for each Linux kernel: one default entry and one entry for +recovery mode. This option lists command-line arguments to add only to the +default menu entry, after those listed in @samp{GRUB_CMDLINE_LINUX}. + +@item GRUB_CMDLINE_NETBSD +@itemx GRUB_CMDLINE_NETBSD_DEFAULT +As @samp{GRUB_CMDLINE_LINUX} and @samp{GRUB_CMDLINE_LINUX_DEFAULT}, but for +NetBSD. + +@item GRUB_DISABLE_LINUX_UUID +Normally, @command{grub-mkconfig} will generate menu entries that use +universally-unique identifiers (UUIDs) to identify the root filesystem to +the Linux kernel, using a @samp{root=UUID=...} kernel parameter. This is +usually more reliable, but in some cases it may not be appropriate. To +disable the use of UUIDs, set this option to @samp{true}. + +@item GRUB_DISABLE_LINUX_RECOVERY +Disable the generation of recovery mode menu entries for Linux. + +@item GRUB_DISABLE_NETBSD_RECOVERY +Disable the generation of recovery mode menu entries for NetBSD. + +@item GRUB_GFXMODE +Set the resolution used on the @samp{gfxterm} graphical terminal. Note that +you can only use modes which your graphics card supports via VESA BIOS +Extensions (VBE), so for example native LCD panel resolutions may not be +available. The default is @samp{640x480}. + +@item GRUB_BACKGROUND +Set a background image for use with the @samp{gfxterm} graphical terminal. +The value of this option must be a file readable by GRUB at boot time, and +it must end with @file{.png}, @file{.tga}, @file{.jpg}, or @file{.jpeg}. +The image will be scaled if necessary to fit the screen. + +@item GRUB_THEME +Set a theme for use with the @samp{gfxterm} graphical terminal. +@xref{Themes}. + +@item GRUB_GFXPAYLOAD_LINUX +Set to @samp{text} to force the Linux kernel to boot in normal text mode, +@samp{keep} to preserve the graphics mode set using @samp{GRUB_GFXMODE}, +@samp{@var{width}x@var{height}}[@samp{x@var{depth}}] to set a particular +graphics mode, or a sequence of these separated by commas or semicolons to +try several modes in sequence. + +Depending on your kernel, your distribution, your graphics card, and the +phase of the moon, note that using this option may cause GNU/Linux to suffer +from various display problems, particularly during the early part of the +boot sequence. If you have problems, simply unset this option and GRUB will +tell Linux to boot in normal text mode. + +@item GRUB_DISABLE_OS_PROBER +Normally, @command{grub-mkconfig} will try to use the external +@command{os-prober} program, if installed, to discover other operating +systems installed on the same system and generate appropriate menu entries +for them. Set this option to @samp{true} to disable this. + +@item GRUB_INIT_TUNE +Play a tune on the speaker when GRUB starts. This is particularly useful +for users unable to see the screen. The value of this option is passed +directly to @ref{play}. +@end table + +For more detailed customisation of @command{grub-mkconfig}'s output, you may +edit the scripts in @file{/etc/grub.d} directly. +@file{/etc/grub.d/40_custom} is particularly useful for adding entire custom +menu entries; simply type the menu entries you want to add at the end of +that file, making sure to leave at least the first two lines intact. + + +@node Shell-like scripting +@section Writing full configuration files directly + + @node Serial terminal @chapter Using GRUB via a serial line @@ -1499,6 +1692,32 @@ into/from your computer. @end table +@node Invoking grub-mkconfig +@chapter Invoking grub-mkconfig + +The program @command{grub-mkconfig} generates a configuration file for GRUB +(@pxref{Simple configuration}). + +@example +grub-mkconfig -o /boot/grub/grub.cfg +@end example + +@command{grub-mkconfig} accepts the following options: + +@table @option +@item --help +Print a summary of the command-line options and exit. + +@item --version +Print the version number of GRUB and exit. + +@item -o @var{file} +@itemx --output=@var{file} +Send the generated configuration file to @var{file}. The default is to send +it to standard output. +@end table + + @node Obtaining and Building GRUB @appendix How to obtain and build GRUB From bb8ea0f5c324043bd09e024b41a2af262909b659 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 11:26:28 +0100 Subject: [PATCH 61/96] * docs/grub.texi (GNU GRUB manual): Remove reference to `Invoking the grub shell'. (Installation): Add reference to `Making a GRUB bootable CD-ROM'. (Installing GRUB using grub-install): Remove reference to the grub shell; mention `grub-mkimage' and `grub-setup' instead. (Invoking grub-install): Likewise. (Interface): Add reference to `Menu entry editor'. (serial): Remove `--device' option. --- ChangeLog | 11 +++++++++++ docs/grub.texi | 26 ++++++++++++-------------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 214be173c..905e36edf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (GNU GRUB manual): Remove reference to `Invoking + the grub shell'. + (Installation): Add reference to `Making a GRUB bootable CD-ROM'. + (Installing GRUB using grub-install): Remove reference to the grub + shell; mention `grub-mkimage' and `grub-setup' instead. + (Invoking grub-install): Likewise. + (Interface): Add reference to `Menu entry editor'. + (serial): Remove `--device' option. + 2010-06-02 Colin Watson * docs/grub.texi (Configuration): New section, documenting diff --git a/docs/grub.texi b/docs/grub.texi index 77f151cfc..4c903729b 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -85,7 +85,6 @@ This edition documents version @value{VERSION}. * Interface:: The menu and the command-line * Commands:: The list of available builtin commands * Troubleshooting:: Error messages produced by GRUB -* Invoking the grub shell:: How to use the grub shell * Invoking grub-install:: How to use the GRUB installer * Invoking grub-mkconfig:: Generate a GRUB configuration file * Obtaining and Building GRUB:: How to obtain and build GRUB @@ -451,6 +450,7 @@ the @dfn{boot directory}. @menu * Installing GRUB using grub-install:: +* Making a GRUB bootable CD-ROM:: @end menu @@ -530,11 +530,11 @@ quite careful. If the output is wrong, it is unlikely that your computer will be able to boot with no problem. Note that @command{grub-install} is actually just a shell script and the -real task is done by the grub shell @command{grub} (@pxref{Invoking the -grub shell}). Therefore, you may run @command{grub} directly to install -GRUB, without using @command{grub-install}. Don't do that, however, -unless you are very familiar with the internals of GRUB. Installing a -boot loader on a running OS may be extremely dangerous. +real task is done by @command{grub-mkimage} and @command{grub-setup}. +Therefore, you may run those commands directly to install GRUB, without +using @command{grub-install}. Don't do that, however, unless you are very +familiar with the internals of GRUB. Installing a boot loader on a running +OS may be extremely dangerous. @node Making a GRUB bootable CD-ROM @@ -1073,6 +1073,7 @@ the command-line interface. @menu * Command-line interface:: The flexible command-line interface * Menu interface:: The simple menu interface +* Menu entry editor:: Editing a menu entry @end menu @@ -1272,7 +1273,7 @@ Commands usable anywhere in the menu and in the command-line. @node serial @subsection serial -@deffn Command serial [@option{--unit=unit}] [@option{--port=port}] [@option{--speed=speed}] [@option{--word=word}] [@option{--parity=parity}] [@option{--stop=stop}] [@option{--device=dev}] +@deffn Command serial [@option{--unit=unit}] [@option{--port=port}] [@option{--speed=speed}] [@option{--word=word}] [@option{--parity=parity}] [@option{--stop=stop}] Initialize a serial device. @var{unit} is a number in the range 0-3 specifying which serial port to use; default is 0, which corresponds to the port often called COM1. @var{port} is the I/O port where the UART @@ -1281,10 +1282,7 @@ is to be found; if specified it takes precedence over @var{unit}. @var{stop} are the number of data bits and stop bits. Data bits must be in the range 5-8 and stop bits must be 1 or 2. Default is 8 data bits and one stop bit. @var{parity} is one of @samp{no}, @samp{odd}, -@samp{even} and defaults to @samp{no}. The option @option{--device} -can only be used in the grub shell and is used to specify the -tty device to be used in the host operating system (@pxref{Invoking the -grub shell}). +@samp{even} and defaults to @samp{no}. The serial port is not used as a communication channel unless the @command{terminal} command is used (@pxref{terminal}). @@ -1654,9 +1652,9 @@ Unset the environment variable @var{envvar}. @node Invoking grub-install @chapter Invoking grub-install -The program @command{grub-install} installs GRUB on your drive using the -grub shell (@pxref{Invoking the grub shell}). You must specify the -device name on which you want to install GRUB, like this: +The program @command{grub-install} installs GRUB on your drive using +@command{grub-mkimage} and (on some platforms) @command{grub-setup}. You +must specify the device name on which you want to install GRUB, like this: @example grub-install @var{install_device} From 1c41aa7883f3f8ba94e7e0c447f434840a4a0161 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 12:47:11 +0100 Subject: [PATCH 62/96] * docs/grub.texi (Chain-loading): New section. (DOS/Windows): New section, borrowed from GRUB Legacy with details adjusted for GRUB 2. (SCO UnixWare): Likewise. (QNX): Likewise. (chainloader): Add reference to `Block list syntax'. (drivemap): New section. (parttool): New section. --- ChangeLog | 11 +++ docs/grub.texi | 187 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 193 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 905e36edf..b0fc06848 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (Chain-loading): New section. + (DOS/Windows): New section, borrowed from GRUB Legacy with details + adjusted for GRUB 2. + (SCO UnixWare): Likewise. + (QNX): Likewise. + (chainloader): Add reference to `Block list syntax'. + (drivemap): New section. + (parttool): New section. + 2010-06-02 Colin Watson * docs/grub.texi (GNU GRUB manual): Remove reference to `Invoking diff --git a/docs/grub.texi b/docs/grub.texi index 4c903729b..5f2e5e36a 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -647,6 +647,35 @@ use more complicated instructions. @xref{DOS/Windows}, for more information. +@node Chain-loading +@subsection Chain-loading an OS + +Operating systems that do not support Multiboot and do not have specific +support in GRUB (specific support is available for Linux, FreeBSD, NetBSD +and OpenBSD) must be chain-loaded, which involves loading another boot +loader and jumping to it in real mode. + +The @command{chainloader} command (@pxref{chainloader}) is used to set this +up. It is normally also necessary to load some GRUB modules and set the +appropriate root device. Putting this together, we get something like this, +for a Windows system on the first partition of the first hard disk: + +@verbatim +menuentry "Windows" { + insmod chain + insmod ntfs + set root=(hd0,1) + chainloader +1 +} +@end verbatim +@c FIXME: document UUIDs. + +On systems with multiple hard disks, an additional workaround may be +required. @xref{DOS/Windows}. + +Chain-loading is only supported on PC BIOS and EFI platforms. + + @node OS-specific notes @section Some caveats on OS-specific issues @@ -655,6 +684,9 @@ Here, we describe some caveats on several operating systems. @menu * GNU/Hurd:: * GNU/Linux:: +* DOS/Windows:: +* SCO UnixWare:: +* QNX:: @end menu @@ -696,6 +728,87 @@ the size, run the command @command{uppermem} @emph{before} loading the kernel. @xref{uppermem}, for more information. +@node DOS/Windows +@subsection DOS/Windows + +GRUB cannot boot DOS or Windows directly, so you must chain-load them +(@pxref{Chain-loading}). However, their boot loaders have some critical +deficiencies, so it may not work to just chain-load them. To overcome +the problems, GRUB provides you with two helper functions. + +If you have installed DOS (or Windows) on a non-first hard disk, you +have to use the disk swapping technique, because that OS cannot boot +from any disks but the first one. The workaround used in GRUB is the +command @command{drivemap} (@pxref{drivemap}), like this: + +@example +drivemap -s (hd0) (hd1) +@end example + +This performs a @dfn{virtual} swap between your first and second hard +drive. + +@strong{Caution:} This is effective only if DOS (or Windows) uses BIOS +to access the swapped disks. If that OS uses a special driver for the +disks, this probably won't work. + +Another problem arises if you installed more than one set of DOS/Windows +onto one disk, because they could be confused if there are more than one +primary partitions for DOS/Windows. Certainly you should avoid doing +this, but there is a solution if you do want to do so. Use the partition +hiding/unhiding technique. + +If GRUB @dfn{hides} a DOS (or Windows) partition (@pxref{parttool}), DOS (or +Windows) will ignore the partition. If GRUB @dfn{unhides} a DOS (or Windows) +partition, DOS (or Windows) will detect the partition. Thus, if you have +installed DOS (or Windows) on the first and the second partition of the +first hard disk, and you want to boot the copy on the first partition, do +the following: + +@example +@group +parttool (hd0,1) hidden- +parttool (hd0,2) hidden+ +set root=(hd0,1) +chainloader +1 +parttool @verb{'${root}'} boot+ +boot +@end group +@end example + + +@node SCO UnixWare +@subsection SCO UnixWare + +It is known that the signature in the boot loader for SCO UnixWare is +wrong, so you will have to specify the option @option{--force} to +@command{chainloader} (@pxref{chainloader}), like this: + +@example +@group +set root=(hd1,1) +chainloader --force +1 +parttool @verb{'${root}'} boot+ +boot +@end group +@end example + + +@node QNX +@subsection QNX + +QNX seems to use a bigger boot loader, so you need to boot it up, like +this: + +@example +@group +set root=(hd1,2) +chainloader +4 +boot +@end group +@end example + + @node Configuration @chapter Writing your own configuration file @@ -1325,6 +1438,7 @@ you forget a command, you can run the command @command{help} * configfile:: Load a configuration file * crc:: Calculate CRC32 checksums * date:: Display or set current date and time +* drivemap:: Map a drive to another * echo:: Display a line of text * export:: Export an environment variable * gettext:: Translate a string @@ -1334,6 +1448,7 @@ you forget a command, you can run the command @command{help} * insmod:: Insert a module * keystatus:: Check key modifier status * ls:: List devices or files +* parttool:: Modify partition table entries * play:: Play a tune * reboot:: Reboot your computer * set:: Set an environment variable @@ -1399,11 +1514,12 @@ grub> @kbd{cat /etc/fstab} @deffn Command chainloader [@option{--force}] file Load @var{file} as a chain-loader. Like any other file loaded by the -filesystem code, it can use the blocklist notation to grab the first -sector of the current partition with @samp{+1}. If you specify the -option @option{--force}, then load @var{file} forcibly, whether it has a -correct signature or not. This is required when you want to load a -defective boot loader, such as SCO UnixWare 7.1 (@pxref{SCO UnixWare}). +filesystem code, it can use the blocklist notation (@pxref{Block list +syntax}) to grab the first sector of the current partition with @samp{+1}. +If you specify the option @option{--force}, then load @var{file} forcibly, +whether it has a correct signature or not. This is required when you want to +load a defective boot loader, such as SCO UnixWare 7.1 (@pxref{SCO +UnixWare}). @end deffn @@ -1458,6 +1574,32 @@ hour, minute, and second unchanged. @end deffn +@node drivemap +@subsection drivemap + +@deffn Command drivemap @option{-l}|@option{-r}|[@option{-s}] @ + from_drive to_drive +Without options, map the drive @var{from_drive} to the drive @var{to_drive}. +This is necessary when you chain-load some operating systems, such as DOS, +if such an OS resides at a non-first drive. For convenience, any partition +suffix on the drive is ignored, so you can safely use @verb{'${root}'} as a +drive specification. + +With the @option{-s} option, perform the reverse mapping as well, swapping +the two drives. + +With the @option{-l} option, list the current mappings. + +With the @option{-r} option, reset all mappings to the default values. + +For example: + +@example +drivemap -s (hd0) (hd1) +@end example +@end deffn + + @node echo @subsection echo @@ -1605,6 +1747,41 @@ name syntax}), then list the contents of that directory. @end deffn +@node parttool +@subsection parttool + +@deffn Command parttool partition commands +Make various modifications to partition table entries. + +Each @var{command} is either a boolean option, in which case it must be +followed with @samp{+} or @samp{-} (with no intervening space) to enable or +disable that option, or else it takes a value in the form +@samp{@var{command}=@var{value}}. + +Currently, @command{parttool} is only useful on DOS partition tables (also +known as Master Boot Record, or MBR). On these partition tables, the +following commands are available: + +@table @asis +@item @samp{boot} (boolean) +When enabled, this makes the selected partition be the active (bootable) +partition on its disk, clearing the active flag on all other partitions. +This command is limited to @emph{primary} partitions. + +@item @samp{type} (value) +Change the type of an existing partition. The value must be a number in the +range 0-0xFF (prefix with @samp{0x} to enter it in hexadecimal). + +@item @samp{hidden} (boolean) +When enabled, this hides the selected partition by setting the @dfn{hidden} +bit in its partition type code; when disabled, unhides the selected +partition by clearing this bit. This is useful only when booting DOS or +Wwindows and multiple primary FAT partitions exist in one disk. See also +@ref{DOS/Windows}. +@end table +@end deffn + + @node play @subsection play From ca0afd5bab02d1e26dae496435b48647e44e08a8 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 13:11:33 +0100 Subject: [PATCH 63/96] * docs/grub.texi (SCO UnixWare): Remove, at Vladimir's request and per the GNU Coding Standards; this is now too obscure to be worth documenting. (QNX): Likewise. (chainloader): Remove cross-reference to `SCO UnixWare'. --- ChangeLog | 8 ++++++++ docs/grub.texi | 37 +------------------------------------ 2 files changed, 9 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index b0fc06848..61e4ea8ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (SCO UnixWare): Remove, at Vladimir's request and + per the GNU Coding Standards; this is now too obscure to be worth + documenting. + (QNX): Likewise. + (chainloader): Remove cross-reference to `SCO UnixWare'. + 2010-06-02 Colin Watson * docs/grub.texi (Chain-loading): New section. diff --git a/docs/grub.texi b/docs/grub.texi index 5f2e5e36a..1f0c2083e 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -685,8 +685,6 @@ Here, we describe some caveats on several operating systems. * GNU/Hurd:: * GNU/Linux:: * DOS/Windows:: -* SCO UnixWare:: -* QNX:: @end menu @@ -777,38 +775,6 @@ boot @end example -@node SCO UnixWare -@subsection SCO UnixWare - -It is known that the signature in the boot loader for SCO UnixWare is -wrong, so you will have to specify the option @option{--force} to -@command{chainloader} (@pxref{chainloader}), like this: - -@example -@group -set root=(hd1,1) -chainloader --force +1 -parttool @verb{'${root}'} boot+ -boot -@end group -@end example - - -@node QNX -@subsection QNX - -QNX seems to use a bigger boot loader, so you need to boot it up, like -this: - -@example -@group -set root=(hd1,2) -chainloader +4 -boot -@end group -@end example - - @node Configuration @chapter Writing your own configuration file @@ -1518,8 +1484,7 @@ filesystem code, it can use the blocklist notation (@pxref{Block list syntax}) to grab the first sector of the current partition with @samp{+1}. If you specify the option @option{--force}, then load @var{file} forcibly, whether it has a correct signature or not. This is required when you want to -load a defective boot loader, such as SCO UnixWare 7.1 (@pxref{SCO -UnixWare}). +load a defective boot loader, such as SCO UnixWare 7.1. @end deffn From 0b35b2a9211feafd80a1a203e793a1e68ccbe5a3 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 13:57:13 +0100 Subject: [PATCH 64/96] * util/grub.d/00_header.in: Add safety check to make sure that ${locale_dir} exists before trying to probe it. --- ChangeLog | 5 +++++ util/grub.d/00_header.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 61e4ea8ec..fb73905e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-02 Colin Watson + + * util/grub.d/00_header.in: Add safety check to make sure that + ${locale_dir} exists before trying to probe it. + 2010-06-02 Colin Watson * docs/grub.texi (SCO UnixWare): Remove, at Vladimir's request and diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index df8f5dfaa..0a5cfac18 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -195,7 +195,7 @@ EOF esac # Gettext variables and module -if [ "x${LANG}" != "xC" ] ; then +if [ "x${LANG}" != "xC" ] && [ -d "${locale_dir}" ] ; then prepare_grub_to_access_device $(${grub_probe} --target=device ${locale_dir}) cat << EOF set locale_dir=(\$root)$(make_system_path_relative_to_its_root ${locale_dir}) From 11dccbfd4d2ed5e91e5f4f767161a0095ef01025 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:45:43 +0200 Subject: [PATCH 65/96] Sort scsi_cmd_t. --- include/grub/scsicmd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/grub/scsicmd.h b/include/grub/scsicmd.h index f9a7cb200..9cc5afe72 100644 --- a/include/grub/scsicmd.h +++ b/include/grub/scsicmd.h @@ -147,14 +147,14 @@ struct grub_scsi_write12 typedef enum { - grub_scsi_cmd_inquiry = 0x12, grub_scsi_cmd_test_unit_ready = 0x00, + grub_scsi_cmd_request_sense = 0x03, + grub_scsi_cmd_inquiry = 0x12, grub_scsi_cmd_read_capacity = 0x25, grub_scsi_cmd_read10 = 0x28, grub_scsi_cmd_write10 = 0x2a, grub_scsi_cmd_read12 = 0xa8, grub_scsi_cmd_write12 = 0xaa, - grub_scsi_cmd_request_sense = 0x03 } grub_scsi_cmd_t; typedef enum From f0e6cceb813e626d313ae6b15e03683b82b322ca Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:46:37 +0200 Subject: [PATCH 66/96] Remove leftover early debug exit. --- commands/usbtest.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/commands/usbtest.c b/commands/usbtest.c index 7d1f85cfd..191c4e4df 100644 --- a/commands/usbtest.c +++ b/commands/usbtest.c @@ -148,8 +148,6 @@ usb_iterate (grub_usb_device_t dev) grub_printf ("%s speed device\n", usb_devspeed[dev->speed]); - return 0; - for (i = 0; i < descdev->configcnt; i++) { struct grub_usb_desc_config *config; From 8bd3a1fb3027c7e05be06d5145bd8d16ee1bcbeb Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:46:55 +0200 Subject: [PATCH 67/96] Add necessarry cast --- disk/scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/disk/scsi.c b/disk/scsi.c index dffabc26e..5d3e50966 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -460,7 +460,7 @@ grub_scsi_open (const char *name, grub_disk_t disk) grub_dprintf ("scsi", "blocks=%u, blocksize=%u\n", scsi->size, scsi->blocksize); grub_dprintf ("scsi", "Disk total 512 sectors = %llu\n", - disk->total_sectors); + (unsigned long long) disk->total_sectors); return GRUB_ERR_NONE; } From f133a8a74b31c085e68831f76a7e78a8c49629da Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:48:10 +0200 Subject: [PATCH 68/96] Enable USB on 64-bit (still won't work with >= 4GiB memory). --- bus/pci.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bus/pci.c b/bus/pci.c index 3e2126962..1635e889b 100644 --- a/bus/pci.c +++ b/bus/pci.c @@ -21,7 +21,8 @@ #include #include -#if GRUB_TARGET_SIZEOF_VOID_P == 4 +/* FIXME: correctly support 64-bit architectures. */ +/* #if GRUB_TARGET_SIZEOF_VOID_P == 4 */ struct grub_pci_dma_chunk * grub_memalign_dma32 (grub_size_t align, grub_size_t size) { @@ -33,7 +34,7 @@ grub_dma_free (struct grub_pci_dma_chunk *ch) { grub_free (ch); } -#endif +/* #endif */ #ifdef GRUB_MACHINE_MIPS_YEELOONG volatile void * From 5d538b8b4a17de54cda284ee1ba081afbef8f978 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:49:22 +0200 Subject: [PATCH 69/96] Use memset --- bus/usb/usb.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/bus/usb/usb.c b/bus/usb/usb.c index 7df148333..c872e9276 100644 --- a/bus/usb/usb.c +++ b/bus/usb/usb.c @@ -105,10 +105,7 @@ grub_usb_clear_halt (grub_usb_device_t dev, int endpoint) grub_usb_err_t grub_usb_set_configuration (grub_usb_device_t dev, int configuration) { - int i; - - for (i = 0; i < 256; i++) - dev->toggle[i] = 0; + grub_memset (dev->toggle, 0, sizeof (dev->toggle)); return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT | GRUB_USB_REQTYPE_STANDARD From 7db51e329b7e8f0cdeaea60b2fd866105406d9c4 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:51:54 +0200 Subject: [PATCH 70/96] Remove double defines and use dma_free --- bus/usb/ohci.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index a42d9fee1..956a27292 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -339,10 +339,8 @@ grub_ohci_pci_iter (grub_pci_device_t dev, return 0; fail: -#ifndef GRUB_MACHINE_MIPS_YEELOONG if (o) - grub_free ((void *) o->hcca); -#endif + grub_dma_free (o->hcca_chunk); grub_free (o); return 0; @@ -883,11 +881,6 @@ grub_ohci_transfer (grub_usb_controller_t dev, return err; } -#define GRUB_OHCI_SET_PORT_ENABLE (1 << 1) -#define GRUB_OHCI_CLEAR_PORT_ENABLE (1 << 0) -#define GRUB_OHCI_SET_PORT_RESET (1 << 4) -#define GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE (1 << 20) - static grub_err_t grub_ohci_portstatus (grub_usb_controller_t dev, unsigned int port, unsigned int enable) From 49396b4f61726411e4d7bfaefbf2f62e93763102 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 2 Jun 2010 16:52:16 +0200 Subject: [PATCH 71/96] Add ChangeLog --- ChangeLog | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5072a6026..a693e4385 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,122 @@ +2010-06-02 Aleš Nesrsta + + Finally make USB usable. + + * bus/usb/ohci.c (grub_ohci_reg_t): Add missing values. + (GRUB_OHCI_RHUB_PORT_POWER_MASK): New macro. + (GRUB_OHCI_RHUB_PORT_ALL_POWERED): Likewise. + (GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK): Likewise. + (GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT): Likewise. + (GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT): Likewise. + (GRUB_OHCI_FSMPS): Likewise. + (GRUB_OHCI_PERIODIC_START): Likewise. + (GRUB_OHCI_FRAME_INTERVAL): Likewise. + (GRUB_OHCI_SET_PORT_ENABLE): Likewise. + (GRUB_OHCI_CLEAR_PORT_ENABLE): Likewise. + (GRUB_OHCI_SET_PORT_RESET): Likewise. + (GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE): Likewise. + * bus/usb/ohci.c (grub_ohci_pci_iter): Various important fixups. + (grub_ohci_transaction): Likewise. + (grub_ohci_transfer): Improve condition detection algorithms. + Handle toggle property. Program the transactions correctly. + Improve error handling. Various important fixups. + (grub_ohci_portstatus): Put register writes in right order. + * bus/usb/uhci.c (grub_free_queue): Compute last_trans. + (grub_uhci_transfer): Don't show "failed" message on success. + * bus/usb/usb.c (grub_usb_set_configuration): Zero-fill whole "toggle" + array. + (grub_usb_device_initialize): Read first 8 bytes of descriptor to + determine its size. + * bus/usb/usbtrans.c (grub_usb_control_msg): Use descdev.maxsize0 even + before initialization is completed. Use IN direction for empty + transfers. Use last_trans and compute toggle. + * include/grub/usbtrans.h (grub_usb_transfer): New field last_trans. + (GRUB_USB_FEATURE_ENDP_HALT): Correct the value. + (GRUB_USB_FEATURE_DEV_REMOTE_WU): Likewise. + (GRUB_USB_FEATURE_TEST_MODE): Likewise. + * include/grub/usb.h (grub_usb_err_t): New value GRUB_USB_ERR_UNRECOVERABLE. + (grub_usb_device): Increase toggle to 256. + (grub_usbms_subclass_t): New values GRUB_USBMS_SUBCLASS_RBC, + GRUB_USBMS_SUBCLASS_MMC2, GRUB_USBMS_SUBCLASS_UFI and + GRUB_USBMS_SUBCLASS_SFF8070. + * include/grub/scsicmd.h (grub_scsi_test_unit_ready): New structure. + (grub_scsi_inquiry): New member page and alloc_length. + (grub_scsi_request_sense): New structure. + (grub_scsi_request_sense_data): Likewise. + (grub_scsi_read_capacity): New fields logical_block_addr, PMI and + control. + * disk/scsi.c (grub_scsi_request_sense): New function. + (grub_scsi_test_unit_ready): Likewise. + (grub_scsi_inquiry): Fill new fields. + (grub_scsi_read_capacity): Likewise. + (grub_scsi_read10): Add request sense at the end. + (grub_scsi_read12): Likewise. + (grub_scsi_write10): Likewise. + (grub_scsi_write12): Likewise. + (grub_scsi_open): Add Test Unit Ready. + * disk/usbms.c (grub_usbms_finddevs): Check configcnt. + Support additional subclasses. Con't clear halt yet. Activate the + proper config. Calculate LUNs correctly. + (grub_usbms_transfer): Various important fixups. + +2010-06-02 Vladimir Serbinenko + + * bus/pci.c (grub_pci_iterate) [GRUB_MACHINE_MIPS_YEELOONG]: Skip ghosts. + * bus/usb/ohci.c (grub_ohci_portstatus): Handle R/WC correctly. + (grub_ohci_fini_hw): New function. + (grub_ohci_restore_hw): Likewise. + (GRUB_MOD_INIT(ohci)): Register preboot hook. + (GRUB_MOD_FINI(ohci)): Shutdown OHCI. + * term/usb_keyboard.c: Remove include of grub/machine/console.h. + +2010-06-02 Vladimir Serbinenko + + Dedicated DMA allocations. + + * bus/pci.c (grub_memalign_dma32): New function + (grub_dma_free): Likewise. + (grub_dma_get_virt): Likewise. + (grub_dma_get_phys): Likewise. + * bus/usb/ohci.c (grub_ohci): New members hcca_addr and hcca_chunk. + (grub_ohci_pci_iter): Use dma32_alloc. + (grub_ohci_transfer): Likewise. + * bus/usb/usbtrans.c (grub_usb_control_msg): Likewise. + (grub_usb_bulk_readwrite): Likewise. + * include/grub/pci.h: Add declarations. + +2010-06-02 Vladimir Serbinenko + + CS5536 support. + + * bus/cs5536.c: New file. + * bus/usb/ohci.c (grub_ohci_pci_iter): Check for CS5536. + * conf/i386.rmk (pkglib_MODULES): Add cs5536.mod. + (cs5536_mod_SOURCES): New variable. + (cs5536_mod_CFLAGS): Likewise. + (cs5536_mod_LDFLAGS): Likewise. + * conf/mips-yeeloong.rmk (kernel_img_HEADERS): Add cs5536.h and + machine/pci.h. + (kernel_img_SOURCES): Add bus/cs5536.c. + (pkglib_MODULES): Add usb.mod, usbtest.mod, ohci.mod, usbms.mod and + usb_keyboard.mod. + (usb_mod_SOURCES): New variable. + (usb_mod_CFLAGS): New variable. + (usb_mod_LDFLAGS): New variable. + (usbtest_mod_SOURCES): New variable. + (usbtest_mod_CFLAGS): New variable. + (usbtest_mod_LDFLAGS): New variable. + (ohci_mod_SOURCES): New variable. + (ohci_mod_CFLAGS): New variable. + (ohci_mod_LDFLAGS): New variable. + (usbms_mod_SOURCES): New variable. + (usbms_mod_CFLAGS): New variable. + (usbms_mod_LDFLAGS): New variable. + (usb_keyboard_mod_SOURCES): New variable. + (usb_keyboard_mod_CFLAGS): New variable. + (usb_keyboard_mod_LDFLAGS): New variable. + * include/grub/smbus.h: New file. + * include/grub/cs5536.h: New file. + 2010-05-28 Colin Watson * configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not From 0819fec8a1f8820bfdfac08e9c1e188136bedf29 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Wed, 2 Jun 2010 22:48:13 +0100 Subject: [PATCH 72/96] * docs/grub.texi (Simple configuration): Fix copy-and-paste typo. Thanks to Jordan Uggla for spotting this. --- ChangeLog | 5 +++++ docs/grub.texi | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 49583746c..8036c7fdb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-02 Colin Watson + + * docs/grub.texi (Simple configuration): Fix copy-and-paste typo. + Thanks to Jordan Uggla for spotting this. + 2010-06-02 Aleš Nesrsta Finally make USB usable. diff --git a/docs/grub.texi b/docs/grub.texi index 1f0c2083e..d73c03d9b 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -877,7 +877,7 @@ Valid terminal output names depend on the platform, but may include @samp{gfxterm} (graphics-mode output), @samp{ofconsole} (Open Firmware console), or @samp{vga_text} (VGA text output, mainly useful with Coreboot). -The default is to use the platform's native terminal input. +The default is to use the platform's native terminal output. @item GRUB_TERMINAL If this option is set, it overrides both @samp{GRUB_TERMINAL_INPUT} and From 9d9b5833508080ef4146e8fd4db3dcbd91fcf194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Thu, 3 Jun 2010 00:47:22 +0200 Subject: [PATCH 73/96] Handle all possible disk device names for NetBSD. --- ChangeLog | 6 ++++++ kern/emu/hostdisk.c | 41 +++++++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8036c7fdb..7279197ee 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-02 Grégoire Sutre + + * kern/emu/hostdisk.c (convert_system_partition_to_system_disk) + [__NetBSD__]: Handle all device names matching /dev/r[a-z]+[0-9][a-z]. + (find_partition_start) [__NetBSD__]: Correct error messages for NetBSD. + 2010-06-02 Colin Watson * docs/grub.texi (Simple configuration): Fix copy-and-paste typo. diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index ae2f7d9ad..fc62cca26 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -413,7 +413,11 @@ devmapper_fail: if (fd == -1) { grub_error (GRUB_ERR_BAD_DEVICE, +# if !defined(__NetBSD__) "cannot open `%s' while attempting to get disk geometry", dev); +# else /* defined(__NetBSD__) */ + "cannot open `%s' while attempting to get disk label", dev); +# endif /* !defined(__NetBSD__) */ return 0; } @@ -425,7 +429,11 @@ devmapper_fail: # endif /* !defined(__NetBSD__) */ { grub_error (GRUB_ERR_BAD_DEVICE, +# if !defined(__NetBSD__) "cannot get disk geometry of `%s'", dev); +# else /* defined(__NetBSD__) */ + "cannot get disk label of `%s'", dev); +# endif /* !defined(__NetBSD__) */ close (fd); return 0; } @@ -1256,22 +1264,28 @@ devmapper_out: return path; #elif defined(__NetBSD__) - /* NetBSD uses "/dev/r[wsc]d[0-9]+[a-z]". */ + /* NetBSD uses "/dev/r[a-z]+[0-9][a-z]". */ char *path = xstrdup (os_dev); - if (strncmp ("/dev/rwd", path, 8) == 0 || - strncmp ("/dev/rsd", path, 8) == 0 || - strncmp ("/dev/rcd", path, 8) == 0) + if (strncmp ("/dev/r", path, sizeof("/dev/r") - 1) == 0 && + (path[sizeof("/dev/r") - 1] >= 'a' && path[sizeof("/dev/r") - 1] <= 'z') && + strncmp ("fd", path + sizeof("/dev/r") - 1, sizeof("fd") - 1) != 0) /* not a floppy device name */ { - char *q; - q = path + strlen(path) - 1; /* last character */ - if (grub_isalpha(*q) && grub_isdigit(*(q-1))) - { - int rawpart = -1; + char *p; + for (p = path + sizeof("/dev/r"); *p >= 'a' && *p <= 'z'; p++); + if (grub_isdigit(*p)) + { + p++; + if ((*p >= 'a' && *p <= 'z') && (*(p+1) == '\0')) + { + /* path matches the required regular expression and + p points to its last character. */ + int rawpart = -1; # ifdef HAVE_GETRAWPARTITION - rawpart = getrawpartition(); + rawpart = getrawpartition(); # endif /* HAVE_GETRAWPARTITION */ - if (rawpart >= 0) - *q = 'a' + rawpart; + if (rawpart >= 0) + *p = 'a' + rawpart; + } } } return path; @@ -1429,8 +1443,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev) return name; # else /* defined(__NetBSD__) */ /* Since os_dev and convert_system_partition_to_system_disk (os_dev) are - * different, we know that os_dev is of the form /dev/r[wsc]d[0-9]+[a-z] - * and in particular it cannot be a floppy device. */ + * different, we know that os_dev cannot be a floppy device. */ # endif /* !defined(__NetBSD__) */ start = find_partition_start (os_dev); From 795b593a475327352308dfba23aeb2217599c8df Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Thu, 3 Jun 2010 09:48:23 +0100 Subject: [PATCH 74/96] * INSTALL: Document several build requirements for optional features (libdevmapper, ncurses, libusb, SDL, FreeType, GNU Unifont). --- ChangeLog | 5 +++++ INSTALL | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7279197ee..d67e7efa4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-03 Colin Watson + + * INSTALL: Document several build requirements for optional features + (libdevmapper, ncurses, libusb, SDL, FreeType, GNU Unifont). + 2010-06-02 Grégoire Sutre * kern/emu/hostdisk.c (convert_system_partition_to_system_disk) diff --git a/INSTALL b/INSTALL index 7186d20db..44a442253 100644 --- a/INSTALL +++ b/INSTALL @@ -19,6 +19,21 @@ configuring the GRUB. * Flex 2.5.35 or later * Other standard GNU/Unix tools +On GNU/Linux, you also need: + +* libdevmapper (recommended) + +To build grub-emu, you need: + +* ncurses +* libusb (recommended) +* SDL (recommended) + +To build GRUB's graphical terminal (gfxterm), you need: + +* FreeType 2 or later +* GNU Unifont + If you use a development snapshot or want to hack on GRUB you may need the following. From 9cdfe32f0916b227ed0ae1211bc1089684063207 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 4 Jun 2010 13:38:10 +0100 Subject: [PATCH 75/96] * util/grub-mkimage.c: Make target-related error messages slightly more helpful; -O talks about "format". Explicitly point to the use of -O if no target is specified. Reported by: Didier Raboud (Debian bug #584415). --- ChangeLog | 7 +++++++ util/grub-mkimage.c | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d67e7efa4..fd2f8ae72 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-04 Colin Watson + + * util/grub-mkimage.c: Make target-related error messages slightly + more helpful; -O talks about "format". Explicitly point to the use + of -O if no target is specified. + Reported by: Didier Raboud (Debian bug #584415). + 2010-06-03 Colin Watson * INSTALL: Document several build requirements for optional features diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 6366a9803..4e39450df 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -1253,7 +1253,7 @@ main (int argc, char *argv[]) image_target = &image_targets[i]; if (!image_target) { - printf ("unknown target %s\n", optarg); + printf ("unknown target format %s\n", optarg); usage (1); } break; @@ -1322,7 +1322,7 @@ main (int argc, char *argv[]) if (!image_target) { - printf ("Target not specified.\n"); + printf ("Target format not specified (use the -O option).\n"); usage (1); } From f28a9212b4465c2b106b4abd057779ddc3c69b3b Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 4 Jun 2010 13:53:30 +0100 Subject: [PATCH 76/96] =?UTF-8?q?*=20util/grub-mkconfig=5Flib.in=20(prepar?= =?UTF-8?q?e=5Fgrub=5Fto=5Faccess=5Fdevice):=20Prepend=20"part=5F"=20to=20?= =?UTF-8?q?partmap=20module=20names,=20in=20line=20with=20grub-install.=20?= =?UTF-8?q?Reported=20by:=20Jind=C5=99ich=20Makovi=C4=8Dka=20(Debian=20bug?= =?UTF-8?q?=20#584426).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ChangeLog | 6 ++++++ util/grub-mkconfig_lib.in | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index fd2f8ae72..65a3c69b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-04 Colin Watson + + * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Prepend + "part_" to partmap module names, in line with grub-install. + Reported by: Jindřich Makovička (Debian bug #584426). + 2010-06-04 Colin Watson * util/grub-mkimage.c: Make target-related error messages slightly diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in index 7ec8cb5be..14ea1842f 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in @@ -107,7 +107,7 @@ prepare_grub_to_access_device () partmap="`${grub_probe} --device ${device} --target=partmap`" for module in ${partmap} ; do - echo "insmod ${module}" + echo "insmod part_${module}" done fs="`${grub_probe} --device ${device} --target=fs`" From 71c3809882f5382ef40e434c7ac1a76d020f3577 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 5 Jun 2010 20:44:44 +0100 Subject: [PATCH 77/96] * util/grub.d/00_header.in: Quote values assigned to `saved_entry', in case they contain spaces. --- ChangeLog | 5 +++++ util/grub.d/00_header.in | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 65a3c69b8..779973f1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-05 Colin Watson + + * util/grub.d/00_header.in: Quote values assigned to `saved_entry', + in case they contain spaces. + 2010-06-04 Colin Watson * util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Prepend diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 0a5cfac18..199a1d7af 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -62,7 +62,7 @@ EOF fi cat < Date: Mon, 7 Jun 2010 14:15:57 +0100 Subject: [PATCH 78/96] * util/grub-mkpasswd-pbkdf2.c (main): Rename top-level `c' variable to `count', fixing variable shadowing that broke the -c option. --- ChangeLog | 7 ++++++- util/grub-mkpasswd-pbkdf2.c | 9 +++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 779973f1e..07c262dc2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,9 @@ -2010-06-05 Colin Watson +2010-06-07 Colin Watson + + * util/grub-mkpasswd-pbkdf2.c (main): Rename top-level `c' variable + to `count', fixing variable shadowing that broke the -c option. + +2010-06-05 Colin Watson * util/grub.d/00_header.in: Quote values assigned to `saved_entry', in case they contain spaces. diff --git a/util/grub-mkpasswd-pbkdf2.c b/util/grub-mkpasswd-pbkdf2.c index a00b1e990..944c6c46a 100644 --- a/util/grub-mkpasswd-pbkdf2.c +++ b/util/grub-mkpasswd-pbkdf2.c @@ -112,7 +112,7 @@ hexify (char *hex, grub_uint8_t *bin, grub_size_t n) int main (int argc, char *argv[]) { - unsigned int c = 10000, buflen = 64, saltlen = 64; + unsigned int count = 10000, buflen = 64, saltlen = 64; char *pass1, *pass2; char *bufhex, *salthex; gcry_err_code_t gcry_err; @@ -137,7 +137,7 @@ main (int argc, char *argv[]) switch (c) { case 'c': - c = strtoul (optarg, NULL, 0); + count = strtoul (optarg, NULL, 0); break; case 'l': @@ -307,7 +307,7 @@ main (int argc, char *argv[]) gcry_err = grub_crypto_pbkdf2 (GRUB_MD_SHA512, (grub_uint8_t *) pass1, strlen (pass1), salt, saltlen, - c, buf, buflen); + count, buf, buflen); memset (pass1, 0, strlen (pass1)); free (pass1); @@ -327,7 +327,8 @@ main (int argc, char *argv[]) hexify (bufhex, buf, buflen); hexify (salthex, salt, saltlen); - printf ("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n", c, salthex, bufhex); + printf ("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n", + count, salthex, bufhex); memset (buf, 0, buflen); memset (bufhex, 0, 2 * buflen); free (buf); From e1cbcc40a45e7fe0f5d0dbf42a2815eb7b832efe Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 14:22:40 +0100 Subject: [PATCH 79/96] * util/grub.d/00_header.in: Add some more quoting (of "${prev_saved_entry}" and "${boot_once}") needed to make savedefault work again. Reported by: Mario 'BitKoenig' Holbe (Debian bug #584812). --- ChangeLog | 7 +++++++ util/grub.d/00_header.in | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 07c262dc2..5568cbd3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-07 Colin Watson + + * util/grub.d/00_header.in: Add some more quoting (of + "${prev_saved_entry}" and "${boot_once}") needed to make savedefault + work again. + Reported by: Mario 'BitKoenig' Holbe (Debian bug #584812). + 2010-06-07 Colin Watson * util/grub-mkpasswd-pbkdf2.c (main): Rename top-level `c' variable diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in index 199a1d7af..791840a60 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in @@ -61,7 +61,7 @@ set default="${GRUB_DEFAULT}" EOF fi cat < Date: Mon, 7 Jun 2010 14:32:12 +0100 Subject: [PATCH 80/96] * docs/grub.texi (Filesystem): Refer to `search' instead of `find'. (password): New section. (password_pbkdf2): New section. (search): New section. (Security): New section. (Troubleshooting): New section, currently very incomplete. (Invoking grub-mkpasswd-pbkdf2): New section. (Internals): New section, currently very incomplete. --- ChangeLog | 11 ++ docs/grub.texi | 317 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 326 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5568cbd3a..3a3df4c5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-06-07 Colin Watson + + * docs/grub.texi (Filesystem): Refer to `search' instead of `find'. + (password): New section. + (password_pbkdf2): New section. + (search): New section. + (Security): New section. + (Troubleshooting): New section, currently very incomplete. + (Invoking grub-mkpasswd-pbkdf2): New section. + (Internals): New section, currently very incomplete. + 2010-06-07 Colin Watson * util/grub.d/00_header.in: Add some more quoting (of diff --git a/docs/grub.texi b/docs/grub.texi index d73c03d9b..837607d62 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -35,6 +35,7 @@ Invariant Sections. * GRUB: (grub). The GRand Unified Bootloader * grub-install: (grub)Invoking grub-install. Install GRUB on your drive * grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration +* grub-mkpasswd-pbkdf2: (grub)Invoking grub-mkpasswd-pbkdf2. @end direntry @setchapternewpage odd @@ -84,9 +85,12 @@ This edition documents version @value{VERSION}. * Filesystem:: Filesystem syntax and semantics * Interface:: The menu and the command-line * Commands:: The list of available builtin commands +* Security:: Authentication and authorisation * Troubleshooting:: Error messages produced by GRUB * Invoking grub-install:: How to use the GRUB installer * Invoking grub-mkconfig:: Generate a GRUB configuration file +* Invoking grub-mkpasswd-pbkdf2:: + Generate GRUB password hashes * Obtaining and Building GRUB:: How to obtain and build GRUB * Reporting bugs:: Where you should send a bug report * Future:: Some future plans on GRUB @@ -1041,8 +1045,8 @@ GRUB uses a special syntax for specifying disk drives which can be accessed by BIOS. Because of BIOS limitations, GRUB cannot distinguish between IDE, ESDI, SCSI, or others. You must know yourself which BIOS device is equivalent to which OS device. Normally, that will be clear if -you see the files in a device or use the command @command{find} -(@pxref{find}). +you see the files in a device or use the command @command{search} +(@pxref{search}). @menu * Device syntax:: How to specify devices @@ -1415,8 +1419,11 @@ you forget a command, you can run the command @command{help} * keystatus:: Check key modifier status * ls:: List devices or files * parttool:: Modify partition table entries +* password:: Set a clear-text password +* password_pbkdf2:: Set a hashed password * play:: Play a tune * reboot:: Reboot your computer +* search:: Search devices by file, label, or UUID * set:: Set an environment variable * unset:: Unset an environment variable @end menu @@ -1747,6 +1754,25 @@ Wwindows and multiple primary FAT partitions exist in one disk. See also @end deffn +@node password +@subsection password + +@deffn Command password user clear-password +Define a user named @var{user} with password @var{clear-password}. +@xref{Security}. +@end deffn + + +@node password_pbkdf2 +@subsection password_pbkdf2 + +@deffn Command password_pbkdf2 user hashed-password +Define a user named @var{user} with password hash @var{hashed-password}. +Use @command{grub-mkpasswd-pbkdf2} (@pxref{Invoking grub-mkpasswd-pbkdf2}) +to generate password hashes. @xref{Security}. +@end deffn + + @node play @subsection play @@ -1774,6 +1800,29 @@ Reboot the computer. @end deffn +@node search +@subsection search + +@deffn Command search @ + [@option{--file}|@option{--label}|@option{--fs-uuid}] @ + [@option{--set} var] [@option{--no-floppy}] name +Search devices by file (@option{-f}, @option{--file}), filesystem label +(@option{-l}, @option{--label}), or filesystem UUID (@option{-u}, +@option{--fs-uuid}). + +If the @option{--set} option is used, the first device found is set as the +value of environment variable @var{var}. The default variable is +@samp{root}. + +The @option{--no-floppy} option prevents searching floppy devices, which can +be slow. + +The @samp{search.file}, @samp{search.fs_label}, and @samp{search.fs_uuid} +commands are aliases for @samp{search --file}, @samp{search --label}, and +@samp{search --fs-uuid} respectively. +@end deffn + + @node set @subsection set @@ -1791,6 +1840,135 @@ Unset the environment variable @var{envvar}. @end deffn +@node Security +@chapter Authentication and authorisation + +By default, the boot loader interface is accessible to anyone with physical +access to the console: anyone can select and edit any menu entry, and anyone +can get direct access to a GRUB shell prompt. For most systems, this is +reasonable since anyone with direct physical access has a variety of other +ways to gain full access, and requiring authentication at the boot loader +level would only serve to make it difficult to recover broken systems. + +However, in some environments, such as kiosks, it may be appropriate to lock +down the boot loader to require authentication before performing certain +operations. + +The @samp{password} (@pxref{password}) and @samp{password_pbkdf2} +(@pxref{password_pbkdf2}) commands can be used to define users, each of +which has an associated password. @samp{password} sets the password in +plain text, requiring @file{grub.cfg} to be secure; @samp{password_pbkdf2} +sets the password hashed using the Password-Based Key Derivation Function +(RFC 2898), requiring the use of @command{grub-mkpasswd-pbkdf2} +(@pxref{Invoking grub-mkpasswd-pbkdf2}) to generate password hashes. + +In order to enable authentication support, the @samp{superusers} environment +variable must be set to a list of usernames, separated by any of spaces, +commas, semicolons, pipes, or ampersands. Superusers are permitted to use +the GRUB command line, edit menu entries, and execute any menu entry. + +Other users may be given access to specific menu entries by giving a list of +usernames (as above) using the @kbd{--users} option to the @samp{menuentry} +command (@pxref{menuentry}). + +Putting this together, a typical @file{grub.cfg} fragment might look like +this: + +@example +@group +set superusers="root" +password_pbkdf2 root grub.pbkdf2.sha512.10000.biglongstring +password user1 insecure + +menuentry "Superusers only" @{ + set root=(hd0,1) + linux /vmlinuz +@} + +menuentry "May be run by user1" --users user1 @{ + set root=(hd0,2) + chainloader +1 +@} +@end group +@end example + +The @command{grub-mkconfig} program does not yet have built-in support for +generating configuration files with authentication. You can use +@file{/etc/grub.d/40_custom} to add simple superuser authentication, by +adding @kbd{set superusers=} and @kbd{password} or @kbd{password_pbkdf2} +commands. + + +@node Troubleshooting +@chapter Error messages produced by GRUB + +@menu +* GRUB only offers a rescue shell:: +@end menu + + +@node GRUB only offers a rescue shell +@section GRUB only offers a rescue shell + +GRUB's normal start-up procedure involves setting the @samp{prefix} +environment variable to a value set in the core image by +@command{grub-install}, setting the @samp{root} variable to match, loading +the @samp{normal} module from the prefix, and running the @samp{normal} +command. This command is responsible for reading +@file{/boot/grub/grub.cfg}, running the menu, and doing all the useful +things GRUB is supposed to do. + +If, instead, you only get a rescue shell, this usually means that GRUB +failed to load the @samp{normal} module for some reason. It may be possible +to work around this temporarily: for instance, if the reason for the failure +is that @samp{prefix} is wrong (perhaps it refers to the wrong device, or +perhaps the path to @file{/boot/grub} was not correctly made relative to the +device), then you can correct this and enter normal mode manually: + +@example +@group +# Inspect the current prefix: +echo @verb{'${prefix}'} +# Set to the correct value, which might be something like this: +set prefix=(hd0,1)/grub +set root=(hd0,1) +insmod normal +normal +@end group +@end example + +However, any problem that leaves you in the rescue shell probably means that +GRUB was not correctly installed. It may be more useful to try to reinstall +it properly using @kbd{grub-install @var{device}} (@pxref{Invoking +grub-install}). When doing this, there are a few things to remember: + +@itemize @bullet{} +@item +Drive ordering in your operating system may not be the same as the boot +drive ordering used by your firmware. Do not assume that your first hard +drive (e.g. @samp{/dev/sda}) is the one that your firmware will boot from. + +@item +At least on BIOS systems, if you tell @command{grub-install} to install GRUB +to a partition but GRUB has already been installed in the master boot +record, then the GRUB installation in the partition will be ignored. + +@item +If possible, it is generally best to avoid installing GRUB to a partition +(unless it is a special partition for the use of GRUB alone, such as the +BIOS Boot Partition used on GPT). Doing this means that GRUB may stop being +able to read its core image due to a file system moving blocks around, such +as while defragmenting, running checks, or even during normal operation. +Installing to the whole disk device is normally more robust. + +@item +Check that GRUB actually knows how to read from the device and file system +containing @file{/boot/grub}. It will not be able to read from encrypted +devices, nor from file systems for which support has not yet been added to +GRUB. +@end itemize + + @node Invoking grub-install @chapter Invoking grub-install @@ -1858,6 +2036,34 @@ it to standard output. @end table +@node Invoking grub-mkpasswd-pbkdf2 +@chapter Invoking grub-mkpasswd-pbkdf2 + +The program @command{grub-mkpasswd-pbkdf2} generates password hashes for +GRUB (@pxref{Security}). + +@example +grub-mkpasswd-pbkdf2 +@end example + +@command{grub-mkpasswd-pbkdf2} accepts the following options: + +@table @option +@item -c @var{number} +@itemx --iteration-count=@var{number} +Number of iterations of the underlying pseudo-random function. Defaults to +10000. + +@item -l @var{number} +@itemx --buflen=@var{number} +Length of the generated hash. Defaults to 64. + +@item -s @var{number} +@itemx --salt=@var{number} +Length of the salt. Defaults to 64. +@end table + + @node Obtaining and Building GRUB @appendix How to obtain and build GRUB @@ -1976,6 +2182,113 @@ a look at @uref{http://www.gnu.org/software/grub/grub.html, the homepage}. +@node Internals +@appendix Hacking GRUB + +@menu +* Getting the source code:: +* Finding your way around:: +@end menu + + +@node Getting the source code +@section Getting the source code + +GRUB is maintained using the @uref{http://bazaar-vcs.org/, Bazaar revision +control system}. To fetch the primary development branch: + +@example +bzr get http://bzr.savannah.gnu.org/r/grub/trunk/grub +@end example + +The GRUB developers maintain several other branches with work in progress. +Of these, the most interesting is the experimental branch, which is a +staging area for new code which we expect to eventually merge into trunk but +which is not yet ready: + +@example +bzr get http://bzr.savannah.gnu.org/r/grub/branches/experimental +@end example + +Once you have used @kbd{bzr get} to fetch an initial copy of a branch, you +can use @kbd{bzr pull} to keep it up to date. If you have modified your +local version, you may need to resolve conflicts when pulling. + + +@node Finding your way around +@section Finding your way around + +Here is a brief map of the GRUB code base. + +GRUB uses Autoconf, but not (yet) Automake. The top-level build rules are +in @file{configure.ac}, @file{Makefile.in}, and @file{conf/*.rmk}. Each +@file{conf/*.rmk} file represents a particular target configuration, and is +processed into GNU Make rules by @file{genmk.rb} (which you only need to +look at if you are extending the build system). If you are adding a new +module which follows an existing pattern, such as a new command or a new +filesystem implementation, it is usually easiest to grep @file{conf/*.rmk} +for an existing example of that pattern to find out where it should be +added. + +Low-level boot code, such as the MBR implementation on PC BIOS systems, is +in the @file{boot/} directory. + +The GRUB kernel is in @file{kern/}. This contains core facilities such as +the device, disk, and file frameworks, environment variable handling, list +processing, and so on. The kernel should contain enough to get up to a +rescue prompt. Header files for kernel facilities, among others, are in +@file{include/}. + +Terminal implementations are in @file{term/}. + +Disk access code is spread across @file{disk/} (for accessing the disk +devices themselves), @file{partmap/} (for interpreting partition table +data), and @file{fs/} (for accessing filesystems). Note that, with the odd +specialised exception, GRUB only contains code to @emph{read} from +filesystems and tries to avoid containing any code to @emph{write} to +filesystems; this lets us confidently assure users that GRUB cannot be +responsible for filesystem corruption. + +PCI and USB bus handling is in @file{bus/}. + +Video handling code is in @file{video/}. The graphical menu system uses +this heavily, but is in a separate directory, @file{gfxmenu/}. + +Most commands are implemented by files in @file{commands/}, with the +following exceptions: + +@itemize +@item +A few core commands live in @file{kern/corecmd.c}. + +@item +Commands related to normal mode live under @file{normal/}. + +@item +Commands that load and boot kernels live under @file{loader/}. + +@item +The @samp{loopback} command is really a disk device, and so lives in +@file{disk/loopback.c}. + +@item +The @samp{gettext} command lives under @file{gettext/}. + +@item +The @samp{loadfont} and @samp{lsfonts} commands live under @file{font/}. + +@item +The @samp{serial}, @samp{terminfo}, and @samp{background_image} commands +live under @file{term/}. + +@item +The @samp{efiemu_*} commands live under @file{efiemu/}. +@end itemize + +There are a few other special-purpose exceptions; grep for them if they +matter to you. + + @node Copying This Manual @appendix Copying This Manual From a6a700aa52768f6392337ddbb8798f99a895a018 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 21:10:29 +0100 Subject: [PATCH 81/96] * docs/grub.texi (Troubleshooting): `echo' is not usually available in the rescue shell, so recommend using `set' instead. Thanks, Jordan Uggla. --- ChangeLog | 6 ++++++ docs/grub.texi | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a3df4c5d..ddb55f17a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-07 Colin Watson + + * docs/grub.texi (Troubleshooting): `echo' is not usually available + in the rescue shell, so recommend using `set' instead. Thanks, + Jordan Uggla. + 2010-06-07 Colin Watson * docs/grub.texi (Filesystem): Refer to `search' instead of `find'. diff --git a/docs/grub.texi b/docs/grub.texi index 837607d62..f2d0c41bf 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1927,8 +1927,8 @@ device), then you can correct this and enter normal mode manually: @example @group -# Inspect the current prefix: -echo @verb{'${prefix}'} +# Inspect the current prefix (and other preset variables): +set # Set to the correct value, which might be something like this: set prefix=(hd0,1)/grub set root=(hd0,1) From ee75515e69598e0c4e6f53c24b3b8247e4a83170 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 21:26:30 +0100 Subject: [PATCH 82/96] * docs/grub.texi (Network): New section. (Device syntax): The network device is called `(pxe)' in GRUB 2, not `(nd)' as in GRUB Legacy. (pxe_unload): New section. --- ChangeLog | 7 +++++ docs/grub.texi | 85 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ddb55f17a..f9a0d2424 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-07 Colin Watson + + * docs/grub.texi (Network): New section. + (Device syntax): The network device is called `(pxe)' in GRUB 2, not + `(nd)' as in GRUB Legacy. + (pxe_unload): New section. + 2010-06-07 Colin Watson * docs/grub.texi (Troubleshooting): `echo' is not usually available diff --git a/docs/grub.texi b/docs/grub.texi index f2d0c41bf..37016b175 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -970,6 +970,78 @@ that file, making sure to leave at least the first two lines intact. @section Writing full configuration files directly +@node Network +@chapter Booting GRUB from the network + +The following instructions only work on PC BIOS systems where the Preboot +eXecution Environment (PXE) is available. + +To generate a PXE boot image, run: + +@example +@group +grub-mkimage --format=i386-pc --output=core.img --prefix='(pxe)/boot/grub' pxe pxecmd +cat /boot/grub/pxeboot.img core.img >grub.pxe +@end group +@end example + +Copy @file{grub.pxe}, @file{/boot/grub/*.mod}, and @file{/boot/grub/*.lst} +to the PXE (TFTP) server, ensuring that @file{*.mod} and @file{*.lst} are +accessible via the @file{/boot/grub/} path from the TFTP server root. Set +the DHCP server configuration to offer @file{grub.pxe} as the boot file (the +@samp{filename} option in ISC dhcpd). + +After GRUB has started, files on the TFTP server will be accessible via the +@samp{(pxe)} device. + +The server and gateway IP address can be controlled by changing the +@samp{(pxe)} device name to @samp{(pxe:@var{server-ip})} or +@samp{(pxe:@var{server-ip}:@var{gateway-ip})}. Note that this should be +changed both in the prefix and in any references to the device name in the +configuration file. + +GRUB provides several environment variables which may be used to inspect or +change the behaviour of the PXE device: + +@table @samp +@item net_pxe_ip +The IP address of this machine. Read-only. + +@item net_pxe_mac +The network interface's MAC address. Read-only. + +@item net_pxe_hostname +The client host name provided by DHCP. Read-only. + +@item net_pxe_domain +The client domain name provided by DHCP. Read-only. + +@item net_pxe_rootpath +The path to the client's root disk provided by DHCP. Read-only. + +@item net_pxe_extensionspath +The path to additional DHCP vendor extensions provided by DHCP. Read-only. + +@item net_pxe_boot_file +The boot file name provided by DHCP. Read-only. + +@item net_pxe_dhcp_server_name +The name of the DHCP server responsible for these boot parameters. +Read-only. + +@item net_pxe_blksize +The PXE transfer block size. Read-write, defaults to 512. + +@item pxe_default_server +The default PXE server. Read-write, although setting this is only useful +before opening a PXE device. + +@item pxe_default_gateway +The default gateway to use when contacting the PXE server. Read-write, +although setting this is only useful before opening a PXE device. +@end table + + @node Serial terminal @chapter Using GRUB via a serial line @@ -1094,7 +1166,7 @@ MBR when installing GRUB), while the syntax @samp{(hd0,1)} represents using the first partition of the disk (or the boot sector of the partition when installing GRUB). -If you enabled the network support, the special drive, @samp{(nd)}, is +If you enabled the network support, the special drive @samp{(pxe)} is also available. Before using the network drive, you must initialize the network. @xref{Network}, for more information. @@ -1422,6 +1494,7 @@ you forget a command, you can run the command @command{help} * password:: Set a clear-text password * password_pbkdf2:: Set a hashed password * play:: Play a tune +* pxe_unload:: Unload the PXE environment * reboot:: Reboot your computer * search:: Search devices by file, label, or UUID * set:: Set an environment variable @@ -1792,6 +1865,16 @@ a rest. @end deffn +@node pxe_unload +@subsection pxe_unload + +@deffn Command pxe_unload +Unload the PXE environment (@pxref{Network}). + +This command is only available on PC BIOS systems. +@end deffn + + @node reboot @subsection reboot From 258c2573a659c3b04b2873bcc3da9351a08e8f9a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 21:29:25 +0100 Subject: [PATCH 83/96] * fs/i386/pc/pxe.c (grub_pxe_open): Fix parsing of gateway_ip. --- ChangeLog | 4 ++++ fs/i386/pc/pxe.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f9a0d2424..b8f5f80d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-06-07 Colin Watson + + * fs/i386/pc/pxe.c (grub_pxe_open): Fix parsing of gateway_ip. + 2010-06-07 Colin Watson * docs/grub.texi (Network): New section. diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c index 82d8ee583..e4d481a8e 100644 --- a/fs/i386/pc/pxe.c +++ b/fs/i386/pc/pxe.c @@ -114,7 +114,7 @@ grub_pxe_open (const char *name, grub_disk_t disk) return err; if (*ptr == ':') { - err = parse_ip (ptr + 1, &(data->server_ip), 0); + err = parse_ip (ptr + 1, &(data->gateway_ip), 0); if (err) return err; } From fb55c3acf9adec8a576e35551a8d2f5d6684cb88 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 22:13:26 +0100 Subject: [PATCH 84/96] * normal/completion.c (grub_normal_do_completion): When completing arguments to "set" and the current word contains an equals sign, skip to after the equals sign before starting completion. --- ChangeLog | 6 ++++++ normal/completion.c | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/ChangeLog b/ChangeLog index b8f5f80d8..bc1b2686a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-07 Colin Watson + + * normal/completion.c (grub_normal_do_completion): When completing + arguments to "set" and the current word contains an equals sign, + skip to after the equals sign before starting completion. + 2010-06-07 Colin Watson * fs/i386/pc/pxe.c (grub_pxe_open): Fix parsing of gateway_ip. diff --git a/normal/completion.c b/normal/completion.c index 13e8f7a6b..334eaea11 100644 --- a/normal/completion.c +++ b/normal/completion.c @@ -414,6 +414,14 @@ grub_normal_do_completion (char *buf, int *restore, else current_word = argv[argc - 1]; + if (argc > 1 && ! grub_strcmp (argv[0], "set")) + { + char *equals = grub_strchr (current_word, '='); + if (equals) + /* Complete the value of the variable. */ + current_word = equals + 1; + } + /* Determine the state the command line is in, depending on the state, it can be determined how to complete. */ cmdline_state = get_state (buf); From da90820083ca2a6ca22877068a9d7262cd5629ac Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 22:18:00 +0100 Subject: [PATCH 85/96] * docs/grub.texi (Naming convention): Use GRUB 2 syntax. (File name syntax): Likewise. (help): --all is no longer supported in GRUB 2. Be more precise about pattern matching. --- ChangeLog | 7 +++++++ docs/grub.texi | 22 ++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index bc1b2686a..3a463ab42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-06-07 Colin Watson + + * docs/grub.texi (Naming convention): Use GRUB 2 syntax. + (File name syntax): Likewise. + (help): --all is no longer supported in GRUB 2. Be more precise + about pattern matching. + 2010-06-07 Colin Watson * normal/completion.c (grub_normal_do_completion): When completing diff --git a/docs/grub.texi b/docs/grub.texi index 37016b175..ffc6b8fe2 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -390,14 +390,14 @@ GRUB searches for the first @sc{pc} slice which has a BSD @samp{a} partition. Of course, to actually access the disks or partitions with GRUB, you -need to use the device specification in a command, like @samp{root -(fd0)} or @samp{unhide (hd0,3)}. To help you find out which number -specifies a partition you want, the GRUB command-line +need to use the device specification in a command, like @samp{set +root=(fd0)} or @samp{parttool (hd0,3) hidden-}. To help you find out +which number specifies a partition you want, the GRUB command-line (@pxref{Command-line interface}) options have argument completion. This means that, for example, you only need to type @example -root ( +set root=( @end example followed by a @key{TAB}, and GRUB will display the list of drives, @@ -1186,8 +1186,8 @@ example is @samp{(hd0,1)/boot/grub/grub.cfg}. This means the file @file{/boot/grub/grub.cfg} in the first partition of the first hard disk. If you omit the device name in an absolute file name, GRUB uses GRUB's @dfn{root device} implicitly. So if you set the root device to, -say, @samp{(hd1,1)} by the command @command{root} (@pxref{root}), then -@code{/boot/kernel} is the same as @code{(hd1,1)/boot/kernel}. +say, @samp{(hd1,1)} by the command @samp{set root=(hd1,1)} (@pxref{set}), +then @code{/boot/kernel} is the same as @code{(hd1,1)/boot/kernel}. @node Block list syntax @@ -1742,15 +1742,13 @@ is shut down using APM. @node help @subsection help -@deffn Command help @option{--all} [pattern @dots{}] +@deffn Command help [pattern @dots{}] Display helpful information about builtin commands. If you do not -specify @var{pattern}, this command shows short descriptions of most of -available commands. If you specify the option @option{--all} to this -command, short descriptions of rarely used commands (such as -@ref{testload}) are displayed as well. +specify @var{pattern}, this command shows short descriptions of all +available commands. If you specify any @var{patterns}, it displays longer information -about each of the commands which match those @var{patterns}. +about each of the commands whose names begin with those @var{patterns}. @end deffn From e0f4c438823f1fa82cac8098469cc138bb1fe37d Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Mon, 7 Jun 2010 22:41:55 +0100 Subject: [PATCH 86/96] * kern/emu/misc.c (device_mapper_null_log): New function. (grub_device_mapper_supported): New function. * include/grub/emu/misc.h (grub_device_mapper_supported): Add prototype. * kern/emu/hostdisk.c (find_partition_start): Check whether device-mapper is supported before trying to use it. * util/deviceiter.c (grub_util_iterate_devices): Likewise. --- ChangeLog | 10 +++ include/grub/emu/misc.h | 4 + kern/emu/hostdisk.c | 2 +- kern/emu/misc.c | 39 ++++++++ util/deviceiter.c | 194 ++++++++++++++++++++-------------------- 5 files changed, 152 insertions(+), 97 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a463ab42..c28f77bc8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-06-07 Colin Watson + + * kern/emu/misc.c (device_mapper_null_log): New function. + (grub_device_mapper_supported): New function. + * include/grub/emu/misc.h (grub_device_mapper_supported): Add + prototype. + * kern/emu/hostdisk.c (find_partition_start): Check whether + device-mapper is supported before trying to use it. + * util/deviceiter.c (grub_util_iterate_devices): Likewise. + 2010-06-07 Colin Watson * docs/grub.texi (Naming convention): Use GRUB 2 syntax. diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h index 0e6ace0e8..f34cd4287 100644 --- a/include/grub/emu/misc.h +++ b/include/grub/emu/misc.h @@ -48,4 +48,8 @@ int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...); char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); extern char * canonicalize_file_name (const char *path); +#ifdef HAVE_DEVICE_MAPPER +int grub_device_mapper_supported (void); +#endif + #endif /* GRUB_EMU_MISC_H */ diff --git a/kern/emu/hostdisk.c b/kern/emu/hostdisk.c index fc62cca26..47389195c 100644 --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -342,7 +342,7 @@ find_partition_start (const char *dev) # endif /* !defined(__NetBSD__) */ # ifdef HAVE_DEVICE_MAPPER - if (device_is_mapped (dev)) { + if (grub_device_mapper_supported () && device_is_mapped (dev)) { struct dm_task *task = NULL; grub_uint64_t start, length; char *target_type, *params, *space; diff --git a/kern/emu/misc.c b/kern/emu/misc.c index 9437169e0..38395fca8 100644 --- a/kern/emu/misc.c +++ b/kern/emu/misc.c @@ -22,6 +22,10 @@ #include #include +#ifdef HAVE_DEVICE_MAPPER +# include +#endif + int verbosity; void @@ -311,3 +315,38 @@ grub_make_system_path_relative_to_its_root (const char *path) return buf3; } + +#ifdef HAVE_DEVICE_MAPPER +static void device_mapper_null_log (int level __attribute__ ((unused)), + const char *file __attribute__ ((unused)), + int line __attribute__ ((unused)), + int dm_errno __attribute__ ((unused)), + const char *f __attribute__ ((unused)), + ...) +{ +} + +int +grub_device_mapper_supported (void) +{ + static int supported = -1; + + if (supported == -1) + { + struct dm_task *dmt; + + /* Suppress annoying log messages. */ + dm_log_with_errno_init (&device_mapper_null_log); + + dmt = dm_task_create (DM_DEVICE_VERSION); + supported = (dmt != NULL); + if (dmt) + dm_task_destroy (dmt); + + /* Restore the original logger. */ + dm_log_with_errno_init (NULL); + } + + return supported; +} +#endif /* HAVE_DEVICE_MAPPER */ diff --git a/util/deviceiter.c b/util/deviceiter.c index 03813bc7d..d7e8f159e 100644 --- a/util/deviceiter.c +++ b/util/deviceiter.c @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef __linux__ # if !defined(__GLIBC__) || \ @@ -676,112 +677,113 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int), } /* DM-RAID. */ - { - struct dm_tree *tree = NULL; - struct dm_task *task = NULL; - struct dm_names *names = NULL; - unsigned int next = 0; - void *top_handle, *second_handle; - struct dm_tree_node *root, *top, *second; - struct dmraid_seen *seen = NULL; + if (grub_device_mapper_supported ()) + { + struct dm_tree *tree = NULL; + struct dm_task *task = NULL; + struct dm_names *names = NULL; + unsigned int next = 0; + void *top_handle, *second_handle; + struct dm_tree_node *root, *top, *second; + struct dmraid_seen *seen = NULL; - /* Build DM tree for all devices. */ - tree = dm_tree_create (); - dmraid_check (tree, "dm_tree_create failed\n"); - task = dm_task_create (DM_DEVICE_LIST); - dmraid_check (task, "dm_task_create failed\n"); - dmraid_check (dm_task_run (task), "dm_task_run failed\n"); - names = dm_task_get_names (task); - dmraid_check (names, "dm_task_get_names failed\n"); - dmraid_check (names->dev, "No DM devices found\n"); - do - { - names = (void *) names + next; - dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev), - MINOR (names->dev)), - "dm_tree_add_dev (%s) failed\n", names->name); - next = names->next; - } - while (next); + /* Build DM tree for all devices. */ + tree = dm_tree_create (); + dmraid_check (tree, "dm_tree_create failed\n"); + task = dm_task_create (DM_DEVICE_LIST); + dmraid_check (task, "dm_task_create failed\n"); + dmraid_check (dm_task_run (task), "dm_task_run failed\n"); + names = dm_task_get_names (task); + dmraid_check (names, "dm_task_get_names failed\n"); + dmraid_check (names->dev, "No DM devices found\n"); + do + { + names = (void *) names + next; + dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev), + MINOR (names->dev)), + "dm_tree_add_dev (%s) failed\n", names->name); + next = names->next; + } + while (next); - /* Walk the second-level children of the inverted tree; that is, devices - which are directly composed of non-DM devices such as hard disks. - This class includes all DM-RAID disks and excludes all DM-RAID - partitions. */ - root = dm_tree_find_node (tree, 0, 0); - top_handle = NULL; - top = dm_tree_next_child (&top_handle, root, 1); - while (top) - { - second_handle = NULL; - second = dm_tree_next_child (&second_handle, top, 1); - while (second) - { - const char *node_name, *node_uuid; - char *name; - struct dmraid_seen *seen_elt; + /* Walk the second-level children of the inverted tree; that is, devices + which are directly composed of non-DM devices such as hard disks. + This class includes all DM-RAID disks and excludes all DM-RAID + partitions. */ + root = dm_tree_find_node (tree, 0, 0); + top_handle = NULL; + top = dm_tree_next_child (&top_handle, root, 1); + while (top) + { + second_handle = NULL; + second = dm_tree_next_child (&second_handle, top, 1); + while (second) + { + const char *node_name, *node_uuid; + char *name; + struct dmraid_seen *seen_elt; - node_name = dm_tree_node_get_name (second); - dmraid_check (node_name, "dm_tree_node_get_name failed\n"); - node_uuid = dm_tree_node_get_uuid (second); - dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n"); - if (strncmp (node_uuid, "DMRAID-", 7) != 0) - { - grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name); - goto dmraid_next_child; - } + node_name = dm_tree_node_get_name (second); + dmraid_check (node_name, "dm_tree_node_get_name failed\n"); + node_uuid = dm_tree_node_get_uuid (second); + dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n"); + if (strncmp (node_uuid, "DMRAID-", 7) != 0) + { + grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name); + goto dmraid_next_child; + } - /* Have we already seen this node? There are typically very few - DM-RAID disks, so a list should be fast enough. */ - if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name)) - { - grub_dprintf ("deviceiter", "Already seen DM device %s\n", - node_name); - goto dmraid_next_child; - } + /* Have we already seen this node? There are typically very few + DM-RAID disks, so a list should be fast enough. */ + if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name)) + { + grub_dprintf ("deviceiter", "Already seen DM device %s\n", + node_name); + goto dmraid_next_child; + } - name = xasprintf ("/dev/mapper/%s", node_name); - if (check_device (name)) - { - if (hook (name, 0)) - { - free (name); - while (seen) - { - struct dmraid_seen *seen_elt = - grub_list_pop (GRUB_AS_LIST_P (&seen)); - free (seen_elt); - } - if (task) - dm_task_destroy (task); - if (tree) - dm_tree_free (tree); - return; - } - } - free (name); + name = xasprintf ("/dev/mapper/%s", node_name); + if (check_device (name)) + { + if (hook (name, 0)) + { + free (name); + while (seen) + { + struct dmraid_seen *seen_elt = + grub_list_pop (GRUB_AS_LIST_P (&seen)); + free (seen_elt); + } + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + return; + } + } + free (name); - seen_elt = xmalloc (sizeof *seen_elt); - seen_elt->name = node_name; - grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); + seen_elt = xmalloc (sizeof *seen_elt); + seen_elt->name = node_name; + grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); dmraid_next_child: - second = dm_tree_next_child (&second_handle, top, 1); - } - top = dm_tree_next_child (&top_handle, root, 1); - } + second = dm_tree_next_child (&second_handle, top, 1); + } + top = dm_tree_next_child (&top_handle, root, 1); + } dmraid_end: - while (seen) - { - struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen)); - free (seen_elt); - } - if (task) - dm_task_destroy (task); - if (tree) - dm_tree_free (tree); - } + while (seen) + { + struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen)); + free (seen_elt); + } + if (task) + dm_task_destroy (task); + if (tree) + dm_tree_free (tree); + } # endif /* HAVE_DEVICE_MAPPER */ #endif /* __linux__ */ } From 6ef0ddb4760e58f5dad51169a42e0c77cb5f41d5 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Jun 2010 10:18:53 +0100 Subject: [PATCH 87/96] * docs/grub.texi (Security): Menu entries are unrestricted by default, not restricted to superusers as I had previously thought. Reword to account for this. --- ChangeLog | 6 ++++++ docs/grub.texi | 18 +++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index c28f77bc8..ce24487d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-06-08 Colin Watson + + * docs/grub.texi (Security): Menu entries are unrestricted by + default, not restricted to superusers as I had previously thought. + Reword to account for this. + 2010-06-07 Colin Watson * kern/emu/misc.c (device_mapper_null_log): New function. diff --git a/docs/grub.texi b/docs/grub.texi index ffc6b8fe2..1c23460ea 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1946,11 +1946,14 @@ sets the password hashed using the Password-Based Key Derivation Function In order to enable authentication support, the @samp{superusers} environment variable must be set to a list of usernames, separated by any of spaces, commas, semicolons, pipes, or ampersands. Superusers are permitted to use -the GRUB command line, edit menu entries, and execute any menu entry. +the GRUB command line, edit menu entries, and execute any menu entry. If +@samp{superusers} is set, then use of the command line is automatically +restricted to superusers. Other users may be given access to specific menu entries by giving a list of -usernames (as above) using the @kbd{--users} option to the @samp{menuentry} -command (@pxref{menuentry}). +usernames (as above) using the @option{--users} option to the +@samp{menuentry} command (@pxref{menuentry}). If the @option{--users} +option is not used for a menu entry, then that entry is unrestricted. Putting this together, a typical @file{grub.cfg} fragment might look like this: @@ -1961,12 +1964,17 @@ set superusers="root" password_pbkdf2 root grub.pbkdf2.sha512.10000.biglongstring password user1 insecure -menuentry "Superusers only" @{ +menuentry "May be run by any user" @{ set root=(hd0,1) linux /vmlinuz @} -menuentry "May be run by user1" --users user1 @{ +menuentry "Superusers only" --users "" @{ + set root=(hd0,1) + linux /vmlinuz single +@} + +menuentry "May be run by user1 or a superuser" --users user1 @{ set root=(hd0,2) chainloader +1 @} From d39f3dec5fefecbc83d64106d39b0a12281efaad Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Jun 2010 10:29:25 +0100 Subject: [PATCH 88/96] * docs/grub.texi (History): Expand to cover GRUB 2. (Serial terminal): Refer to `terminal_input' and `terminal_output' commands, not `terminal'. (serial): Likewise. (terminal_input): New section. (terminal_output): New section. (uppermem): New section (stub). (Obtaining and Building GRUB): Refer to Bazaar, not Subversion. --- ChangeLog | 11 ++++++++ docs/grub.texi | 74 +++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index ce24487d3..15be02a51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2010-06-08 Colin Watson + + * docs/grub.texi (History): Expand to cover GRUB 2. + (Serial terminal): Refer to `terminal_input' and `terminal_output' + commands, not `terminal'. + (serial): Likewise. + (terminal_input): New section. + (terminal_output): New section. + (uppermem): New section (stub). + (Obtaining and Building GRUB): Refer to Bazaar, not Subversion. + 2010-06-08 Colin Watson * docs/grub.texi (Security): Menu entries are unrestricted by diff --git a/docs/grub.texi b/docs/grub.texi index 1c23460ea..ac3bc2f90 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -174,6 +174,22 @@ official GNU package, and opened its development by making the latest sources available via anonymous CVS. @xref{Obtaining and Building GRUB}, for more information. +Over the next few years, GRUB was extended to meet many needs, but it +quickly became clear that its design was not keeping up with the extensions +being made to it, and we reached the point where it was very difficult to +make any further changes without breaking existing features. Around 2002, +Yoshinori K. Okuji started work on PUPA (Preliminary Universal Programming +Architecture for GNU GRUB), aiming to rewrite the core of GRUB to make it +cleaner, safer, more robust, and more powerful. PUPA was eventually renamed +to GRUB 2, and the original version of GRUB was renamed to GRUB Legacy. +Small amounts of maintenance continued to be done on GRUB Legacy, but the +last release (0.97) was made in 2005 and at the time of writing it seems +unlikely that there will be another. + +By around 2007, GNU/Linux distributions started to use GRUB 2 to limited +extents, and by the end of 2009 multiple major distributions were installing +it by default. + @node Features @section GRUB features @@ -1078,7 +1094,8 @@ you want to use COM2, you must specify @samp{--unit=1} instead. This command accepts many other options, so please refer to @ref{serial}, for more details. -The command @command{terminal} (@pxref{terminal}) chooses which type of +The commands @command{terminal_input} (@pxref{terminal_input}) and +@command{terminal_output} (@pxref{terminal_output} choose which type of terminal you want to use. In the case above, the terminal will be a serial terminal, but you can also pass @code{console} to the command, as @samp{terminal serial console}. In this case, a terminal in which @@ -1421,6 +1438,8 @@ Commands usable anywhere in the menu and in the command-line. @menu * serial:: Set up a serial device +* terminal_input:: Manage input terminals +* terminal_output:: Manage output terminals * terminfo:: Define terminal type @end menu @@ -1440,13 +1459,52 @@ bits and one stop bit. @var{parity} is one of @samp{no}, @samp{odd}, @samp{even} and defaults to @samp{no}. The serial port is not used as a communication channel unless the -@command{terminal} command is used (@pxref{terminal}). +@command{terminal_input} or @command{terminal_output} command is used +(@pxref{terminal_input}, @pxref{terminal_output}). This command is only available if GRUB is compiled with serial support. See also @ref{Serial terminal}. @end deffn +@node terminal_input +@subsection terminal_input + +@deffn Command terminal_input [@option{--append}|@option{--remove}] @ + [terminal1] [terminal2] @dots{} +List or select an input terminal. + +With no arguments, list the active and available input terminals. + +With @option{--append}, add the named terminals to the list of active input +terminals; any of these may be used to provide input to GRUB. + +With @option{--remove}, remove the named terminals from the active list. + +With no options but a list of terminal names, make only the listed terminal +names active. +@end deffn + + +@node terminal_output +@subsection terminal_output + +@deffn Command terminal_output [@option{--append}|@option{--remove}] @ + [terminal1] [terminal2] @dots{} +List or select an output terminal. + +With no arguments, list the active and available output terminals. + +With @option{--append}, add the named terminals to the list of active output +terminals; all of these will receive output from GRUB. + +With @option{--remove}, remove the named terminals from the active list. + +With no options but a list of terminal names, make only the listed terminal +names active. +@end deffn + + @node terminfo @subsection terminfo @@ -1499,6 +1557,7 @@ you forget a command, you can run the command @command{help} * search:: Search devices by file, label, or UUID * set:: Set an environment variable * unset:: Unset an environment variable +* uppermem:: Set the upper memory size @end menu @@ -1921,6 +1980,12 @@ Unset the environment variable @var{envvar}. @end deffn +@node uppermem +@subsection uppermem + +This command is not yet implemented for GRUB 2, although it is planned. + + @node Security @chapter Authentication and authorisation @@ -2190,8 +2255,9 @@ just do: @end group @end example -Also, the latest version is available from the SVN. See -@uref{http://savannah.gnu.org/svn/?group=grub} for more information. +Also, the latest version is available using Bazaar. See +@uref{http://www.gnu.org/software/grub/grub-download.en.html} for more +information. @node Reporting bugs @appendix Reporting bugs From 50e532ca1a421581c6ea63f77a9cd2a5e8c8548a Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Tue, 8 Jun 2010 10:37:16 +0100 Subject: [PATCH 89/96] * .bzrignore: Add ascii.bitmaps, ascii.h, grub_script.yy.c, and grub_script.yy.h. --- .bzrignore | 4 ++++ ChangeLog | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/.bzrignore b/.bzrignore index 46e8637b6..aa9c4ff84 100644 --- a/.bzrignore +++ b/.bzrignore @@ -3,6 +3,8 @@ 30_os-prober 40_custom aclocal.m4 +ascii.bitmaps +ascii.h autom4te.cache build_env.mk .bzrignore @@ -48,6 +50,8 @@ grub_script_check_init.c grub_script_check_init.h grub_script.tab.c grub_script.tab.h +grub_script.yy.c +grub_script.yy.h grub-set-default grub-setup grub_setup_init.c diff --git a/ChangeLog b/ChangeLog index 15be02a51..e9570905e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-08 Colin Watson + + * .bzrignore: Add ascii.bitmaps, ascii.h, grub_script.yy.c, and + grub_script.yy.h. + 2010-06-08 Colin Watson * docs/grub.texi (History): Expand to cover GRUB 2. From f4d095d77d9d87a1275de19411656ff8cfe69b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Tue, 8 Jun 2010 12:09:34 +0200 Subject: [PATCH 90/96] Add . to the directories searched for unifont. --- ChangeLog | 4 ++++ configure.ac | 12 +++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index e9570905e..b48b79819 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-06-08 Grégoire Sutre + + * configure.ac: Add `.' to the directories searched for unifont. + 2010-06-08 Colin Watson * .bzrignore: Add ascii.bitmaps, ascii.h, grub_script.yy.c, and diff --git a/configure.ac b/configure.ac index 31b179d46..97c493e27 100644 --- a/configure.ac +++ b/configure.ac @@ -179,11 +179,13 @@ if test "x$YACC" = x; then AC_MSG_ERROR([bison is not found]) fi -for file in /usr/src/unifont.bdf /usr/share/fonts/X11/misc/unifont.pcf.gz /usr/share/fonts/unifont/unifont.pcf.gz; do - if test -e $file ; then - AC_SUBST([FONT_SOURCE], [$file]) - break - fi +for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do + for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont; do + if test -f "$dir/unifont.$ext"; then + AC_SUBST([FONT_SOURCE], [$dir/unifont.$ext]) + break 2 + fi + done done AC_PROG_INSTALL From e8a6f3b6a5f07e8a63788e33866fa99ed8737297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Tue, 8 Jun 2010 12:23:30 +0200 Subject: [PATCH 91/96] Use absolute offsets for start of embedding area. --- ChangeLog | 5 +++++ util/i386/pc/grub-setup.c | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index b48b79819..45637ac17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-08 Grégoire Sutre + + * util/i386/pc/grub-setup.c (setup): Use absolute offsets for start of + embedding area. Use <= instead of == when checking for non-emptiness. + 2010-06-08 Grégoire Sutre * configure.ac: Add `.' to the directories searched for unifont. diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 6e6b2e878..08a76f65c 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -126,8 +126,8 @@ setup (const char *dir, /* There's always an embed region, and it starts right after the MBR. */ embed_region.start = 1; - if (embed_region.end > p->start) - embed_region.end = p->start; + if (embed_region.end > grub_partition_get_start (p)) + embed_region.end = grub_partition_get_start (p); return 0; } @@ -147,8 +147,8 @@ setup (const char *dir, /* If there's an embed region, it is in a dedicated partition. */ if (! memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16)) { - embed_region.start = p->start; - embed_region.end = p->start + p->len; + embed_region.start = grub_partition_get_start (p); + embed_region.end = grub_partition_get_start (p) + grub_partition_get_len (p); return 1; } @@ -361,7 +361,7 @@ setup (const char *dir, else grub_util_error (_("No DOS-style partitions found")); - if (embed_region.end == embed_region.start) + if (embed_region.end <= embed_region.start) { if (! strcmp (dest_partmap, "msdos")) grub_util_warn (_("This msdos-style partition label has no post-MBR gap; embedding won't be possible!")); From 0ea7c4f93cdacfd650dfba43ee6e410a2414aca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Sutre?= Date: Tue, 8 Jun 2010 12:52:42 +0200 Subject: [PATCH 92/96] Make --version uniform and avoid hard-coded program name. --- ChangeLog | 19 +++++++++++++++++++ util/grub-install.in | 10 ++++++---- util/grub-mkconfig.in | 13 ++++++++----- util/grub-mkimage.c | 2 +- util/grub-mkrescue.in | 8 +++++--- util/grub-reboot.in | 8 ++++++-- util/grub-set-default.in | 8 ++++++-- util/i386/efi/grub-install.in | 10 ++++++---- util/i386/pc/grub-setup.c | 2 +- util/ieee1275/grub-install.in | 10 ++++++---- util/powerpc/ieee1275/grub-mkrescue.in | 8 +++++--- util/sparc64/ieee1275/grub-setup.c | 2 +- 12 files changed, 70 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 45637ac17..9bbeae6c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2010-06-08 Grégoire Sutre + + Make --version uniform and avoid hard-coded program name. + + * util/grub-mkimage.c (main): Use `program_name' instead of + hard-coded string. + * util/i386/pc/grub-setup.c (main): Likewise. + * util/sparc64/ieee1275/grub-setup.c (parse_options): Likewise. + * util/grub-install.in: Save the basename of $0 in $self, and use the + latter in informational messages. Use the same format for --version + as the binary programs. + * util/grub-mkconfig.in: Likewise. + * util/grub-mkrescue.in: Likewise. + * util/grub-reboot.in: Likewise. + * util/grub-set-default.in: Likewise. + * util/i386/efi/grub-install.in: Likewise. + * util/ieee1275/grub-install.in: Likewise. + * util/powerpc/ieee1275/grub-mkrescue.in: Likewise. + 2010-06-08 Grégoire Sutre * util/i386/pc/grub-setup.c (setup): Use absolute offsets for start of diff --git a/util/grub-install.in b/util/grub-install.in index 0db216fd5..1e7fc1f2e 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -34,6 +34,8 @@ font=@datadir@/@PACKAGE_TARNAME@/ascii.pf2 pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` localedir=@datadir@/locale +self=`basename $0` + grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` @@ -61,7 +63,7 @@ fi # Print the usage. usage () { cat <. @@ -108,7 +110,7 @@ for option in "$@"; do usage exit 0 ;; -v | --version) - echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" exit 0 ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in index 0095e1ce8..d916459d6 100644 --- a/util/grub-mkconfig.in +++ b/util/grub-mkconfig.in @@ -23,7 +23,8 @@ exec_prefix=@exec_prefix@ sbindir=@sbindir@ libdir=@libdir@ sysconfdir=@sysconfdir@ -package_version=@PACKAGE_VERSION@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ host_os=@host_os@ datarootdir=@datarootdir@ datadir=@datadir@ @@ -31,6 +32,8 @@ pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"` grub_cfg="" grub_mkconfig_dir=${sysconfdir}/grub.d +self=`basename $0` + grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` @@ -38,7 +41,7 @@ grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` # Print the usage. usage () { cat <&2 + echo "$self: You must run this as root" >&2 exit 1 fi fi @@ -284,7 +287,7 @@ cat << EOF # # DO NOT EDIT THIS FILE # -# It is automatically generated by $0 using templates +# It is automatically generated by $self using templates # from ${grub_mkconfig_dir} and settings from ${sysconfdir}/default/grub # EOF diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c index 4e39450df..7b03c2fd0 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c @@ -1307,7 +1307,7 @@ main (int argc, char *argv[]) break; case 'V': - printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); return 0; case 'v': diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 99b10de7b..61b0c94f7 100644 --- a/util/grub-mkrescue.in +++ b/util/grub-mkrescue.in @@ -30,6 +30,8 @@ target_cpu=@target_cpu@ native_platform=@platform@ pkglib_DATA="@pkglib_DATA@" +self=`basename $0` + multiboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-multiboot coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-coreboot qemu_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-qemu @@ -44,7 +46,7 @@ grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` # Print the usage. usage () { cat <. EOF @@ -67,7 +69,7 @@ for option in "$@"; do usage exit 0 ;; -v | --version) - echo "$0 (GNU GRUB ${PACKAGE_VERSION})" + echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" exit 0 ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; diff --git a/util/grub-reboot.in b/util/grub-reboot.in index 20f2b10bc..2c49f5e13 100644 --- a/util/grub-reboot.in +++ b/util/grub-reboot.in @@ -22,6 +22,10 @@ transform="@program_transform_name@" prefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ +PACKAGE_NAME=@PACKAGE_NAME@ +PACKAGE_VERSION=@PACKAGE_VERSION@ + +self=`basename $0` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` rootdir= @@ -30,7 +34,7 @@ rootdir= # Print the usage. usage () { cat <. @@ -78,7 +80,7 @@ for option in "$@"; do usage exit 0 ;; -v | --version) - echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" + echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" exit 0 ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; @@ -219,7 +221,7 @@ $grub_mkimage -O ${target_cpu}-efi --output=${grubdir}/grub.efi $modules || exit echo "Installation finished. No error reported." echo "This is the contents of the device map $device_map." echo "Check if this is correct or not. If any of the lines is incorrect," -echo "fix it and re-run the script \`grub-install'." +echo "fix it and re-run the script \`$self'." echo cat $device_map diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 08a76f65c..ef0f5a990 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -702,7 +702,7 @@ main (int argc, char *argv[]) break; case 'V': - printf ("grub-setup (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); return 0; case 'v': diff --git a/util/ieee1275/grub-install.in b/util/ieee1275/grub-install.in index 4d00cc217..72135213d 100644 --- a/util/ieee1275/grub-install.in +++ b/util/ieee1275/grub-install.in @@ -34,6 +34,8 @@ target_cpu=@target_cpu@ platform=@platform@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` +self=`basename $0` + grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` @@ -53,7 +55,7 @@ nvsetenv=`which nvsetenv` # Print the usage. usage () { cat <. EOF @@ -61,7 +63,7 @@ for option in "$@"; do usage exit 0 ;; -v | --version) - echo "grub-mkrescue (GNU GRUB ${PACKAGE_VERSION})" + echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" exit 0 ;; --modules=*) modules=`echo "$option" | sed 's/--modules=//'` ;; diff --git a/util/sparc64/ieee1275/grub-setup.c b/util/sparc64/ieee1275/grub-setup.c index 8a2d30ba1..93e135eb3 100644 --- a/util/sparc64/ieee1275/grub-setup.c +++ b/util/sparc64/ieee1275/grub-setup.c @@ -503,7 +503,7 @@ parse_options (struct grub_setup_info *gp, int argc, char *argv[]) break; case 'V': - printf ("grub-setup (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); + printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION); return 0; case 'v': From 9146024736865ce501bd750cb1b7a0b286db48e0 Mon Sep 17 00:00:00 2001 From: Robert Millan Date: Wed, 9 Jun 2010 20:43:25 +0200 Subject: [PATCH 93/96] 2010-06-09 Robert Millan * util/grub.d/10_linux.in: Prefer compressed images over non-compressed ones, when both are available. --- ChangeLog | 5 +++++ util/grub.d/10_linux.in | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 9bbeae6c2..6158ef4b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-09 Robert Millan + + * util/grub.d/10_linux.in: Prefer compressed images over non-compressed + ones, when both are available. + 2010-06-08 Grégoire Sutre Make --version uniform and avoid hard-coded program name. diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in index 802d59f51..416ab6ed6 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in @@ -97,7 +97,7 @@ EOF EOF } -list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do +list=`for i in /boot/vmlinu[zx]-* /vmlinu[zx]-* ; do if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi done` prepare_boot_cache= From 6289c3a71507d8b02d859aa2e59d4e4dc81eb417 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 9 Jun 2010 22:24:12 +0200 Subject: [PATCH 94/96] * docs/grub.texi (Vendor power-on button): Add Asus EeePC 1005PE as reported by Henrique Ferreiro. --- ChangeLog | 5 +++++ docs/grub.texi | 2 ++ 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 6158ef4b3..0575e7c5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-09 Vladimir Serbinenko + + * docs/grub.texi (Vendor power-on button): Add Asus EeePC 1005PE as + reported by Henrique Ferreiro. + 2010-06-09 Robert Millan * util/grub.d/10_linux.in: Prefer compressed images over non-compressed diff --git a/docs/grub.texi b/docs/grub.texi index ac3bc2f90..9fe197da2 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -1123,6 +1123,8 @@ Values known to GRUB team are: @table @key @item Dell XPS M1530 85:3 +@item Asus EeePC 1005PE +84:1 (unconfirmed) @end table To take full advantage of this function install GRUB into MBR. From 56a0d956d196be7828d0845aa225a0514c395e37 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 11 Jun 2010 22:12:16 +0100 Subject: [PATCH 95/96] * Makefile.in (install-local): Include $(srcdir)/docs/man/$$dest.h2m when generating manual pages. * docs/man/grub-bin2h.h2m: New file. * docs/man/grub-editenv.h2m: New file. * docs/man/grub-fstest.h2m: New file. * docs/man/grub-install.h2m: New file. * docs/man/grub-macho2img.h2m: New file. * docs/man/grub-mkconfig.h2m: New file. * docs/man/grub-mkdevicemap.h2m: New file. * docs/man/grub-mkfont.h2m: New file. * docs/man/grub-mkimage.h2m: New file. * docs/man/grub-mkpasswd-pbkdf2.h2m: New file. * docs/man/grub-mkrelpath.h2m: New file. * docs/man/grub-mkrescue.h2m: New file. * docs/man/grub-ofpathname.h2m: New file. * docs/man/grub-pe2elf.h2m: New file. * docs/man/grub-probe.h2m: New file. * docs/man/grub-reboot.h2m: New file. * docs/man/grub-script-check.h2m: New file. * docs/man/grub-set-default.h2m: New file. * docs/man/grub-setup.h2m: New file. --- ChangeLog | 24 ++++++++++++++++++++++++ Makefile.in | 8 ++++---- docs/man/grub-bin2h.h2m | 2 ++ docs/man/grub-editenv.h2m | 2 ++ docs/man/grub-fstest.h2m | 2 ++ docs/man/grub-install.h2m | 2 ++ docs/man/grub-macho2img.h2m | 2 ++ docs/man/grub-mkconfig.h2m | 2 ++ docs/man/grub-mkdevicemap.h2m | 2 ++ docs/man/grub-mkfont.h2m | 2 ++ docs/man/grub-mkimage.h2m | 2 ++ docs/man/grub-mkpasswd-pbkdf2.h2m | 2 ++ docs/man/grub-mkrelpath.h2m | 2 ++ docs/man/grub-mkrescue.h2m | 2 ++ docs/man/grub-ofpathname.h2m | 2 ++ docs/man/grub-pe2elf.h2m | 2 ++ docs/man/grub-probe.h2m | 2 ++ docs/man/grub-reboot.h2m | 2 ++ docs/man/grub-script-check.h2m | 2 ++ docs/man/grub-set-default.h2m | 2 ++ docs/man/grub-setup.h2m | 2 ++ 21 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 docs/man/grub-bin2h.h2m create mode 100644 docs/man/grub-editenv.h2m create mode 100644 docs/man/grub-fstest.h2m create mode 100644 docs/man/grub-install.h2m create mode 100644 docs/man/grub-macho2img.h2m create mode 100644 docs/man/grub-mkconfig.h2m create mode 100644 docs/man/grub-mkdevicemap.h2m create mode 100644 docs/man/grub-mkfont.h2m create mode 100644 docs/man/grub-mkimage.h2m create mode 100644 docs/man/grub-mkpasswd-pbkdf2.h2m create mode 100644 docs/man/grub-mkrelpath.h2m create mode 100644 docs/man/grub-mkrescue.h2m create mode 100644 docs/man/grub-ofpathname.h2m create mode 100644 docs/man/grub-pe2elf.h2m create mode 100644 docs/man/grub-probe.h2m create mode 100644 docs/man/grub-reboot.h2m create mode 100644 docs/man/grub-script-check.h2m create mode 100644 docs/man/grub-set-default.h2m create mode 100644 docs/man/grub-setup.h2m diff --git a/ChangeLog b/ChangeLog index c4a6246ee..43cf36b32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2010-06-11 Colin Watson + + * Makefile.in (install-local): Include $(srcdir)/docs/man/$$dest.h2m + when generating manual pages. + * docs/man/grub-bin2h.h2m: New file. + * docs/man/grub-editenv.h2m: New file. + * docs/man/grub-fstest.h2m: New file. + * docs/man/grub-install.h2m: New file. + * docs/man/grub-macho2img.h2m: New file. + * docs/man/grub-mkconfig.h2m: New file. + * docs/man/grub-mkdevicemap.h2m: New file. + * docs/man/grub-mkfont.h2m: New file. + * docs/man/grub-mkimage.h2m: New file. + * docs/man/grub-mkpasswd-pbkdf2.h2m: New file. + * docs/man/grub-mkrelpath.h2m: New file. + * docs/man/grub-mkrescue.h2m: New file. + * docs/man/grub-ofpathname.h2m: New file. + * docs/man/grub-pe2elf.h2m: New file. + * docs/man/grub-probe.h2m: New file. + * docs/man/grub-reboot.h2m: New file. + * docs/man/grub-script-check.h2m: New file. + * docs/man/grub-set-default.h2m: New file. + * docs/man/grub-setup.h2m: New file. + 2010-06-10 Vladimir Serbinenko Use FOR_* macros instead of *_iterate whenever possible. diff --git a/Makefile.in b/Makefile.in index 75388e3c8..afe4beb6e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -323,26 +323,26 @@ install-local: all if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \ - $(HELP2MAN) --section=1 -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ + $(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ done $(SHELL) $(mkinstalldirs) $(DESTDIR)$(sbindir) $(DESTDIR)$(mandir)/man8 @list='$(sbin_UTILITIES)'; for file in $$list; do \ if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ $(INSTALL_PROGRAM) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \ - $(HELP2MAN) --section=8 -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ + $(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ done @list='$(bin_SCRIPTS)'; for file in $$list; do \ if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(bindir)/$$dest; \ - $(HELP2MAN) --section=1 -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ + $(HELP2MAN) --section=1 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man1/$$dest.1 $(builddir)/$$file; \ done @list='$(sbin_SCRIPTS)'; for file in $$list; do \ if test -f "$$file"; then dir=; else dir="$(srcdir)/"; fi; \ dest="`echo $$file | sed 's,.*/,,' | sed '$(transform)'`"; \ $(INSTALL_SCRIPT) $$dir$$file $(DESTDIR)$(sbindir)/$$dest; \ - $(HELP2MAN) --section=8 -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ + $(HELP2MAN) --section=8 -i $(srcdir)/docs/man/$$dest.h2m -o $(DESTDIR)$(mandir)/man8/$$dest.8 $(builddir)/$$file; \ done $(SHELL) $(mkinstalldirs) $(DESTDIR)$(sysconfdir)/grub.d @list='$(grub-mkconfig_SCRIPTS)'; for file in $$list; do \ diff --git a/docs/man/grub-bin2h.h2m b/docs/man/grub-bin2h.h2m new file mode 100644 index 000000000..ef463f3d1 --- /dev/null +++ b/docs/man/grub-bin2h.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-bin2h \- convert a binary file to a C header diff --git a/docs/man/grub-editenv.h2m b/docs/man/grub-editenv.h2m new file mode 100644 index 000000000..efbd79070 --- /dev/null +++ b/docs/man/grub-editenv.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-editenv \- edit GRUB environment block diff --git a/docs/man/grub-fstest.h2m b/docs/man/grub-fstest.h2m new file mode 100644 index 000000000..be39429b5 --- /dev/null +++ b/docs/man/grub-fstest.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-fstest \- debug tool for GRUB filesystem drivers diff --git a/docs/man/grub-install.h2m b/docs/man/grub-install.h2m new file mode 100644 index 000000000..65252155c --- /dev/null +++ b/docs/man/grub-install.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-install \- install GRUB to a device diff --git a/docs/man/grub-macho2img.h2m b/docs/man/grub-macho2img.h2m new file mode 100644 index 000000000..412bf926a --- /dev/null +++ b/docs/man/grub-macho2img.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-macho2img \- convert Mach-O to raw image diff --git a/docs/man/grub-mkconfig.h2m b/docs/man/grub-mkconfig.h2m new file mode 100644 index 000000000..b0d33ec61 --- /dev/null +++ b/docs/man/grub-mkconfig.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkconfig \- generate a GRUB configuration file diff --git a/docs/man/grub-mkdevicemap.h2m b/docs/man/grub-mkdevicemap.h2m new file mode 100644 index 000000000..8ab34ac86 --- /dev/null +++ b/docs/man/grub-mkdevicemap.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkdevicemap \- generate a GRUB device map file automatically diff --git a/docs/man/grub-mkfont.h2m b/docs/man/grub-mkfont.h2m new file mode 100644 index 000000000..d8580186f --- /dev/null +++ b/docs/man/grub-mkfont.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkfont \- make GRUB font files diff --git a/docs/man/grub-mkimage.h2m b/docs/man/grub-mkimage.h2m new file mode 100644 index 000000000..71f270940 --- /dev/null +++ b/docs/man/grub-mkimage.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkimage \- make a bootable image of GRUB diff --git a/docs/man/grub-mkpasswd-pbkdf2.h2m b/docs/man/grub-mkpasswd-pbkdf2.h2m new file mode 100644 index 000000000..5b2b2ef7f --- /dev/null +++ b/docs/man/grub-mkpasswd-pbkdf2.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkpasswd-pbkdf2 \- generate hashed password for GRUB diff --git a/docs/man/grub-mkrelpath.h2m b/docs/man/grub-mkrelpath.h2m new file mode 100644 index 000000000..ccc0880fa --- /dev/null +++ b/docs/man/grub-mkrelpath.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkrelpath \- make a system path relative to its root diff --git a/docs/man/grub-mkrescue.h2m b/docs/man/grub-mkrescue.h2m new file mode 100644 index 000000000..5e92e0d99 --- /dev/null +++ b/docs/man/grub-mkrescue.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-mkrescue \- make a GRUB rescue image diff --git a/docs/man/grub-ofpathname.h2m b/docs/man/grub-ofpathname.h2m new file mode 100644 index 000000000..f07158cb3 --- /dev/null +++ b/docs/man/grub-ofpathname.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-ofpathname \- find OpenBOOT path for a device diff --git a/docs/man/grub-pe2elf.h2m b/docs/man/grub-pe2elf.h2m new file mode 100644 index 000000000..3fdb88b43 --- /dev/null +++ b/docs/man/grub-pe2elf.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-pe2elf \- convert PE image to ELF diff --git a/docs/man/grub-probe.h2m b/docs/man/grub-probe.h2m new file mode 100644 index 000000000..817ba8ef6 --- /dev/null +++ b/docs/man/grub-probe.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-probe \- probe device information for GRUB diff --git a/docs/man/grub-reboot.h2m b/docs/man/grub-reboot.h2m new file mode 100644 index 000000000..957e4b797 --- /dev/null +++ b/docs/man/grub-reboot.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-reboot \- set the default boot entry for GRUB, for the next boot only diff --git a/docs/man/grub-script-check.h2m b/docs/man/grub-script-check.h2m new file mode 100644 index 000000000..39c0a3ef6 --- /dev/null +++ b/docs/man/grub-script-check.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-script-check \- check grub.cfg for syntax errors diff --git a/docs/man/grub-set-default.h2m b/docs/man/grub-set-default.h2m new file mode 100644 index 000000000..3ac13d7ed --- /dev/null +++ b/docs/man/grub-set-default.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-set-default \- set the default boot entry for GRUB diff --git a/docs/man/grub-setup.h2m b/docs/man/grub-setup.h2m new file mode 100644 index 000000000..e70e465a4 --- /dev/null +++ b/docs/man/grub-setup.h2m @@ -0,0 +1,2 @@ +[NAME] +grub-setup \- set up a device to boot using GRUB From 283af07aff47fdc234e80da3fa4c5891f0ab9289 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 11 Jun 2010 22:15:35 +0100 Subject: [PATCH 96/96] * include/grub/efi/uga_draw.h (GRUB_EFI_UGA_GLT_MAX): Rename to ... (GRUB_EFI_UGA_BLT_MAX): ... this (typo fix). --- ChangeLog | 5 +++++ include/grub/efi/uga_draw.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 43cf36b32..ab9415191 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2010-06-11 Colin Watson + + * include/grub/efi/uga_draw.h (GRUB_EFI_UGA_GLT_MAX): Rename to ... + (GRUB_EFI_UGA_BLT_MAX): ... this (typo fix). + 2010-06-11 Colin Watson * Makefile.in (install-local): Include $(srcdir)/docs/man/$$dest.h2m diff --git a/include/grub/efi/uga_draw.h b/include/grub/efi/uga_draw.h index 93504307c..a31f2672e 100644 --- a/include/grub/efi/uga_draw.h +++ b/include/grub/efi/uga_draw.h @@ -32,7 +32,7 @@ enum grub_efi_uga_blt_operation GRUB_EFI_UGA_VIDEO_TO_BLT, GRUB_EFI_UGA_BLT_TO_VIDEO, GRUB_EFI_UGA_VIDEO_TO_VIDEO, - GRUB_EFI_UGA_GLT_MAX + GRUB_EFI_UGA_BLT_MAX }; struct grub_efi_uga_pixel