You are on page 1of 4

Display UEFI Firmware Version, Vendor, Revision and Build Date

Display UEFI Firmware Version, Vendor, Revision and Build Date


Finnbarr P. Murphy
(fpm@fpmurphy.com) So you are at your UEFI shell prompt and wish to display your UEFI firmware version and related information such as the vendor, revision and build date. How do you get this information? The ver command does not provide this information. You can parse the output of smbiobview -t 0 and get the information. Or you can simply compile and run the following UEFI utility:

// // Copyright (c) 2012 Finnbarr P. Murphy. All rights reserved. // // Display Firmware Information Vendor, Version and Release Date via SMBIOS // // Any source code included from EDK2 is copyright Intel Corporation // // Licence: BSD License // #include <efi.h> // Install GNU_EFI package to get these headers #define GUID EFI_GUID // hack for SmBios.h #include "SmBios.h" // from EDK2. GNU_EFI libsmbios.h is defective #include <efilib.h> #define BUFSIZE 64 #define INVALID_HANDLE (UINT16) (-1) #define DMI_INVALID_HANDLE 0x83 #define DMI_SUCCESS 0x00 STATIC SMBIOS_TABLE_ENTRY_POINT *mSmbiosTable = NULL; STATIC SMBIOS_STRUCTURE_POINTER m_SmbiosStruct; STATIC SMBIOS_STRUCTURE_POINTER *mSmbiosStruct = &amp;m_SmbiosStruct; int Strlen(const char *str) { const char *s; for (s = str; *s; ++s) ; return (s - str); } // // Modified from EDK2 source code. Copyright Intel Corporation. // CHAR8* LibGetSmbiosString ( SMBIOS_STRUCTURE_POINTER *Smbios, UINT16 StringNumber) { UINT16 Index; CHAR8 *String; ASSERT (Smbios != NULL); String = (CHAR8 *) (Smbios->Raw + Smbios->Hdr->Length); for (Index = 1; Index <= StringNumber; Index++) { if (StringNumber == Index) { return String; } for (; *String != 0; String++) ;

Fo r

10-16-2012

pe rs o

Copyright 2004-2012 Finnbarr P. Murphy. All rights reserved.

nn a

lu

se

on
1/4

ly

Display UEFI Firmware Version, Vendor, Revision and Build Date String++; if (*String == 0) { Smbios->Raw = (UINT8 *)++String; return NULL; } } return NULL; } // // Modified from EDK2 source code. Copyright Intel Corporation. // EFI_STATUS LibGetSmbiosStructure ( UINT16 *Handle, UINT8 **Buffer, UINT16 *Length) { SMBIOS_STRUCTURE_POINTER Smbios; SMBIOS_STRUCTURE_POINTER SmbiosEnd; UINT8 *Raw; if (*Handle == INVALID_HANDLE) { *Handle = mSmbiosStruct->Hdr->Handle; return DMI_INVALID_HANDLE; } if ((Buffer == NULL) || (Length == NULL)) { Print(L"Invalid handle\n"); return DMI_INVALID_HANDLE; } *Length = 0; Smbios.Hdr = mSmbiosStruct->Hdr; SmbiosEnd.Raw = Smbios.Raw + mSmbiosTable->TableLength; while (Smbios.Raw < SmbiosEnd.Raw) { if (Smbios.Hdr->Handle == *Handle) { Raw = Smbios.Raw; LibGetSmbiosString (&amp;Smbios, (UINT16) (-1)); *Length = (UINT16) (Smbios.Raw - Raw); *Buffer = Raw; if (Smbios.Raw < SmbiosEnd.Raw) { *Handle = Smbios.Hdr->Handle; } else { *Handle = INVALID_HANDLE; } return DMI_SUCCESS; } LibGetSmbiosString (&amp;Smbios, (UINT16) (-1)); } *Handle = INVALID_HANDLE; return DMI_INVALID_HANDLE; } CHAR16 * ASCII_to_UCS2(const char *s, int len) { CHAR16 *ret = NULL; int i; ret = AllocateZeroPool(len*2 + 2); if (!ret) return NULL; for (i = 0; i < len; i++) ret[i] = s[i]; return ret; } EFI_STATUS efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) { EFI_STATUS status = EFI_SUCCESS; EFI_GUID Guid = EFI_GLOBAL_VARIABLE; CHAR16 *ptr; CHAR8 *str; UINT16 Handle;

Fo r

10-16-2012

pe rs o

Copyright 2004-2012 Finnbarr P. Murphy. All rights reserved.

nn a

lu

se
2/4

on

ly

