grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Add support for entering the firmware setup screen.


From: Vladimir 'φ-coder/phcoder' Serbinenko
Subject: Re: [PATCH] Add support for entering the firmware setup screen.
Date: Sat, 08 Sep 2012 12:09:51 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.6esrpre) Gecko/20120817 Icedove/10.0.6

Patch committed. Please next time use indent when creating new files and
follow ChangeLog style.
On 24.05.2012 16:31, Peter Jones wrote:

> 
> diff --git a/ChangeLog b/ChangeLog
> index ce52576..29ebcbd 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,11 @@
> +2012-05-24  Peter Jones <address@hidden>
> +
> +     * grub-core/Makefile.core.def: add efifwsetup module
> +     * grub-core/commands/efi/efifwsetup.c: add code for fwsetup command
> +     * grub-core/kern/efi/efi.c (grub_efi_set_variable): New function
> +     * include/grub/efi/api.h: add define for OsIndications variable
> +     * include/grub/efi/efi.h: export grub_efi_set_variable
> +
>  2012-04-18  Vladimir Serbinenko  <address@hidden>
>  
>       * configure.ac: Bump to beta5.
> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> index 000cf0d..d0c06d5 100644
> --- a/grub-core/Makefile.core.def
> +++ b/grub-core/Makefile.core.def
> @@ -576,6 +576,12 @@ module = {
>  };
>  
>  module = {
> +  name = efifwsetup;
> +  efi = commands/efi/efifwsetup.c;
> +  enable = efi;
> +};
> +
> +module = {
>    name = blocklist;
>    common = commands/blocklist.c;
>  };
> diff --git a/grub-core/commands/efi/efifwsetup.c 
> b/grub-core/commands/efi/efifwsetup.c
> new file mode 100644
> index 0000000..b1cf414
> --- /dev/null
> +++ b/grub-core/commands/efi/efifwsetup.c
> @@ -0,0 +1,88 @@
> +/* fwsetup.c - Reboot into firmware setup menu. */
> +/*
> + *  GRUB  --  GRand Unified Bootloader
> + *  Copyright (C) 2012  Free Software Foundation, Inc.
> + *
> + *  GRUB is free software: you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation, either version 3 of the License, or
> + *  (at your option) any later version.
> + *
> + *  GRUB is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + *  You should have received a copy of the GNU General Public License
> + *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +#include <grub/types.h>
> +#include <grub/mm.h>
> +#include <grub/misc.h>
> +#include <grub/efi/api.h>
> +#include <grub/efi/efi.h>
> +#include <grub/command.h>
> +
> +GRUB_MOD_LICENSE ("GPLv3+");
> +
> +static grub_err_t
> +grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)),
> +               int argc __attribute__ ((unused)),
> +               char **args __attribute__ ((unused)))
> +{
> +  grub_efi_uint64_t *old_os_indications;
> +  grub_efi_uint64_t os_indications = GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
> +  grub_err_t status;
> +  grub_size_t oi_size;
> +  grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
> +
> +  old_os_indications = grub_efi_get_variable("OsIndications", &global,
> +                                          &oi_size);
> +
> +  if (old_os_indications != NULL && oi_size == 8)
> +    os_indications |= *old_os_indications;
> +
> +  status = grub_efi_set_variable("OsIndications", &global, &os_indications,
> +                              sizeof (os_indications));
> +  if (status != GRUB_ERR_NONE)
> +    return status;
> +
> +  grub_reboot();
> +
> +  return GRUB_ERR_BUG;
> +}
> +
> +static grub_command_t cmd = NULL;
> +
> +static grub_efi_boolean_t
> +efifwsetup_is_supported(void)
> +{
> +  grub_efi_uint64_t *os_indications_supported = NULL;
> +  grub_size_t oi_size = 0;
> +  grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
> +
> +  os_indications_supported = grub_efi_get_variable("OsIndicationsSupported",
> +                                               &global, &oi_size);
> +
> +  if (!os_indications_supported)
> +    return 0;
> +
> +  if (*os_indications_supported & GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI)
> +    return 1;
> +
> +  return 0;
> +}
> +
> +GRUB_MOD_INIT(efifwsetup)
> +{
> +  if (efifwsetup_is_supported())
> +    cmd = grub_register_command("fwsetup", grub_cmd_fwsetup, "",
> +                             "Reboot into firmware setup menu.");
> +
> +}
> +
> +GRUB_MOD_FINI(efifwsetup)
> +{
> +  if (cmd)
> +    grub_unregister_command (cmd);
> +}
> diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
> index 6f12c76..7a418a6 100644
> --- a/grub-core/kern/efi/efi.c
> +++ b/grub-core/kern/efi/efi.c
> @@ -230,6 +230,36 @@ grub_efi_get_variable (const char *var, const 
> grub_efi_guid_t *guid,
>    return NULL;
>  }
>  
> +grub_err_t
> +grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
> +                   void *data, grub_size_t datasize)
> +{
> +  grub_efi_status_t status;
> +  grub_efi_runtime_services_t *r;
> +  grub_efi_char16_t *var16;
> +  grub_size_t len, len16;
> +
> +  len = grub_strlen (var);
> +  len16 = len * GRUB_MAX_UTF16_PER_UTF8;
> +  var16 = grub_malloc ((len16 + 1) * sizeof (var16[0]));
> +  if (!var16)
> +    return grub_errno;
> +  len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
> +  var16[len16] = 0;
> +
> +  r = grub_efi_system_table->runtime_services;
> +
> +  grub_efi_uint32_t attributes = GRUB_EFI_VARIABLE_NON_VOLATILE |
> +                              GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
> +                              GRUB_EFI_VARIABLE_RUNTIME_ACCESS;
> +
> +  status = efi_call_5 (r->set_variable, var16, guid, attributes, 
> datasize,data);
> +  if (status == GRUB_EFI_SUCCESS)
> +    return GRUB_ERR_NONE;
> +
> +  return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var);
> +}
> +
>  grub_uint64_t
>  grub_rtc_get_time_ms (void)
>  {
> diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
> index 26127de..a47a4e3 100644
> --- a/include/grub/efi/api.h
> +++ b/include/grub/efi/api.h
> @@ -58,6 +58,8 @@
>  #define GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER             0x00000010
>  #define GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE          0x00000020
>  
> +#define GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI        0x0000000000000001ULL
> +
>  #define GRUB_EFI_VARIABLE_NON_VOLATILE               0x0000000000000001
>  #define GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
>  #define GRUB_EFI_VARIABLE_RUNTIME_ACCESS     0x0000000000000004
> diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
> index e67d92b..489cf9e 100644
> --- a/include/grub/efi/efi.h
> +++ b/include/grub/efi/efi.h
> @@ -64,6 +64,11 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) 
> (grub_efi_uintn_t memo
>  void *EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
>                                          const grub_efi_guid_t *guid,
>                                          grub_size_t *datasize_out);
> +grub_err_t
> +EXPORT_FUNC (grub_efi_set_variable) (const char *var,
> +                                  const grub_efi_guid_t *guid,
> +                                  void *data,
> +                                  grub_size_t datasize);
>  int
>  EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t 
> *dp1,
>                                            const grub_efi_device_path_t *dp2);



-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]