From 44fed9dca9311fa21f516c8812f017771953ceb6 Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Fri, 27 Aug 2004 23:12:38 -0600 Subject: [PATCH] Imported Debian patch 0.4.9-0.sarge.2 --- Makefile | 8 +- README | 9 +- debian/changelog | 31 ++++ doc/ChangeLog | 20 +++ src/efibootmgr/efibootmgr.c | 268 ++++++++++++------------------ src/efibootmgr/module.mk | 16 +- src/include/efi.h | 43 +++-- src/include/efibootmgr.h | 3 + src/include/efivars_procfs.h | 30 ++++ src/include/efivars_sysfs.h | 30 ++++ src/lib/efi.c | 199 ++++++++++------------ src/lib/efivars_procfs.c | 180 ++++++++++++++++++++ src/lib/efivars_sysfs.c | 120 +++++++++++++ src/man/man8/efibootmgr.8 | 42 +++-- src/man/man8/efibootmgr.8.docbook | 34 +++- 15 files changed, 714 insertions(+), 319 deletions(-) create mode 100644 src/include/efivars_procfs.h create mode 100644 src/include/efivars_sysfs.h create mode 100644 src/lib/efivars_procfs.c create mode 100644 src/lib/efivars_sysfs.c diff --git a/Makefile b/Makefile index 67d275a..3ae1463 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ default: all - RELEASE_DATE := "04-Sep-2003" + RELEASE_DATE := "24-Feb-2004" RELEASE_MAJOR := 0 - RELEASE_MINOR := 4 - RELEASE_SUBLEVEL := 2 - RELEASE_EXTRALEVEL := + RELEASE_MINOR := 5 + RELEASE_SUBLEVEL := 0 + RELEASE_EXTRALEVEL := -test3 RELEASE_NAME := efibootmgr RELEASE_STRING := $(RELEASE_NAME)-$(RELEASE_MAJOR).$(RELEASE_MINOR).$(RELEASE_SUBLEVEL)$(RELEASE_EXTRALEVEL) diff --git a/README b/README index 1fb38fd..9ee586b 100644 --- a/README +++ b/README @@ -29,7 +29,9 @@ usage: efibootmgr [options] -O | --delete-bootorder delete BootOrder -p | --part part (defaults to 1) containing loader -q | --quiet be quiet - -t | --test filename don't write to NVRAM, write to filename + --test filename don't write to NVRAM, write to filename + -t | --timeout seconds Boot manager timeout + -T | --delete-timeout delete Timeout value -u | --unicode | --UCS-2 pass extra args as UCS-2 (default is ASCII) -U | --acpi_uid XXXX set the ACPI UID (used with -i) -v | --verbose print additional information @@ -43,6 +45,7 @@ Typical usage: BootCurrent: 0004 BootNext: 0003 BootOrder: 0004,0000,0001,0002,0003 + Timeout: 30 seconds Boot0000* Diskette Drive(device:0) Boot0001* CD-ROM Drive(device:FF) Boot0002* Hard Drive(Device:80)/HD(Part1,Sig00112233) @@ -62,6 +65,10 @@ Typical usage: boot manager after first use. This allows you to change the next boot behavior without changing BootOrder. + Timeout - the time in seconds between when the boot manager appears + on the screen until when it automatically chooses the startup value + from BootNext or BootOrder. + Five boot entries (0000 - 0004), the active/inactive flag (* means active), and the name displayed on the screen. diff --git a/debian/changelog b/debian/changelog index c5b5007..1aa9376 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,34 @@ +efibootmgr (0.4.9-0.sarge.2) testing; urgency=high + + * Base dependencies are frozen; this release reverts the portion of the + test4 changes that added a dependency on pciutils. Thanks to Dann Frazier + for figuring this out and providing a suitable patch. Closes: #268490 + + -- Bdale Garbee Fri, 27 Aug 2004 23:12:38 -0600 + +efibootmgr (0.4.9-0.sarge.1) testing; urgency=high + + * build 0.4.9-1 in testing chroot for sarge + * new upstream version. This is actually 0.5.0-test4, renumbered to avoid + nastiness when 0.5.0 is released. Upstream says 0.5.0 will be this code + with a documentation change. Closes: #258838, #235227 + * add pciutils-dev to build dependencies since we need libpci now + * hack in a typedef to get a u64 definition for ethtool.h + * urgency high because previous version fails with current 2.6 kernels + + -- Bdale Garbee Wed, 18 Aug 2004 09:47:21 -0600 + +efibootmgr (0.4.9-1) unstable; urgency=high + + * new upstream version. This is actually 0.5.0-test4, renumbered to avoid + nastiness when 0.5.0 is released. Upstream says 0.5.0 will be this code + with a documentation change. Closes: #258838, #235227 + * add pciutils-dev to build dependencies since we need libpci now + * hack in a typedef to get a u64 definition for ethtool.h + * urgency high because previous version fails with current 2.6 kernels + + -- Bdale Garbee Wed, 18 Aug 2004 08:59:03 -0600 + efibootmgr (0.4.2-4) unstable; urgency=low * add amd64 to the list of architectures to build on, closes: #249988 diff --git a/doc/ChangeLog b/doc/ChangeLog index 5daad8f..2841c36 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,23 @@ +* Sat Apr 24 2004 Matt Domsch +- Fixed reversed logic of create_or_edit_variable which prevented object + creation or editing on sysfs. +- Removed debug printfs in sysfs read/write commands. +- Released v0.5.0-test3 + +* Thu Feb 04 2004 Matt Domsch +- removed -t short option for --test +- added -t and -T delete timeout options +- updated man page and README about the timeout options +- Released v0.5.0-test2 + +* Tue Sep 09 2003 Matt Domsch +- Released v0.5.0-test1 + +* Thu Sep 04 2003 Matt Domsch +- Seperated access to variables through /proc into efivars_procfs.[ch] +- Added efivars_sysfs.h to access variables through sysfs. +- Moved around some functions, cleaned up some duplication. + * Thu Sep 04 2003 Matt Domsch - released v0.4.2-test2 as v0.4.2 without additional changes. diff --git a/src/efibootmgr/efibootmgr.c b/src/efibootmgr/efibootmgr.c index 4184143..1aa3595 100644 --- a/src/efibootmgr/efibootmgr.c +++ b/src/efibootmgr/efibootmgr.c @@ -1,7 +1,7 @@ /* efibootmgr.c - Manipulates EFI variables as exported in /proc/efi/vars - Copyright (C) 2001 Dell Computer Corporation + Copyright (C) 2001-2004 Dell, 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 @@ -49,6 +49,7 @@ #include "disk.h" #include "efibootmgr.h" + #ifndef EFIBOOTMGR_VERSION #define EFIBOOTMGR_VERSION "unknown (fix Makefile!)" #endif @@ -73,55 +74,27 @@ var_num_from_name(const char *pattern, char *name, uint16_t *num) sscanf(name, pattern, num); } -static int -select_boot_var_names(const struct dirent *d) +static void +fill_bootvar_name(char *dest, size_t len, const char *name) { - int num, rc; - rc = sscanf(d->d_name, "Boot0%03x-%*s", &num); - return rc; + efi_guid_t guid = EFI_GLOBAL_VARIABLE; + char text_uuid[40]; + efi_guid_unparse(&guid, text_uuid); + snprintf(dest, len, "%s-%s", name, text_uuid); } -#if 0 -static int -select_blk_var_names(const struct dirent *d) +static void +fill_var(efi_variable_t *var, const char *name) { - int num; - return sscanf(d->d_name, "blk%x-%*s", &num); -} -#endif + efi_guid_t guid = EFI_GLOBAL_VARIABLE; -static int -read_boot_var_names(struct dirent ***namelist) -{ - int n; - n = scandir(PROC_DIR_EFI_VARS, namelist, select_boot_var_names, alphasort); - if (n < 0) { - perror("scandir " PROC_DIR_EFI_VARS); - fprintf(stderr, "You must 'modprobe efivars' before running efibootmgr.\n"); - } - return n; + efichar_from_char(var->VariableName, name, 1024); + memcpy(&var->VendorGuid, &guid, sizeof(guid)); + var->Attributes = EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS + | EFI_VARIABLE_RUNTIME_ACCESS; } -#if 0 -static int -read_blk_var_names(struct dirent ***namelist) -{ - int n; - n = scandir(PROC_DIR_EFI_VARS, namelist, select_blk_var_names, alphasort); - if (n < 0) - perror("scandir"); - return n; -} - -static int -dirent_list_length(struct dirent **namelist) -{ - int i; - if (!namelist) return 0; - for (i=0; namelist[i]; i++); - return i; -} -#endif static void read_vars(struct dirent **namelist, @@ -273,42 +246,39 @@ make_boot_var(list_t *boot_list) free(boot); return NULL; } - write_variable(&boot->var_data); + create_variable(&boot->var_data); list_add_tail(&boot->list, boot_list); return boot; } + + +static efi_status_t +read_boot(efi_variable_t *var, const char *name) +{ + char name_guid[PATH_MAX]; + + memset(var, 0, sizeof(*var)); + fill_bootvar_name(name_guid, sizeof(name_guid), name); + return read_variable(name_guid, var); +} + static efi_status_t read_boot_order(efi_variable_t *boot_order) { efi_status_t status; - efi_guid_t guid = EFI_GLOBAL_VARIABLE; - char boot_order_name[80], text_uuid[40]; - efi_guid_unparse(&guid, text_uuid); - - memset(boot_order, 0, sizeof(*boot_order)); - sprintf(boot_order_name, "BootOrder-%s", text_uuid); - status = read_variable(boot_order_name, boot_order); + status = read_boot(boot_order, "BootOrder"); if (status != EFI_SUCCESS && status != EFI_NOT_FOUND) return status; if (status == EFI_NOT_FOUND) { - /* Create it */ - efichar_from_char(boot_order->VariableName, "BootOrder", - 1024); - memcpy(&boot_order->VendorGuid, &guid, sizeof(guid)); - boot_order->Attributes = EFI_VARIABLE_NON_VOLATILE - | EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_RUNTIME_ACCESS; - return status; + fill_var(boot_order, "BootOrder"); } return EFI_SUCCESS; } - - static efi_status_t add_to_boot_order(uint16_t num) { @@ -333,7 +303,7 @@ add_to_boot_order(uint16_t num) /* Now new_data has what we need */ memcpy(&(boot_order.Data), new_data, new_data_size); boot_order.DataSize = new_data_size; - return write_variable(&boot_order); + return create_or_edit_variable(&boot_order); } @@ -345,13 +315,16 @@ remove_from_boot_order(uint16_t num) uint64_t new_data_size; uint16_t *new_data, *old_data; int old_i,new_i; + char boot_order_name[PATH_MAX]; status = read_boot_order(&boot_order); if (status != EFI_SUCCESS) return status; - /* If it's empty, yea! */ if (!boot_order.DataSize) return EFI_SUCCESS; + fill_bootvar_name(boot_order_name, sizeof(boot_order_name), + "BootOrder"); + /* We've now got an array (in boot_order.Data) of the boot order. Simply copy the array, skipping the entry we're deleting. @@ -376,101 +349,59 @@ remove_from_boot_order(uint16_t num) memcpy(&(boot_order.Data), new_data, new_data_size); boot_order.DataSize = new_data_size; - return write_variable(&boot_order); + return edit_variable(&boot_order); } -static int -read_boot_current() +static efi_status_t +delete_var(const char *name) { - efi_status_t status; - efi_variable_t boot_next; - efi_guid_t guid = EFI_GLOBAL_VARIABLE; - char boot_next_name[80], text_uuid[40]; - uint16_t *n = (uint16_t *)(boot_next.Data); - - efi_guid_unparse(&guid, text_uuid); - - memset(&boot_next, 0, sizeof(boot_next)); - sprintf(boot_next_name, "BootCurrent-%s", text_uuid); - - status = read_variable(boot_next_name, &boot_next); - if (status) return -1; + efi_variable_t var; - return *n; + memset(&var, 0, sizeof(var)); + fill_var(&var, name); + return delete_variable(&var); } static int -read_boot_next() +read_boot_u16(const char *name) { efi_status_t status; - efi_variable_t boot_next; - efi_guid_t guid = EFI_GLOBAL_VARIABLE; - char boot_next_name[80], text_uuid[40]; - uint16_t *n = (uint16_t *)(boot_next.Data); - - efi_guid_unparse(&guid, text_uuid); - - memset(&boot_next, 0, sizeof(boot_next)); - sprintf(boot_next_name, "BootNext-%s", text_uuid); + efi_variable_t var; + uint16_t *n = (uint16_t *)(var.Data); - status = read_variable(boot_next_name, &boot_next); + memset(&var, 0, sizeof(var)); + status = read_boot(&var, name); if (status) return -1; - return *n; } - static efi_status_t -set_boot_next(uint16_t num) +set_boot_u16(const char *name, uint16_t num) { efi_variable_t var; - efi_guid_t guid = EFI_GLOBAL_VARIABLE; uint16_t *n = (uint16_t *)var.Data; memset(&var, 0, sizeof(var)); - efichar_from_char(var.VariableName, "BootNext", - 1024); - memcpy(&var.VendorGuid, &guid, sizeof(guid)); + fill_var(&var, name); *n = num; var.DataSize = sizeof(uint16_t); - var.Attributes = EFI_VARIABLE_NON_VOLATILE - | EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_RUNTIME_ACCESS; - return write_variable(&var); + return create_or_edit_variable(&var); } -static efi_status_t -delete_boot_next() -{ - efi_variable_t var; - efi_guid_t guid = EFI_GLOBAL_VARIABLE; - - memset(&var, 0, sizeof(var)); - - efichar_from_char(var.VariableName, "BootNext", - 1024); - memcpy(&var.VendorGuid, &guid, sizeof(guid)); - return write_variable(&var); -} - - static efi_status_t delete_boot_var(uint16_t num) { efi_status_t status; efi_variable_t var; - efi_guid_t guid = EFI_GLOBAL_VARIABLE; - char name[80]; + char name[16]; list_t *pos, *n; var_entry_t *boot; - sprintf(name, "Boot%04x", num); + snprintf(name, sizeof(name), "Boot%04x", num); memset(&var, 0, sizeof(var)); - - efichar_from_char(var.VariableName, name, 1024); - memcpy(&var.VendorGuid, &guid, sizeof(guid)); - status = write_variable(&var); + fill_var(&var, name); + status = delete_variable(&var); if (status) return status; @@ -624,23 +555,16 @@ parse_boot_order(char *buffer, uint16_t *order, int length) static efi_status_t set_boot_order() { - efi_variable_t var; - efi_guid_t guid = EFI_GLOBAL_VARIABLE; - uint16_t *n = (uint16_t *)var.Data; + efi_variable_t boot_order; + uint16_t *n = (uint16_t *)boot_order.Data; if (!opts.bootorder) return EFI_SUCCESS; - memset(&var, 0, sizeof(var)); + memset(&boot_order, 0, sizeof(boot_order)); + fill_var(&boot_order, "BootOrder"); - efichar_from_char(var.VariableName, "BootOrder", - 1024); - memcpy(&var.VendorGuid, &guid, sizeof(guid)); - var.Attributes = EFI_VARIABLE_NON_VOLATILE - | EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_RUNTIME_ACCESS; - - var.DataSize = parse_boot_order(opts.bootorder, n, 1024/sizeof(uint16_t)) * sizeof(uint16_t); - return write_variable(&var); + boot_order.DataSize = parse_boot_order(opts.bootorder, n, 1024/sizeof(uint16_t)) * sizeof(uint16_t); + return create_or_edit_variable(&boot_order); } static void @@ -733,7 +657,7 @@ set_active_state() else { load_option->attributes |= LOAD_OPTION_ACTIVE; - return write_variable(&boot->var_data); + return edit_variable(&boot->var_data); } } else if (opts.active == 0) { @@ -743,7 +667,7 @@ set_active_state() else { load_option->attributes &= ~LOAD_OPTION_ACTIVE; - return write_variable(&boot->var_data); + return edit_variable(&boot->var_data); } } } @@ -753,20 +677,6 @@ set_active_state() -static efi_status_t -delete_boot_order() -{ - efi_variable_t var; - efi_guid_t guid = EFI_GLOBAL_VARIABLE; - - memset(&var, 0, sizeof(var)); - - efichar_from_char(var.VariableName, "BootOrder", - 1024); - memcpy(&var.VendorGuid, &guid, sizeof(guid)); - return write_variable(&var); -} - static void usage() @@ -792,7 +702,9 @@ usage() printf("\t-O | --delete-bootorder delete BootOrder\n"); printf("\t-p | --part part (defaults to 1) containing loader\n"); printf("\t-q | --quiet be quiet\n"); - printf("\t-t | --test filename don't write to NVRAM, write to filename.\n"); + printf("\t | --test filename don't write to NVRAM, write to filename.\n"); + printf("\t-t | --timeout seconds set boot manager timeout waiting for user input.\n"); + printf("\t-T | --delete-timeout delete Timeout.\n"); printf("\t-u | --unicode | --UCS-2 pass extra args as UCS-2 (default is ASCII)\n"); printf("\t-U | --acpi_uid XXXX set the ACPI UID (used with -i)\n"); printf("\t-v | --verbose print additional information\n"); @@ -807,6 +719,7 @@ set_default_opts() opts.bootnum = -1; /* auto-detect */ opts.bootnext = -1; /* Don't set it */ opts.active = -1; /* Don't set it */ + opts.timeout = -1; /* Don't set it */ opts.edd10_devicenum = 0x80; opts.loader = "\\elilo.efi"; opts.label = "Linux"; @@ -835,7 +748,7 @@ parse_opts(int argc, char **argv) {"create", no_argument, 0, 'c'}, {"disk", required_argument, 0, 'd'}, {"iface", required_argument, 0, 'i'}, - {"acpi_hid", required_argument, 0, 'H' }, + {"acpi_hid", required_argument, 0, 'H'}, {"edd-device", required_argument, 0, 'E'}, {"edd30", required_argument, 0, 'e'}, {"gpt", no_argument, 0, 'g'}, @@ -847,10 +760,12 @@ parse_opts(int argc, char **argv) {"delete-bootorder", no_argument, 0, 'O'}, {"part", required_argument, 0, 'p'}, {"quiet", no_argument, 0, 'q'}, - {"test", required_argument, 0, 't'}, + {"test", required_argument, 0, 1}, + {"timeout", required_argument, 0, 't'}, + {"delete-timeout", no_argument, 0, 'T'}, {"unicode", no_argument, 0, 'u'}, {"UCS-2", no_argument, 0, 'u'}, - {"acpi_uid", required_argument, 0, 'U' }, + {"acpi_uid", required_argument, 0, 'U'}, {"verbose", optional_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"write-signature", no_argument, 0, 'w'}, @@ -858,7 +773,7 @@ parse_opts(int argc, char **argv) }; c = getopt_long (argc, argv, - "AaBb:cd:e:E:gH:i:l:L:n:No:Op:qt:uU:v::Vw", + "AaBb:cd:e:E:gH:i:l:L:n:No:Op:qt:TuU:v::Vw", long_options, &option_index); if (c == -1) break; @@ -928,9 +843,19 @@ parse_opts(int argc, char **argv) case 'q': opts.quiet = 1; break; - case 't': + case 1: opts.testfile = optarg; break; + case 't': + rc = sscanf(optarg, "%u", &num); + if (rc == 1) { + opts.timeout = num; + opts.set_timeout = 1; + } + break; + case 'T': + opts.delete_timeout = 1; + break; case 'u': opts.unicode = 1; break; @@ -989,6 +914,9 @@ main(int argc, char **argv) return 1; } + if (!opts.testfile) + set_fs_kernel_calls(); + if (!opts.testfile) { num_boot_names = read_boot_var_names(&boot_names); read_vars(boot_names, num_boot_names, &boot_entry_list); @@ -1017,7 +945,7 @@ main(int argc, char **argv) if (!opts.testfile) { if (opts.delete_bootorder) { - delete_boot_order(); + delete_var("BootOrder"); } if (opts.bootorder) { @@ -1026,22 +954,34 @@ main(int argc, char **argv) if (opts.delete_bootnext) { - delete_boot_next(); + delete_var("BootNext"); + } + + if (opts.delete_timeout) { + delete_var("Timeout"); } if (opts.bootnext >= 0) { - set_boot_next(opts.bootnext & 0xFFFF); + set_boot_u16("BootNext", opts.bootnext & 0xFFFF); + } + + if (opts.set_timeout) { + set_boot_u16("Timeout", opts.timeout); } if (!opts.quiet) { - num = read_boot_next(); + num = read_boot_u16("BootNext"); if (num != -1 ) { printf("BootNext: %04x\n", num); } - num = read_boot_current(); + num = read_boot_u16("BootCurrent"); if (num != -1) { printf("BootCurrent: %04x\n", num); } + num = read_boot_u16("Timeout"); + if (num != -1) { + printf("Timeout: %u seconds\n", num); + } show_boot_order(); show_boot_vars(); } diff --git a/src/efibootmgr/module.mk b/src/efibootmgr/module.mk index 7764641..069a648 100644 --- a/src/efibootmgr/module.mk +++ b/src/efibootmgr/module.mk @@ -2,21 +2,21 @@ efibootmgr_SRCDIR := src/efibootmgr efibootmgr_OBJECTS := efibootmgr.o efibootmgr_TARGETS := efibootmgr efibootmgr_FULLTARGET := \ - $(patsubst %, $(efibootmgr_SRCDIR)/%, $(efibootmgr_TARGETS)) + $(patsubst %, $(efibootmgr_SRCDIR)/%, $(efibootmgr_TARGETS)) efibootmgr_FULLOBJECT := \ - $(patsubst %, $(efibootmgr_SRCDIR)/%, $(efibootmgr_OBJECT)) + $(patsubst %, $(efibootmgr_SRCDIR)/%, $(efibootmgr_OBJECT)) efibootmgr_LIBS := crc32.o disk.o efi.o efichar.o gpt.o scsi_ioctls.o \ - unparse_path.o + unparse_path.o efivars_procfs.o efivars_sysfs.o efibootmgr_LIBDIR := src/lib efibootmgr_FULLLIB := \ - $(patsubst %,$(efibootmgr_LIBDIR)/%,$(efibootmgr_LIBS)) + $(patsubst %,$(efibootmgr_LIBDIR)/%,$(efibootmgr_LIBS)) -ALLDEPS += $(efibootmgr_FULLTARGET) +ALLDEPS += $(efibootmgr_FULLTARGET) CLEANLIST += $(efibootmgr_FULLTARGET) CLEANLIST += $(efibootmgr_FULLOBJECT) -bindir_TARGETS += $(efibootmgr_FULLTARGET) +bindir_TARGETS += $(efibootmgr_FULLTARGET) $(efibootmgr_FULLTARGET): \ - $(efibootmgr_FULLOBJECT) \ - $(efibootmgr_FULLLIB) + $(efibootmgr_FULLOBJECT) \ + $(efibootmgr_FULLLIB) diff --git a/src/include/efi.h b/src/include/efi.h index b53187e..5fc52ff 100644 --- a/src/include/efi.h +++ b/src/include/efi.h @@ -1,8 +1,8 @@ /* - efi.[ch] - Manipulates EFI variables as exported in /proc/efi/vars - - Copyright (C) 2001 Dell Computer Corporation - + efi.[ch] - Extensible Firmware Interface definitions + + Copyright (C) 2001, 2003 Dell Computer Corporation + 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 the Free Software Foundation; either version 2 of the License, or @@ -27,6 +27,7 @@ * version 1.02, 12 December, 2000 */ #include +#include #define BITS_PER_LONG (sizeof(unsigned long) * 8) @@ -336,24 +337,34 @@ typedef struct { } __attribute__((packed)) END_DEVICE_PATH; -/* Used for ACPI _HID */ -#define EISAID_PNP0A03 0xa0341d0 - -#define PROC_DIR_EFI_VARS "/proc/efi/vars/" +struct efivar_kernel_calls { + efi_status_t (*read)(const char *name, efi_variable_t *var); + efi_status_t (*edit)(const char *name, efi_variable_t *var); + efi_status_t (*create)(efi_variable_t *var); + efi_status_t (*delete)(efi_variable_t *var); + char *path; +}; +/* Used for ACPI _HID */ +#define EISAID_PNP0A03 0xa0341d0 /* Exported functions */ -efi_status_t read_variable(char *name, efi_variable_t *var); -efi_status_t write_variable(efi_variable_t *var); -int make_linux_efi_variable(efi_variable_t *var, +extern int make_linux_efi_variable(efi_variable_t *var, unsigned int free_number); -char * efi_guid_unparse(efi_guid_t *guid, char *out); -EFI_DEVICE_PATH *load_option_path(EFI_LOAD_OPTION *option); - - +extern char * efi_guid_unparse(efi_guid_t *guid, char *out); +extern EFI_DEVICE_PATH *load_option_path(EFI_LOAD_OPTION *option); +extern efi_status_t read_variable(const char *name, efi_variable_t *var); +extern efi_status_t edit_variable(efi_variable_t *var); +extern efi_status_t create_variable(efi_variable_t *var); +extern efi_status_t delete_variable(efi_variable_t *var); +extern efi_status_t create_or_edit_variable(efi_variable_t *var); +extern void set_fs_kernel_calls(); +extern int read_boot_var_names(struct dirent ***namelist); +extern int variable_to_name(efi_variable_t *var, char *name); +extern int var_name_to_path(const char *name, char *path); -#endif /* _ASM_IA64_EFI_H */ +#endif /* EFI_H */ diff --git a/src/include/efibootmgr.h b/src/include/efibootmgr.h index 163793f..3546834 100644 --- a/src/include/efibootmgr.h +++ b/src/include/efibootmgr.h @@ -49,6 +49,9 @@ typedef struct { unsigned int unicode:1; unsigned int write_signature:1; unsigned int forcegpt:1; + unsigned int set_timeout:1; + unsigned int delete_timeout:1; + unsigned short int timeout; } efibootmgr_opt_t; diff --git a/src/include/efivars_procfs.h b/src/include/efivars_procfs.h new file mode 100644 index 0000000..2f0958d --- /dev/null +++ b/src/include/efivars_procfs.h @@ -0,0 +1,30 @@ +/* + efivars_procfs.h - EFI Variables accessed through /proc/efi/vars + + Copyright (C) 2003 Dell Computer Corporation + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EFIVARS_PROCFS_H +#define EFIVARS_PROCFS_H + +#include "efi.h" + +#define PROCFS_DIR_EFI_VARS "/proc/efi/vars" + +extern struct efivar_kernel_calls procfs_kernel_calls; + +#endif /* EFIVARS_PROCFS_H */ diff --git a/src/include/efivars_sysfs.h b/src/include/efivars_sysfs.h new file mode 100644 index 0000000..1e24810 --- /dev/null +++ b/src/include/efivars_sysfs.h @@ -0,0 +1,30 @@ +/* + efivars_sysfs.h - EFI Variables accessed through /sys/firmware/efi/vars + + Copyright (C) 2003 Dell Computer Corporation + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef EFIVARS_SYSFS_H +#define EFIVARS_SYSFS_H + +#include "efi.h" + +#define SYSFS_DIR_EFI_VARS "/sys/firmware/efi/vars" + +extern struct efivar_kernel_calls sysfs_kernel_calls; + +#endif /* EFIVARS_SYSFS_H */ diff --git a/src/lib/efi.c b/src/lib/efi.c index 0ab0339..ebfcdbc 100644 --- a/src/lib/efi.c +++ b/src/lib/efi.c @@ -1,5 +1,5 @@ /* - efi.[ch] - Manipulates EFI variables as exported in /proc/efi/vars + efivars_proc.[ch] - Manipulates EFI variables as exported in /proc/efi/vars Copyright (C) 2001,2003 Dell Computer Corporation @@ -47,6 +47,10 @@ typedef __uint8_t u8; /* ditto */ #include "scsi_ioctls.h" #include "disk.h" #include "efibootmgr.h" +#include "efivars_procfs.h" +#include "efivars_sysfs.h" + +static struct efivar_kernel_calls *fs_kernel_calls; EFI_DEVICE_PATH * load_option_path(EFI_LOAD_OPTION *option) @@ -69,36 +73,33 @@ efi_guid_unparse(efi_guid_t *guid, char *out) return out; } - -efi_status_t -read_variable(char *name, efi_variable_t *var) +void +set_fs_kernel_calls() { - int newnamesize; - char *newname; - int fd; - size_t readsize; - if (!name || !var) return EFI_INVALID_PARAMETER; - - newnamesize = strlen(PROC_DIR_EFI_VARS) + strlen(name) + 1; - newname = malloc(newnamesize); - if (!newname) return EFI_OUT_OF_RESOURCES; - sprintf(newname, "%s%s", PROC_DIR_EFI_VARS,name); - fd = open(newname, O_RDONLY); - if (fd == -1) { - free(newname); - return EFI_NOT_FOUND; + char name[PATH_MAX]; + DIR *dir; + snprintf(name, PATH_MAX, "%s", SYSFS_DIR_EFI_VARS); + dir = opendir(name); + if (dir) { + closedir(dir); + fs_kernel_calls = &sysfs_kernel_calls; + return; } - readsize = read(fd, var, sizeof(*var)); - if (readsize != sizeof(*var)) { - free(newname); - close(fd); - return EFI_INVALID_PARAMETER; + + snprintf(name, PATH_MAX, "%s", PROCFS_DIR_EFI_VARS); + dir = opendir(name); + if (dir) { + closedir(dir); + fs_kernel_calls = &procfs_kernel_calls; + return; } - close(fd); - free(newname); - return var->Status; + fprintf(stderr, "Fatal: Couldn't open either sysfs or procfs directories for accessing EFI variables.\n"); + fprintf(stderr, "Try 'modprobe efivars' as root.\n"); + exit(1); } + + static efi_status_t write_variable_to_file(efi_variable_t *var) { @@ -120,108 +121,72 @@ write_variable_to_file(efi_variable_t *var) close(fd); return EFI_SUCCESS; } -/** - * select_variable_names() - * @d - dirent to compare against - * - * This ignores "." and ".." entries, and selects all others. - */ -static int -select_variable_names(const struct dirent *d) +efi_status_t +read_variable(const char *name, efi_variable_t *var) { - if (!strcmp(d->d_name, ".") || - !strcmp(d->d_name, "..")) - return 0; - return 1; + if (!name || !var) return EFI_INVALID_PARAMETER; + return fs_kernel_calls->read(name, var); } -/** - * find_write_victim() - * @var - variable to be written - * @file - name of file to open for writing @var is returned. - * - * This ignores "." and ".." entries, and selects all others. - */ -static char * -find_write_victim(efi_variable_t *var, char file[PATH_MAX]) +efi_status_t +create_variable(efi_variable_t *var) { - struct dirent **namelist = NULL; - int i, n, found=0; - char testname[PATH_MAX], *p; - - memset(testname, 0, sizeof(testname)); - n = scandir(PROC_DIR_EFI_VARS, &namelist, - select_variable_names, alphasort); - if (n < 0) { - perror("scandir " PROC_DIR_EFI_VARS); - fprintf(stderr, "You must 'modprobe efivars' first.\n"); - return NULL; - } + if (!var) return EFI_INVALID_PARAMETER; + if (opts.testfile) return write_variable_to_file(var); + return fs_kernel_calls->create(var); +} - p = testname; - efichar_to_char(p, var->VariableName, PATH_MAX); - p += strlen(p); - p += sprintf(p, "-"); - efi_guid_unparse(&var->VendorGuid, p); +efi_status_t +delete_variable(efi_variable_t *var) +{ + if (!var) return EFI_INVALID_PARAMETER; + if (opts.testfile) return write_variable_to_file(var); + return fs_kernel_calls->delete(var); +} - for (i=0; id_name, sizeof(testname))) { - found++; - sprintf(file, "%s%s", PROC_DIR_EFI_VARS, - namelist[i]->d_name); - break; - } - } - while (n--) { - if (namelist[n]) { - free(namelist[n]); - namelist[n] = NULL; - } - } - free(namelist); +efi_status_t +edit_variable(efi_variable_t *var) +{ + char name[PATH_MAX]; + if (!var) return EFI_INVALID_PARAMETER; + if (opts.testfile) return write_variable_to_file(var); - if (!found) return NULL; - return file; + variable_to_name(var, name); + return fs_kernel_calls->edit(name, var); } - efi_status_t -write_variable(efi_variable_t *var) +create_or_edit_variable(efi_variable_t *var) { - int fd; - size_t writesize; - char buffer[PATH_MAX], name[PATH_MAX], *p = NULL; + efi_variable_t testvar; + char name[PATH_MAX]; - if (!var) return EFI_INVALID_PARAMETER; - if (opts.testfile) return write_variable_to_file(var); - memset(buffer, 0, sizeof(buffer)); - memset(name, 0, sizeof(name)); + memcpy(&testvar, var, sizeof(*var)); + variable_to_name(var, name); - p = find_write_victim(var, name); - if (!p) return EFI_INVALID_PARAMETER; + if (read_variable(name, &testvar) == EFI_SUCCESS) + return edit_variable(var); + else + return create_variable(var); +} - fd = open(name, O_WRONLY); - if (fd == -1) { - sprintf(buffer, "write_variable():open(%s)", name); - perror(buffer); - return EFI_INVALID_PARAMETER; - } - writesize = write(fd, var, sizeof(*var)); - if (writesize != sizeof(*var)) { -#if 0 - sprintf(buffer, "write_variable():write(%s)", name); - perror(buffer); - dump_raw_data(var, sizeof(*var)); -#endif - close(fd); - return EFI_INVALID_PARAMETER; +static int +select_boot_var_names(const struct dirent *d) +{ + int num, rc; + rc = sscanf(d->d_name, "Boot0%03x-%*s", &num); + return rc; +} - } - close(fd); - return EFI_SUCCESS; +int +read_boot_var_names(struct dirent ***namelist) +{ + if (!fs_kernel_calls || !namelist) return -1; + return scandir(fs_kernel_calls->path, + namelist, select_boot_var_names, + alphasort); } @@ -690,3 +655,15 @@ make_linux_efi_variable(efi_variable_t *var, var->DataSize = load_option_size + opt_data_size; return var->DataSize; } + + +int +variable_to_name(efi_variable_t *var, char *name) +{ + char *p = name; + efichar_to_char(p, var->VariableName, PATH_MAX); + p += strlen(p); + p += sprintf(p, "-"); + efi_guid_unparse(&var->VendorGuid, p); + return strlen(name); +} diff --git a/src/lib/efivars_procfs.c b/src/lib/efivars_procfs.c new file mode 100644 index 0000000..2ff5d64 --- /dev/null +++ b/src/lib/efivars_procfs.c @@ -0,0 +1,180 @@ +/* + efivars_procfs.[ch] - Manipulates EFI variables as exported in /proc/efi/vars + + Copyright (C) 2001,2003 Dell Computer Corporation + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define _FILE_OFFSET_BITS 64 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "efi.h" +#include "efichar.h" +#include "efibootmgr.h" +#include "efivars_procfs.h" + +static efi_status_t +procfs_read_variable(const char *name, efi_variable_t *var) +{ + char filename[PATH_MAX]; + int fd; + size_t readsize; + if (!name || !var) return EFI_INVALID_PARAMETER; + + snprintf(filename, PATH_MAX-1, "%s/%s", PROCFS_DIR_EFI_VARS,name); + fd = open(filename, O_RDONLY); + if (fd == -1) { + return EFI_NOT_FOUND; + } + readsize = read(fd, var, sizeof(*var)); + if (readsize != sizeof(*var)) { + close(fd); + return EFI_INVALID_PARAMETER; + } + close(fd); + return var->Status; +} + +/** + * select_variable_names() + * @d - dirent to compare against + * + * This ignores "." and ".." entries, and selects all others. + */ + +static int +select_variable_names(const struct dirent *d) +{ + if (!strcmp(d->d_name, ".") || + !strcmp(d->d_name, "..")) + return 0; + return 1; +} + +/** + * find_write_victim() + * @var - variable to be written + * @file - name of file to open for writing @var is returned. + * + * This ignores "." and ".." entries, and selects all others. + */ +static char * +find_write_victim(efi_variable_t *var, char file[PATH_MAX]) +{ + struct dirent **namelist = NULL; + int i, n, found=0; + char testname[PATH_MAX], *p; + + memset(testname, 0, sizeof(testname)); + n = scandir(PROCFS_DIR_EFI_VARS, &namelist, + select_variable_names, alphasort); + if (n < 0) + return NULL; + + p = testname; + efichar_to_char(p, var->VariableName, PATH_MAX); + p += strlen(p); + p += sprintf(p, "-"); + efi_guid_unparse(&var->VendorGuid, p); + + for (i=0; id_name, sizeof(testname))) { + found++; + sprintf(file, "%s/%s", PROCFS_DIR_EFI_VARS, + namelist[i]->d_name); + break; + } + } + + while (n--) { + if (namelist[n]) { + free(namelist[n]); + namelist[n] = NULL; + } + } + free(namelist); + + if (!found) return NULL; + return file; +} + + +static efi_status_t +procfs_write_variable(efi_variable_t *var) +{ + int fd; + size_t writesize; + char buffer[PATH_MAX], name[PATH_MAX], *p = NULL; + + if (!var) return EFI_INVALID_PARAMETER; + memset(buffer, 0, sizeof(buffer)); + memset(name, 0, sizeof(name)); + + p = find_write_victim(var, name); + if (!p) return EFI_INVALID_PARAMETER; + + fd = open(name, O_WRONLY); + if (fd == -1) { + sprintf(buffer, "write_variable():open(%s)", name); + perror(buffer); + return EFI_INVALID_PARAMETER; + } + writesize = write(fd, var, sizeof(*var)); + if (writesize != sizeof(*var)) { + close(fd); + return EFI_INVALID_PARAMETER; + + } + close(fd); + return EFI_SUCCESS; +} + +static efi_status_t +procfs_delete_variable(efi_variable_t *var) +{ + if (!var) return EFI_INVALID_PARAMETER; + var->DataSize = 0; + var->Attributes = 0; + return procfs_write_variable(var); + +} + +static efi_status_t +procfs_edit_variable(const char *unused, efi_variable_t *var) +{ + if (!var) return EFI_INVALID_PARAMETER; + return procfs_write_variable(var); + +} + +struct efivar_kernel_calls procfs_kernel_calls = { + .read = procfs_read_variable, + .edit = procfs_edit_variable, + .create = procfs_write_variable, + .delete = procfs_delete_variable, + .path = PROCFS_DIR_EFI_VARS, +}; diff --git a/src/lib/efivars_sysfs.c b/src/lib/efivars_sysfs.c new file mode 100644 index 0000000..642c5ad --- /dev/null +++ b/src/lib/efivars_sysfs.c @@ -0,0 +1,120 @@ +/* + efivars_sysfs.[ch] - Manipulates EFI variables as exported in /sys/firmware/efi/vars + + Copyright (C) 2001,2003 Dell Computer Corporation + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define _FILE_OFFSET_BITS 64 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "efi.h" +#include "efichar.h" +#include "efibootmgr.h" +#include "efivars_sysfs.h" + +static efi_status_t +sysfs_read_variable(const char *name, efi_variable_t *var) +{ + char filename[PATH_MAX]; + int fd; + size_t readsize; + char buffer[PATH_MAX+40]; + if (!name || !var) return EFI_INVALID_PARAMETER; + memset(buffer, 0, sizeof(buffer)); + + snprintf(filename, PATH_MAX-1, "%s/%s/raw_var", SYSFS_DIR_EFI_VARS,name); + fd = open(filename, O_RDONLY); + if (fd == -1) { + return EFI_NOT_FOUND; + } + readsize = read(fd, var, sizeof(*var)); + if (readsize != sizeof(*var)) { + close(fd); + return EFI_INVALID_PARAMETER; + } + close(fd); + return var->Status; +} + +static efi_status_t +sysfs_write_variable(const char *filename, efi_variable_t *var) +{ + int fd; + size_t writesize; + char buffer[PATH_MAX+40]; + + if (!filename || !var) return EFI_INVALID_PARAMETER; + memset(buffer, 0, sizeof(buffer)); + + fd = open(filename, O_WRONLY); + if (fd == -1) { + return EFI_INVALID_PARAMETER; + } + writesize = write(fd, var, sizeof(*var)); + if (writesize != sizeof(*var)) { + close(fd); + return EFI_INVALID_PARAMETER; + } + close(fd); + return EFI_SUCCESS; +} + + +static efi_status_t +sysfs_edit_variable(const char *name, efi_variable_t *var) +{ + char filename[PATH_MAX]; + if (!var) return EFI_INVALID_PARAMETER; + snprintf(filename, PATH_MAX-1, "%s/%s/raw_var", SYSFS_DIR_EFI_VARS,name); + return sysfs_write_variable(filename, var); +} + +static efi_status_t +sysfs_create_variable(efi_variable_t *var) +{ + char filename[PATH_MAX]; + if (!var) return EFI_INVALID_PARAMETER; + snprintf(filename, PATH_MAX-1, "%s/%s", SYSFS_DIR_EFI_VARS,"new_var"); + return sysfs_write_variable(filename, var); +} + +static efi_status_t +sysfs_delete_variable(efi_variable_t *var) +{ + char filename[PATH_MAX]; + if (!var) return EFI_INVALID_PARAMETER; + snprintf(filename, PATH_MAX-1, "%s/%s", SYSFS_DIR_EFI_VARS,"del_var"); + return sysfs_write_variable(filename, var); +} + +struct efivar_kernel_calls sysfs_kernel_calls = { + .read = sysfs_read_variable, + .edit = sysfs_edit_variable, + .create = sysfs_create_variable, + .delete = sysfs_delete_variable, + .path = SYSFS_DIR_EFI_VARS, +}; diff --git a/src/man/man8/efibootmgr.8 b/src/man/man8/efibootmgr.8 index a2f6d49..e65a659 100644 --- a/src/man/man8/efibootmgr.8 +++ b/src/man/man8/efibootmgr.8 @@ -3,12 +3,13 @@ .\" .\" Please send any bug reports, improvements, comments, patches, .\" etc. to Steve Cheng . -.TH "EFIBOOTMGR" "8" "11 August 2003" "" "" +.TH "EFIBOOTMGR" "8" "06 February 2004" "" "" + .SH NAME efibootmgr \- manipulate the EFI Boot Manager .SH SYNOPSIS -\fBefibootmgr\fR [ \fB-a\fR] [ \fB-A\fR] [ \fB-b \fIXXXX\fB\fR] [ \fB-B \fIXXXX\fB\fR] [ \fB-c\fR] [ \fB-d \fIDISK\fB\fR] [ \fB-e \fI1|3|-1\fB\fR] [ \fB-E \fINUM\fB\fR] [ \fB-g\fR] [ \fB-H \fIXXXX\fB\fR] [ \fB-i \fINAME\fB\fR] [ \fB-l \fINAME\fB\fR] [ \fB-L \fILABEL\fB\fR] [ \fB-n \fIXXXX\fB\fR] [ \fB-N\fR] [ \fB-o \fIXXXX\fB,\fIYYYY\fB,\fIZZZZ\fB\fR\fI ...\fR] [ \fB-O\fR] [ \fB-p \fIPART\fB\fR] [ \fB-q\fR] [ \fB-t\fR] [ \fB-u\fR] [ \fB-U \fIXXXX\fB\fR] [ \fB-v\fR] [ \fB-V\fR] [ \fB-w\fR] +\fBefibootmgr\fR [ \fB-a\fR ] [ \fB-A\fR ] [ \fB-b \fIXXXX\fB\fR ] [ \fB-B \fIXXXX\fB\fR ] [ \fB-c\fR ] [ \fB-d \fIDISK\fB\fR ] [ \fB-e \fI1|3|-1\fB\fR ] [ \fB-E \fINUM\fB\fR ] [ \fB-g\fR ] [ \fB-H \fIXXXX\fB\fR ] [ \fB-i \fINAME\fB\fR ] [ \fB-l \fINAME\fB\fR ] [ \fB-L \fILABEL\fB\fR ] [ \fB-n \fIXXXX\fB\fR ] [ \fB-N\fR ] [ \fB-o \fIXXXX\fB,\fIYYYY\fB,\fIZZZZ\fB\fR\fI ...\fR ] [ \fB-O\fR ] [ \fB-p \fIPART\fB\fR ] [ \fB-q\fR ] [ \fB-t \fIseconds\fB\fR ] [ \fB-T\fR ] [ \fB-u\fR ] [ \fB-U \fIXXXX\fB\fR ] [ \fB-v\fR ] [ \fB-V\fR ] [ \fB-w\fR ] .SH "DESCRIPTION" .PP @@ -24,7 +25,9 @@ Specification, v1.02 or later, available from: .RS .B "Note:" efibootmgr requires that the kernel support access to EFI -non-volatile variables (through \fI/proc/efi/vars\fR). +non-volatile variables (through +\fI/proc/efi/vars\fR on 2.4 kernels, +\fI/sys/firmware/efi/vars\fR on 2.6 kernels). \fBmodprobe efivars\fR should do the trick. .RE .SH "OPTIONS" @@ -89,9 +92,15 @@ Partition number containing the bootloader (defaults to 1) \fB-q | --quiet\fR Quiet mode - supresses output. .TP -\fB-t | --test \fIfilename\fB\fR +\fB--test \fIfilename\fB\fR Don't write to NVRAM, write to \fIfilename\fR. .TP +\fB-t | --timeout \fIseconds\fB\fR +Boot Manager timeout, in \fIseconds\fR. +.TP +\fB-T | --delete-timeout\fR +Delete Timeout variable. +.TP \fB-u | --unicode | --UCS-2 \fR pass extra command line arguments as UCS-2 (default is ASCII) @@ -108,13 +117,15 @@ Just print version string and exit. \fB-w | --write-signature\fR write unique signature to the MBR if needed .SH "EXAMPLES" -.TP 1. +.TP 3 +1. .SS "DISPLAYING THE CURRENT SETTINGS (MUST BE ROOT)." .PP [root@localhost ~]# efibootmgr BootCurrent: 0004 BootNext: 0003 BootOrder: 0004,0000,0001,0002,0003 +Timeout: 30 seconds Boot0000* Diskette Drive(device:0) Boot0001* CD-ROM Drive(device:FF) Boot0002* Hard Drive(Device:80)/HD(Part1,Sig00112233) @@ -140,10 +151,17 @@ deleted by the boot manager after first use. This allows you to change the next boot behavior without changing BootOrder. .TP 0.2i \(bu +Timeout - the time in seconds between when the boot +manager appears on the screen until when it +automatically chooses the startup value from BootNext +or BootOrder. +.TP 0.2i +\(bu Five boot entries (0000 - 0004), along with the active/inactive flag (* means active) and the name displayed on the screen. .RE -.TP 2. +.TP 3 +2. .SS "CREATING A NEW BOOT OPTION" .PP An OS installer would call \fBefibootmgr -c\fR. @@ -152,25 +170,29 @@ Partition, and is mounted at \fI/dev/sda1\fR. This creates a new boot option, called "Linux", and puts it at the top of the boot order list. Options may be passed to modify the default behavior. The default OS Loader is \fIelilo.efi\fR. -.TP 3. +.TP 3 +3. .SS "CHANGING THE BOOT ORDER" .PP Assuming the configuration in Example #1, \fBefibootmgr -o 3,4\fR could be called to specify PXE boot first, then Linux boot. -.TP 4. +.TP 3 +4. .SS "CHANGING THE BOOT ORDER FOR THE NEXT BOOT ONLY" .PP Assuming the configuration in Example #1, \fBefibootmgr -n 4\fR could be called to specify that the Linux entry be taken on next boot. -.TP 5. +.TP 3 +5. .SS "DELETING A BOOT OPTION" .PP Assuming the configuration in Example #1, \fBefibootmgr -b 4 -B\fR could be called to delete entry 4 and remove it from the BootOrder. -.TP 6. +.TP 3 +6. .SS "CREATING NETWORK BOOT ENTRIES" .PP A system administrator wants to create a boot option to network diff --git a/src/man/man8/efibootmgr.8.docbook b/src/man/man8/efibootmgr.8.docbook index 81c65b9..0eec0f7 100644 --- a/src/man/man8/efibootmgr.8.docbook +++ b/src/man/man8/efibootmgr.8.docbook @@ -17,7 +17,7 @@ dann"> frazier"> - 2003-08-11"> + 2004-02-05"> 8"> @@ -37,7 +37,7 @@ &mansurname; - 2002, 2003 + 2002, 2003, 2004 &manusername; &mandate; @@ -75,7 +75,8 @@ -O -p PART -q - -t + -t seconds + -T -u -U XXXX -v @@ -100,7 +101,9 @@ &manpackage; requires that the kernel support access to EFI - non-volatile variables (through /proc/efi/vars). + non-volatile variables (through + /proc/efi/vars on 2.4 kernels, + /sys/firmware/efi/vars on 2.6 kernels). modprobe efivars should do the trick. @@ -228,11 +231,23 @@ - | filename + filename Don't write to NVRAM, write to filename. + + | seconds + + Boot Manager timeout, in seconds. + + + + | + + Delete Timeout variable. + + | | @@ -280,6 +295,7 @@ BootCurrent: 0004 BootNext: 0003 BootOrder: 0004,0000,0001,0002,0003 + Timeout: 30 seconds Boot0000* Diskette Drive(device:0) Boot0001* CD-ROM Drive(device:FF) Boot0002* Hard Drive(Device:80)/HD(Part1,Sig00112233) @@ -308,6 +324,14 @@ to change the next boot behavior without changing BootOrder. + + + Timeout - the time in seconds between when the boot + manager appears on the screen until when it + automatically chooses the startup value from BootNext + or BootOrder. + + Five boot entries (0000 - 0004), along with the active/inactive -- 2.30.2