Imported Debian patch 0.4.9-0.sarge.2 debian/0.4.9-0.sarge.2
authorBdale Garbee <bdale@gag.com>
Sat, 28 Aug 2004 05:12:38 +0000 (23:12 -0600)
committerBdale Garbee <bdale@gag.com>
Tue, 20 May 2008 05:06:18 +0000 (23:06 -0600)
15 files changed:
Makefile
README
debian/changelog
doc/ChangeLog
src/efibootmgr/efibootmgr.c
src/efibootmgr/module.mk
src/include/efi.h
src/include/efibootmgr.h
src/include/efivars_procfs.h [new file with mode: 0644]
src/include/efivars_sysfs.h [new file with mode: 0644]
src/lib/efi.c
src/lib/efivars_procfs.c [new file with mode: 0644]
src/lib/efivars_sysfs.c [new file with mode: 0644]
src/man/man8/efibootmgr.8
src/man/man8/efibootmgr.8.docbook

index 67d275ac7d4672fde40a9803289ea9c20f7f0051..3ae14633c0960f1df3c579b723fa6a1301023fdc 100644 (file)
--- 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 1fb38fdb13281a824aa932ae99d3e62137a3c71c..9ee586be5b94b95e3728f854fd7cef52a026841c 100644 (file)
--- 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.
 
index c5b500726ade40826885cfdfbc1956a0972cdce5..1aa93767178c15bb4f282ab4b6370d4da42003c3 100644 (file)
@@ -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 <bdale@gag.com>  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 <bdale@gag.com>  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 <bdale@gag.com>  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
index 5daad8f12f63d86108781e99b2801bdee918b09d..2841c362bcfa42e85f1d42f7ad0a69f3d7e74aa2 100644 (file)
@@ -1,3 +1,23 @@
+* Sat Apr 24 2004 Matt Domsch <Matt_Domsch@dell.com>
+- 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 <Matt_Domsch@dell.com>
+- removed -t short option for --test
+- added -t <timeout> 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 <Matt_Domsch@dell.com>
+- Released v0.5.0-test1
+
+* Thu Sep 04 2003 Matt Domsch <Matt_Domsch@dell.com>
+- 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 <Matt_Domsch@dell.com>
 - released v0.4.2-test2 as v0.4.2 without additional changes.
 
index 41841432d8cdbe4bcd864d84a4b829fe525f3242..1aa3595e38253686e430c4f6c7ac86df1679b033 100644 (file)
@@ -1,7 +1,7 @@
 /*
   efibootmgr.c - Manipulates EFI variables as exported in /proc/efi/vars
 
-  Copyright (C) 2001 Dell Computer Corporation <Matt_Domsch@dell.com>
+  Copyright (C) 2001-2004 Dell, Inc. <Matt_Domsch@dell.com>
 
     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();
                }
index 7764641743e4a318a3a395f0e214cdd94e06dece..069a6485f8e1520f629cd6c4c22657a16670614d 100644 (file)
@@ -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)
index b53187edb80c824685c72243843e1203466ea203..5fc52ff48fdc678f34ad95503b725436c9ab3ec9 100644 (file)
@@ -1,8 +1,8 @@
 /*
-  efi.[ch] - Manipulates EFI variables as exported in /proc/efi/vars
-  Copyright (C) 2001 Dell Computer Corporation <Matt_Domsch@dell.com>
+  efi.[ch] - Extensible Firmware Interface definitions
+
+  Copyright (C) 2001, 2003 Dell Computer Corporation <Matt_Domsch@dell.com>
+
     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 <stdint.h>
+#include <dirent.h>
 
 #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 */
index 163793f61cff0da07da05a6be5d3077922ca15a8..3546834d5b5f2eff17bb679840ea78af0229f3e4 100644 (file)
@@ -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 (file)
index 0000000..2f0958d
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+  efivars_procfs.h - EFI Variables accessed through /proc/efi/vars
+
+  Copyright (C) 2003 Dell Computer Corporation <Matt_Domsch@dell.com>
+
+    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 (file)
index 0000000..1e24810
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+  efivars_sysfs.h - EFI Variables accessed through /sys/firmware/efi/vars
+
+  Copyright (C) 2003 Dell Computer Corporation <Matt_Domsch@dell.com>
+
+    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 */
index 0ab0339b23a852d591dfa38236b4394f99a5da88..ebfcdbc41318a935603119e5c47efbd39c3dcbbd 100644 (file)
@@ -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 <Matt_Domsch@dell.com>
 