Display UEFI Firmware Version, Vendor, Revision and Build Date UINTN Index; UINT16 Length; UINT8 *Buffer; SMBIOS_STRUCTURE_POINTER SmbiosStruct; SMBIOS_TABLE_TYPE0 *SmbiosType0; InitializeLib(image, systab); status = LibGetSystemConfigurationTable(&amp;SMBIOSTableGuid, (VOID**)&amp;mSmbiosTabl e); if ((status != EFI_SUCCESS || mSmbiosTable == NULL) || (CompareMem (mSmbiosTable->AnchorString, "_SM_", 4) != 0)) { Print(L"ERROR: SMBIOS table not found.\n"); return status; } mSmbiosStruct->Raw = (UINT8 *) (UINTN) (mSmbiosTable->TableAddress); Print(L"SMBIOS Ver: %x.%x Rev: %x Table Count: %d\n", mSmbiosTable->MajorVersion, mSmbiosTable->MinorVersion, mSmbiosTable->EntryPointRevision, mSmbiosTable->NumberOfSmbiosStructures); Handle = INVALID_HANDLE; LibGetSmbiosStructure (&amp;Handle, NULL, NULL); // loop though the tables looking for a type 0 table. for (Index = 0; Index < mSmbiosTable->NumberOfSmbiosStructures; Index++) { if (Handle == INVALID_HANDLE) { break; } if (LibGetSmbiosStructure (&amp;Handle, &amp;Buffer, &amp;Length) != DMI_SUCCESS) break; } SmbiosStruct.Raw = Buffer; if (SmbiosStruct.Hdr->Type == 0) { // Type 0 /* vendor string */ str = LibGetSmbiosString(&amp;SmbiosStruct, ptr = ASCII_to_UCS2(str, Strlen(str)); Print(L"Firmware Vendor: %s\n", ptr); FreePool(ptr); /* version string */ str = LibGetSmbiosString(&amp;SmbiosStruct, ptr = ASCII_to_UCS2(str, Strlen(str)); Print(L"Firmware Version: %s\n", ptr); FreePool(ptr); /* release string */ str = LibGetSmbiosString(&amp;SmbiosStruct, ptr = ASCII_to_UCS2(str, Strlen(str)); Print(L"Firmware Release: %s\n", ptr); FreePool(ptr); break; }

nn a

pe rs o

Fo r

} return status;

The information we want is not located in the firmware NVRAM as EFI variables. Instead we have to retrieve the information via SMBIOS. The utility works by locating the base address of the SMBIOS table from the firmware EFI Configuration Table. The utility then walks down the SMBIOS table structures looking at the type of each structure. When it find a Type 0 (BIOS Information Indicator designated in the SMBIOS standard to contain BIOS-related information) structure, it prints out the first three strings in that structure. The meaning of these three strings is specified by the SMBIOS standard, i.e. the first string is the BIOS Vendors Name, the second string is freeform and contains the BIOS Version and the third string in the structure is the BIOS Release Date in either mm/dd/yy or mm/dd/yyyy format. See Section 7.1 of the SMBIOS specification for more information.

10-16-2012

Copyright 2004-2012 Finnbarr P. Murphy. All rights reserved.

lu
1); 2); 3);

se
- BIOS

on

ly

3/4

Display UEFI Firmware Version, Vendor, Revision and Build Date

[Updated 10/06/2012] Here is what is outputted by the utility on a Lenovo T430 laptop:

SMBIOS Ver: 2.7 Rev: 0 Table Count: 71 Firmware Vendor: LENOVO Firmware Version: G1ET69WW (2.05) Firmware Release: 09/12/2012

See the DMTF SMBIOS and the UEFI specifications for more information.

Fo r

10-16-2012

pe rs o

Copyright 2004-2012 Finnbarr P. Murphy. All rights reserved.

nn a

lu

se

By the way, do not confuse the EFI Configuration Table with the EFI System Table which is probably the most important data structure in EFI. The EFI Configuration Table is a member of the EFI System Table. A pointer to the EFI System Table is passed into each driver and application as part of its entry-point handoff. From the EFI System Table, an image can gain access to system configuration information (including the address of the SMBIOS table), EFI Boot Services, EFI Runtime Services, various Protocol services and more. You can get the Firmware Vendor and Firmware Revision information from the EFI System Table but not the Firmware Date.

on

ly

To compile this code, you must have the gnu_efi package installed. It is available on Fedora and most other Linux distributions. Due to problems in the definition of an SMBIOS structure in /usr/include/efi/libsmbios.h, comment out the libsmbios.h include directive in /usr/include/efi/efilib.h and use the EDK2 SmBios.h header instead. I have placed a copy of this header along with a Makefile and the above source code on GitHub under the showfirmware subdirectory.

4/4

You might also like