From 3c52136a94b35e026724c9f444848f495a71fe05 Mon Sep 17 00:00:00 2001 From: okuji Date: Fri, 10 Sep 2004 20:31:55 +0000 Subject: [PATCH] 2004-09-10 Yoshinori K. Okuji * normal/menu.c: Include grub/loader.h and grub/machine/time.h. (print_message): Add a missing newline. (run_menu): Added timeout support. (run_menu_entry): New local function. (grub_menu_run): Added support for booting. * kern/loader.c (grub_loader_is_loaded): New function. * include/grub/powerpc/ieee1275/time.h: Include grub/symbol.h. (grub_get_rtc): Exported. * include/grub/i386/pc/time.h: Include grub/symbol.h. (grub_get_rtc): Exported. * include/grub/normal.h (struct grub_command_list): Remove constant from the member `command'. * include/grub/loader.h (grub_loader_is_loaded): Declared. * include/grub/err.h (GRUB_ERR_INVALID_COMMAND): New constant. * conf/i386-pc.rmk (kernel_img_HEADERS): Added machine/time.h. --- ChangeLog | 25 ++++ conf/i386-pc.mk | 4 +- conf/i386-pc.rmk | 4 +- include/grub/err.h | 3 +- include/grub/i386/pc/time.h | 6 +- include/grub/loader.h | 3 +- include/grub/normal.h | 2 +- include/grub/powerpc/ieee1275/time.h | 6 +- kern/loader.c | 8 +- normal/menu.c | 213 ++++++++++++++++++++------- 10 files changed, 209 insertions(+), 65 deletions(-) diff --git a/ChangeLog b/ChangeLog index fcfb850bf..57bae7e3f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2004-09-10 Yoshinori K. Okuji + + * normal/menu.c: Include grub/loader.h and grub/machine/time.h. + (print_message): Add a missing newline. + (run_menu): Added timeout support. + (run_menu_entry): New local function. + (grub_menu_run): Added support for booting. + + * kern/loader.c (grub_loader_is_loaded): New function. + + * include/grub/powerpc/ieee1275/time.h: Include grub/symbol.h. + (grub_get_rtc): Exported. + + * include/grub/i386/pc/time.h: Include grub/symbol.h. + (grub_get_rtc): Exported. + + * include/grub/normal.h (struct grub_command_list): Remove + constant from the member `command'. + + * include/grub/loader.h (grub_loader_is_loaded): Declared. + + * include/grub/err.h (GRUB_ERR_INVALID_COMMAND): New constant. + + * conf/i386-pc.rmk (kernel_img_HEADERS): Added machine/time.h. + 2004-08-28 Marco Gerards Add support for the JFS filesystem. diff --git a/conf/i386-pc.mk b/conf/i386-pc.mk index 87e5c151a..be6ee07cc 100644 --- a/conf/i386-pc.mk +++ b/conf/i386-pc.mk @@ -249,11 +249,11 @@ kernel_img-symlist.d: symlist.c -include kernel_img-symlist.d -kernel_img_HEADERS = boot.h device.h disk.h dl.h elf.h err.h \ +kernel_img_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \ file.h fs.h kernel.h loader.h misc.h mm.h net.h rescue.h symbol.h \ term.h types.h machine/biosdisk.h machine/boot.h \ machine/console.h machine/init.h machine/memory.h \ - machine/loader.h machine/partition.h machine/vga.h arg.h env.h + machine/loader.h machine/partition.h machine/time.h machine/vga.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,8200 diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk index f06cc0ff3..37c965de4 100644 --- a/conf/i386-pc.rmk +++ b/conf/i386-pc.rmk @@ -29,11 +29,11 @@ kernel_img_SOURCES = kern/i386/pc/startup.S kern/main.c kern/device.c \ kern/env.c disk/i386/pc/biosdisk.c \ term/i386/pc/console.c \ symlist.c -kernel_img_HEADERS = boot.h device.h disk.h dl.h elf.h err.h \ +kernel_img_HEADERS = arg.h boot.h device.h disk.h dl.h elf.h env.h err.h \ file.h fs.h kernel.h loader.h misc.h mm.h net.h rescue.h symbol.h \ term.h types.h machine/biosdisk.h machine/boot.h \ machine/console.h machine/init.h machine/memory.h \ - machine/loader.h machine/partition.h machine/vga.h arg.h env.h + machine/loader.h machine/partition.h machine/time.h machine/vga.h kernel_img_CFLAGS = $(COMMON_CFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_LDFLAGS = -nostdlib -Wl,-N,-Ttext,8200 diff --git a/include/grub/err.h b/include/grub/err.h index a630ec8aa..04a96de11 100644 --- a/include/grub/err.h +++ b/include/grub/err.h @@ -1,7 +1,7 @@ /* err.h - error numbers and prototypes */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003 Free Software Foundation, Inc. + * Copyright (C) 2002,2003,2004 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 @@ -41,6 +41,7 @@ typedef enum GRUB_ERR_READ_ERROR, GRUB_ERR_WRITE_ERROR, GRUB_ERR_UNKNOWN_COMMAND, + GRUB_ERR_INVALID_COMMAND, GRUB_ERR_BAD_ARGUMENT, GRUB_ERR_BAD_PART_TABLE, GRUB_ERR_UNKNOWN_OS, diff --git a/include/grub/i386/pc/time.h b/include/grub/i386/pc/time.h index ccef12732..e95e6ee2c 100644 --- a/include/grub/i386/pc/time.h +++ b/include/grub/i386/pc/time.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003 Free Software Foundation, Inc. + * Copyright (C) 2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +20,8 @@ #ifndef KERNEL_TIME_HEADER #define KERNEL_TIME_HEADER 1 +#include + #ifdef GRUB_UTIL # include # define GRUB_TICKS_PER_SECOND CLOCKS_PER_SEC @@ -28,6 +30,6 @@ #endif /* Return the real time in ticks. */ -grub_uint32_t grub_get_rtc (void); +grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void); #endif /* ! KERNEL_TIME_HEADER */ diff --git a/include/grub/loader.h b/include/grub/loader.h index 6ad8d7922..ce06023fa 100644 --- a/include/grub/loader.h +++ b/include/grub/loader.h @@ -1,7 +1,7 @@ /* loader.h - OS loaders */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003 Free Software Foundation, Inc. + * Copyright (C) 2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,6 +29,7 @@ extern grub_addr_t EXPORT_VAR(grub_os_area_addr); extern grub_size_t EXPORT_VAR(grub_os_area_size); +int EXPORT_FUNC(grub_loader_is_loaded) (void); void EXPORT_FUNC(grub_loader_set) (grub_err_t (*boot) (void), grub_err_t (*unload) (void)); void EXPORT_FUNC(grub_loader_unset) (void); diff --git a/include/grub/normal.h b/include/grub/normal.h index 14d0c5e1d..665fb85c8 100644 --- a/include/grub/normal.h +++ b/include/grub/normal.h @@ -70,7 +70,7 @@ typedef struct grub_command *grub_command_t; struct grub_command_list { /* The string of a command. */ - const char *command; + char *command; /* The next element. */ struct grub_command_list *next; diff --git a/include/grub/powerpc/ieee1275/time.h b/include/grub/powerpc/ieee1275/time.h index dafbef397..8ef712e90 100644 --- a/include/grub/powerpc/ieee1275/time.h +++ b/include/grub/powerpc/ieee1275/time.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003 Marco Gerards + * Copyright (C) 2003,2004 Marco Gerards * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +20,8 @@ #ifndef KERNEL_TIME_HEADER #define KERNEL_TIME_HEADER 1 +#include + #ifdef GRUB_UTIL # include # define GRUB_TICKS_PER_SECOND CLOCKS_PER_SEC @@ -28,6 +30,6 @@ #endif /* Return the real time in ticks. */ -grub_uint32_t grub_get_rtc (void); +grub_uint32_t EXPORT_FUNC (grub_get_rtc) (void); #endif /* ! KERNEL_TIME_HEADER */ diff --git a/kern/loader.c b/kern/loader.c index ea7c774a1..2c1dbe2ed 100644 --- a/kern/loader.c +++ b/kern/loader.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2002,2003 Free Software Foundation, Inc. + * Copyright (C) 2002,2003,2004 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 @@ -27,6 +27,12 @@ static grub_err_t (*grub_loader_unload_func) (void); static int grub_loader_loaded; +int +grub_loader_is_loaded (void) +{ + return grub_loader_loaded; +} + void grub_loader_set (grub_err_t (*boot) (void), grub_err_t (*unload) (void)) diff --git a/normal/menu.c b/normal/menu.c index a6a7de753..f001b11ab 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2003 Free Software Foundation, Inc. + * Copyright (C) 2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +20,8 @@ #include #include #include +#include +#include /* FIXME: These below are all runaround. */ @@ -80,7 +82,7 @@ print_message (int nested) Press enter to boot the selected OS, \'e\' to edit the\n\ commands before booting, or \'c\' for a command-line."); if (nested) - grub_printf ("\ + grub_printf ("\n\ ESC to return previous menu."); } @@ -170,6 +172,7 @@ static int run_menu (grub_menu_t menu, int nested) { int first, offset; + unsigned long saved_time; grub_setcursor (0); @@ -184,93 +187,197 @@ run_menu (grub_menu_t menu, int nested) init_page (nested); print_entries (menu, first, offset); grub_refresh (); + + /* Initialize the time. */ + saved_time = grub_get_rtc (); while (1) { int c; - c = GRUB_TERM_ASCII_CHAR (grub_getkey ()); - switch (c) + if (menu->timeout > 0) { - case 16: - case '^': - if (offset > 0) - { - print_entry (4 + offset, 0, get_entry (menu, first + offset)); - offset--; - print_entry (4 + offset, 1, get_entry (menu, first + offset)); - } - else if (first > 0) - { - first--; - print_entries (menu, first, offset); - } - break; + unsigned long current_time; - case 14: - case 'v': - if (menu->size > first + offset + 1) + current_time = grub_get_rtc (); + if (current_time - saved_time >= GRUB_TICKS_PER_SECOND) { - if (offset < 11) + menu->timeout--; + saved_time = current_time; + } + + grub_gotoxy (3, 22); + grub_printf ("The highlighted entry will be booted automatically in %d seconds. ", + menu->timeout); + grub_gotoxy (74, 4 + offset); + grub_refresh (); + } + + if (menu->timeout == 0) + return menu->default_entry; + + if (grub_checkkey () >= 0 || menu->timeout < 0) + { + c = GRUB_TERM_ASCII_CHAR (grub_getkey ()); + + if (menu->timeout >= 0) + { + grub_gotoxy (3, 22); + grub_printf (" "); + menu->timeout = -1; + menu->fallback_entry = -1; + grub_gotoxy (74, 4 + offset); + } + + switch (c) + { + case 16: + case '^': + if (offset > 0) { print_entry (4 + offset, 0, get_entry (menu, first + offset)); - offset++; + offset--; print_entry (4 + offset, 1, get_entry (menu, first + offset)); } - else + else if (first > 0) { - first++; + first--; print_entries (menu, first, offset); } - } - break; - - case '\n': - case '\r': - case 6: - grub_setcursor (1); - return first + offset; - - case '\e': - if (nested) - { + break; + + case 14: + case 'v': + if (menu->size > first + offset + 1) + { + if (offset < 11) + { + print_entry (4 + offset, 0, + get_entry (menu, first + offset)); + offset++; + print_entry (4 + offset, 1, + get_entry (menu, first + offset)); + } + else + { + first++; + print_entries (menu, first, offset); + } + } + break; + + case '\n': + case '\r': + case 6: grub_setcursor (1); - return -1; + return first + offset; + + case '\e': + if (nested) + { + grub_setcursor (1); + return -1; + } + break; + + case 'c': + grub_setcursor (1); + grub_cmdline_run (1); + grub_setcursor (0); + init_page (nested); + print_entries (menu, first, offset); + break; + + default: + break; } - break; - - case 'c': - grub_setcursor (1); - grub_cmdline_run (1); - grub_setcursor (0); - init_page (nested); - print_entries (menu, first, offset); - break; - - default: - break; + + grub_refresh (); } - - grub_refresh (); } /* Never reach here. */ return -1; } +/* Run a menu entry. */ +static void +run_menu_entry (grub_menu_entry_t entry) +{ + grub_command_list_t cl; + + for (cl = entry->command_list; cl != 0; cl = cl->next) + { + grub_command_t c; + + c = grub_command_find (cl->command); + if (! c) + break; + + if (! (c->flags & GRUB_COMMAND_FLAG_CMDLINE)) + { + grub_error (GRUB_ERR_INVALID_COMMAND, + "invalid command `%s'", + cl->command); + break; + } + + if (! (c->flags & GRUB_COMMAND_FLAG_NO_ECHO)) + grub_printf ("%s\n", cl->command); + + if (grub_command_execute (cl->command) != 0) + break; + } + + if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) + /* Implicit execution of boot, only if something is loaded. */ + grub_command_execute ("boot"); +} + void grub_menu_run (grub_menu_t menu, int nested) { while (1) { int boot_entry; + grub_menu_entry_t e; boot_entry = run_menu (menu, nested); if (boot_entry < 0) break; - /* FIXME: Boot the entry. */ + grub_cls (); + grub_setcursor (1); + + e = get_entry (menu, boot_entry); + grub_printf (" Booting \'%s\'\n\n", e->title); + + run_menu_entry (e); + + /* Deal with a fallback entry. */ + /* FIXME: Mutiple fallback entries like GRUB Legacy. */ + if (menu->fallback_entry >= 0) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + + e = get_entry (menu, menu->fallback_entry); + menu->fallback_entry = -1; + grub_printf ("\n Falling back to \'%s\'\n\n", e->title); + run_menu_entry (e); + } + + if (grub_errno != GRUB_ERR_NONE) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + + /* Wait until the user pushes any key so that the user + can see what happened. */ + grub_printf ("\nPress any key to continue..."); + (void) grub_getkey (); + } } }