Add a module for retrieving SMBIOS information
PATCH v5 2/2 Add a module for retrieving SMBIOS information
The following are two use cases from Rajat Jain <[email protected]>:
1) We have a board that boots Linux and this board itself can be plugged into one of different chassis types. We need to pass different parameters to the kernel based on the "CHASSIS_TYPE" information that is passed by the bios in the DMI / SMBIOS tables.
2) We may have a USB stick that can go into multiple boards, and the exact kernel to be loaded depends on the machine information (PRODUCT_NAME etc) passed via the DMI.
---
Changes since v4:
To address points suggested by Andrei Borzenkov:
* Described the returned values' formatting in the documentation.
* Set the copyright year to only the current year in new files.
* Stopped passing a string buffer to the formatting functions.
docs/grub.texi | 75 ++++++++ grub-core/Makefile.core.def | 15 ++ grub-core/commands/efi/smbios.c | 59 ++++++ grub-core/commands/i386/pc/smbios.c | 50 +++++ grub-core/commands/smbios.c | 364 +++++++++++++++++++++++++++++++++++ grub-core/efiemu/i386/pc/cfgtables.c | 15 +- include/grub/smbios.h | 68 +++++++ 7 files changed, 635 insertions(+), 11 deletions(-) create mode 100644 grub-core/commands/efi/smbios.c create mode 100644 grub-core/commands/i386/pc/smbios.c create mode 100644 grub-core/commands/smbios.c create mode 100644 include/grub/smbios.h
docs/grub.texi +75 -0
@@ -3850,6 +3850,7 @@ you forget a command, you can run the command @command{help} * sha256sum:: Compute or check SHA256 hash * sha512sum:: Compute or check SHA512 hash * sleep:: Wait for a specified number of seconds +* smbios:: Retrieve SMBIOS information * source:: Read a configuration file in same context * test:: Check file types and compare values * true:: Do nothing, successfully
@@ -4972,6 +4973,80 @@ if timeout was interrupted by @key{ESC}. @end deffn +@node smbios +@subsection smbios + +@deffn Command smbios @ + [@option{--type} @var{type}] @ + [@option{--handle} @var{handle}] @ + [@option{--match} @var{match}] @ + (@option{--get-byte} | @option{--get-word} | @option{--get-dword} | @ + @option{--get-qword} | @option{--get-string} | @option{--get-uuid}) @ + @var{offset} @ + [@option{--set} @var{variable}] +Retrieve SMBIOS information. + +The @command{smbios} command returns the value of a field in an SMBIOS +structure. The following options determine which structure to select. + +@itemize @bullet +@item +Specifying @option{--type} will select structures with a matching +@var{type}. The type can be any integer from 0 to 255. +@item +Specifying @option{--handle} will select structures with a matching +@var{handle}. The handle can be any integer from 0 to 65535. +@item +Specifying @option{--match} will select structure number @var{match} in the +filtered list of structures; e.g. @code{smbios --type 4 --match 2} will select +the second Process Information (Type 4) structure. The list is always ordered +the same as the hardware's SMBIOS table. The match number must be a positive +integer. If unspecified, the first matching structure will be selected. +@end itemize + +The remaining options determine which field in the selected SMBIOS structure to +return. Only one of these options may be specified at a time. + +@itemize @bullet +@item +When given @option{--get-byte}, return the value of the byte +at @var{offset} bytes into the selected SMBIOS structure. +It will be formatted as an unsigned decimal integer. +@item +When given @option{--get-word}, return the value of the word (two bytes) +at @var{offset} bytes into the selected SMBIOS structure. +It will be formatted as an unsigned decimal integer. +@item +When given @option{--get-dword}, return the value of the dword (four bytes) +at @var{offset} bytes into the selected SMBIOS structure. +It will be formatted as an unsigned decimal integer. +@item +When given @option{--get-qword}, return the value of the qword (eight bytes) +at @var{offset} bytes into the selected SMBIOS structure. +It will be formatted as an unsigned decimal integer. +@item +When given @option{--get-string}, return the string with its index found +at @var{offset} bytes into the selected SMBIOS structure. +@item +When given @option{--get-uuid}, return the value of the UUID (sixteen bytes) +at @var{offset} bytes into the selected SMBIOS structure. +It will be formatted as lower-case hyphenated hexadecimal digits, with the +first three fields as little-endian, and the rest printed byte-by-byte. +@end itemize + +The default action is to print the value of the requested field to the console, +but a variable name can be specified with @option{--set} to store the value +instead of printing it. + +For example, this will store and then display the system manufacturer's name. + +@example +smbios --type 1 --get-string 4 --set system_manufacturer +echo $system_manufacturer +@end example +@end deffn + + @node source @subsection source
grub-core/Makefile.core.def +15 -0
@@ -1014,6 +1014,21 @@ module = { }; module = { + name = smbios; + + common = commands/smbios.c; + efi = commands/efi/smbios.c; + i386_pc = commands/i386/pc/smbios.c; + i386_coreboot = commands/i386/pc/smbios.c; + i386_multiboot = commands/i386/pc/smbios.c; + + enable = efi; + enable = i386_pc; + enable = i386_coreboot; + enable = i386_multiboot; +}; + +module = { name = suspend; ieee1275 = commands/ieee1275/suspend.c; enable = i386_ieee1275;
grub-core/commands/efi/smbios.c new file +59 -0
59 lines not on this page · raw message
grub-core/commands/i386/pc/smbios.c new file +50 -0
50 lines not on this page · raw message
grub-core/commands/smbios.c new file +364 -0
364 lines not on this page · raw message
grub-core/efiemu/i386/pc/cfgtables.c +4 -11
@@ -22,11 +22,11 @@#include <grub/misc.h> #include <grub/mm.h> #include <grub/acpi.h> +#include <grub/smbios.h> grub_err_t grub_machine_efiemu_init_tables (void ) { -grub_uint8_t *ptr;void *table;grub_err_t err;grub_efi_guid_t smbios =GRUB_EFI_SMBIOS_TABLE_GUID ;
@@ -57,17 +57,10 @@ grub_machine_efiemu_init_tables (void)if (err)return err; } - -for (ptr = (grub_uint8_t *)0xf0000 ; ptr < (grub_uint8_t *)0x100000 ; - ptr +=16 ) -if (grub_memcmp (ptr,"_SM_" ,4 ) ==0 - &&grub_byte_checksum (ptr, *(ptr +5 )) ==0 ) -break ; - -if (ptr < (grub_uint8_t *)0x100000 ) + table =grub_smbios_get_eps (); +if (table) { -grub_dprintf ("efiemu" ,"Registering SMBIOS\n" ); - err =grub_efiemu_register_configuration_table (smbios,0 ,0 , ptr); + err =grub_efiemu_register_configuration_table (smbios,0 ,0 , table);if (err)return err; }
include/grub/smbios.h new file +68 -0
68 lines not on this page · raw message
Signature · 1 line
2.5.0
Two nitpicks otherwise looks good. Thanks!
20.02.2016 22:12, David Michael пишет:
...
Quoted 54 lines
grub-core/commands/smbios.c new file +48
-0@@ -0,0 +1,364 @@ +/* smbios.c - retrieve smbios information. */ +/* +* GRUB -- GRand Unified Bootloader +* Copyright (C) 2016 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/dl.h> +#include <grub/env.h> +#include <grub/extcmd.h> +#include <grub/i18n.h> +#include <grub/misc.h> +#include <grub/mm.h> +#include <grub/smbios.h> + +GRUB_MOD_LICENSE ("GPLv3+" ); + + +/* Locate the SMBIOS entry point structure depending on the hardware. */ +struct grub_smbios_eps * +grub_smbios_get_eps (void ) +{ +static struct grub_smbios_eps *eps =NULL ; +if (eps !=NULL ) +return eps; + eps =grub_machine_smbios_get_eps (); +return eps; +} + +/* Locate the SMBIOS3 entry point structure depending on the hardware. */ +struct grub_smbios_eps3 * +grub_smbios_get_eps3 (void ) +{ +static struct grub_smbios_eps3 *eps =NULL ; +if (eps !=NULL ) +return eps;
grub-core/commands/smbios.c line 58
Quoted 10 lines
grub-core/commands/smbios.c new file +10
-0+ eps =grub_machine_smbios_get_eps3 (); +return eps; +} + +/* Abstract useful values found in either the SMBIOS3 or SMBIOS EPS. */ +static struct { +grub_addr_t start; +grub_addr_t end; +grub_uint16_t structures; +} table_desc = {0 ,0 ,0 };
Static is supposed to be initialized to zero by default.
...
Quoted 36 lines
grub-core/commands/smbios.c new file +36
-0+static grub_err_t +grub_cmd_smbios (grub_extcmd_context_t ctxt, +int argc __attribute__ ((unused)), +char **argv __attribute__ ((unused))) +{ +struct grub_arg_list *state = ctxt->state; + +grub_int16_t type =-1 ; +grub_int32_t handle =-1 ; +grub_uint16_t match =0 ; +grub_uint8_t offset =0 ; + +const grub_uint8_t *structure; +const char *value; +grub_int32_t option; +grub_int8_t field_type =-1 ; +grub_uint8_t i; + +if (table_desc.start ==0 ) +return grub_error (GRUB_ERR_IO , +N_ ("the SMBIOS entry point structure was not found" )); + +/* Read the given filtering options. */ +if (state[0 ].set) + { + option =grub_strtol (state[0 ].arg,NULL ,0 ); +if (option <0 || option >255 ) +return grub_error (GRUB_ERR_BAD_ARGUMENT , +N_ ("the type must be between 0 and 255" )); + type = (grub_int16_t )option; + } +if (state[1 ].set) + { + option =grub_strtol (state[1 ].arg,NULL ,0 ); +if (option <0 || option >65535 ) + return grub_error (GRUB_ERR_BAD_ARGUMENT,
grub-core/commands/smbios.c line 282
Quoted 10 lines
grub-core/commands/smbios.c new file +10
-0+ N_("the handle must be between 0 and 65535")); + handle = (grub_int32_t )option; + } +if (state[2 ].set) + { + option =grub_strtol (state[2 ].arg,NULL ,0 ); +if (option <=0 ) +return grub_error (GRUB_ERR_BAD_ARGUMENT , +N_ ("the match must be a positive integer" )); + match = (grub_uint16_t )option;
Should we check that option <= 65535?
Quoted 1 line · Andrei Borzenkov
Two nitpicks otherwise looks good. Thanks!
Thanks for reviewing these again. I agree with your suggestions, but do they warrant another updated patch, or can those changes just be squashed onto this commit?
Also, since sending this, Leif Lindholm has proposed a patch for sharing the EFI table lookup code, which is functionality used by this module. Is that something that would be included in 2.02? Should I make a quick update to this to use the new function?
Thanks.
David
03.03.2016 07:13, David Michael пишет:
Quoted 7 lines · Andrei Borzenkov
Quoted 1 line
Two nitpicks otherwise looks good. Thanks!
Thanks for reviewing these again. I agree with your suggestions, but do they warrant another updated patch, or can those changes just be squashed onto this commit?
Could you send final version with all changes applied; it makes it easier to review and apply.
Quoted 5 lines
Also, since sending this, Leif Lindholm has proposed a patch for sharing the EFI table lookup code, which is functionality used by this module. Is that something that would be included in 2.02? Should I make a quick update to this to use the new function?
That's probably post-2.02 change.