@@ -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; i<n; i++) {
-               if (namelist[i] &&
-                   strncmp(testname, namelist[i]->d_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 (file)
index 0000000..2ff5d64
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+  efivars_procfs.[ch] - Manipulates EFI variables as exported in /proc/efi/vars
+
+  Copyright (C) 2001,2003 Dell Computer Corporation <Matt_Domsch@dell.com>
+
+    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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#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; i<n; i++) {
+               if (namelist[i] &&
+                   strncmp(testname, namelist[i]->d_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 (file)
index 0000000..642c5ad
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+  efivars_sysfs.[ch] - Manipulates EFI variables as exported in /sys/firmware/efi/vars
+
+  Copyright (C) 2001,2003 Dell Computer Corporation <Matt_Domsch@dell.com>
+
+    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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#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,
+};
index a2f6d49d54e5ed1f8b0bb7205893ebc2f962c6ea..e65a6597653c150337c5ca87a25b1e40a8afff51 100644 (file)
@@ -3,12 +3,13 @@
 .\" <http://shell.ipoline.com/~elmert/comp/docbook2X/> 
 .\" Please send any bug reports, improvements, comments, patches, 
 .\" etc. to Steve Cheng <steve@ggi-project.org>.
-.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
index 81c65b94c566d9e254e5c78094d9144d19d33291..0eec0f7dfa5c127159961c73d170fa60f8a30480 100644 (file)
@@ -17,7 +17,7 @@
   <!ENTITY manfirstname "<firstname>dann</firstname>">
   <!ENTITY mansurname   "<surname>frazier</surname>">
   <!-- Please adjust the date whenever revising the manpage. -->
-  <!ENTITY mandate      "<date>2003-08-11</date>">
+  <!ENTITY mandate      "<date>2004-02-05</date>">
   <!-- SECTION should be 1-8, maybe with subsection. Other parameters are
        allowed: see man(7), man(1). -->
   <!ENTITY mansection   "<manvolnum>8</manvolnum>">
@@ -37,7 +37,7 @@
       &mansurname;
     </author>
     <copyright>
-      <year>2002, 2003</year>
+      <year>2002, 2003, 2004</year>
       <holder>&manusername;</holder>
     </copyright>
     &mandate;
@@ -75,7 +75,8 @@
         <arg>-O</arg>
         <arg>-p <replaceable>PART</replaceable></arg>
         <arg>-q</arg>
-        <arg>-t</arg>
+        <arg>-t <replaceable>seconds</replaceable></arg>
+        <arg>-T</arg>
         <arg>-u</arg>
         <arg>-U <replaceable>XXXX</replaceable></arg>
         <arg>-v</arg>
     <note>
       <para>
         &manpackage; requires that the kernel support access to EFI
-        non-volatile variables (through <filename>/proc/efi/vars</filename>).
+        non-volatile variables (through
+        <filename>/proc/efi/vars</filename> on 2.4 kernels,
+        <filename>/sys/firmware/efi/vars</filename> on 2.6 kernels).
         <command>modprobe efivars</command> should do the trick.
       </para>
     </note>
         </listitem>
       </varlistentry>
       <varlistentry>
-        <term><option>-t</option> | <option>--test</option> <replaceable>filename</replaceable></term>
+        <term><option>--test</option> <replaceable>filename</replaceable></term>
         <listitem>
           <para>Don't write to NVRAM, write to <replaceable>filename</replaceable>.</para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term><option>-t</option> | <option>--timeout</option> <replaceable>seconds</replaceable></term>
+        <listitem>
+          <para>Boot Manager timeout, in <replaceable>seconds</replaceable>.</para>
+        </listitem>
+      </varlistentry>
+      <varlistentry>
+        <term><option>-T</option> | <option>--delete-timeout</option></term>
+        <listitem>
+          <para>Delete Timeout variable.</para>
+        </listitem>
+      </varlistentry>
       <varlistentry>
         <term><option>-u</option> | <option>--unicode</option> | <option>--UCS-2</option> </term>
         <listitem>
   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)   
                 to change the next boot behavior without changing BootOrder.
               </para>
             </listitem>
+            <listitem>
+              <para>
+               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.
+              </para>
+            </listitem>
             <listitem>
               <para>
                 Five boot entries (0000 - 0004), along with the active/inactive