Display UEFI Firmware Version Vendor Revision and Build Date

Embed Size (px)

Citation preview

  • 7/31/2019 Display UEFI Firmware Version Vendor Revision and Build Date

    1/4

    Display UEFI Firmware Version, Vendor, Revision and Build Date

    Display UEFI Firmware Version,

    Vendor, Revision and Build DateFinnbarr P. Murphy

    ([email protected])

    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 ofsmbiobview -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 // 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

    #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 = &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

  • 7/31/2019 Display UEFI Firmware Version Vendor Revision and Build Date

    2/4

    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 (&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 (&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;

    10-16-2012 Copyright 2004-2012 Finnbarr P. Murphy. All rights reserved. 2/4

  • 7/31/2019 Display UEFI Firmware Version Vendor Revision and Build Date

    3/4

    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(&SMBIOSTableGuid, (VOID**)&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 (&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 (&Handle, &Buffer, &Length) != DMI_SUCCESS)

    {

    break;

    }

    SmbiosStruct.Raw = Buffer;

    if (SmbiosStruct.Hdr->Type == 0) { // Type 0 - BIOS

    /* vendor string */

    str = LibGetSmbiosString(&SmbiosStruct, 1);

    ptr = ASCII_to_UCS2(str, Strlen(str));

    Print(L"Firmware Vendor: %s\n", ptr);

    FreePool(ptr);/* version string */

    str = LibGetSmbiosString(&SmbiosStruct, 2);

    ptr = ASCII_to_UCS2(str, Strlen(str));

    Print(L"Firmware Version: %s\n", ptr);

    FreePool(ptr);

    /* release string */

    str = LibGetSmbiosString(&SmbiosStruct, 3);

    ptr = ASCII_to_UCS2(str, Strlen(str));

    Print(L"Firmware Release: %s\n", ptr);

    FreePool(ptr);

    break;

    }

    }

    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 Versionand the third string in the structure is the BIOS Release Date in either mm/dd/yyor 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. 3/4

    http://en.wikipedia.org/wiki/System_Management_BIOShttp://en.wikipedia.org/wiki/System_Management_BIOS
  • 7/31/2019 Display UEFI Firmware Version Vendor Revision and Build Date

    4/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

    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 EDK2SmBios.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.

    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 systemconfiguration 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.

    See the DMTFSMBIOS and the UEFI specifications for more information.

    10-16-2012 Copyright 2004-2012 Finnbarr P. Murphy. All rights reserved. 4/4

    http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=EDK2https://github.com/fpmurphy/UEFI-Utilitieshttp://en.wikipedia.org/wiki/Distributed_Management_Task_Forcehttp://dmtf.org/standards/smbioshttp://www.uefi.org/http://www.uefi.org/http://dmtf.org/standards/smbioshttp://en.wikipedia.org/wiki/Distributed_Management_Task_Forcehttps://github.com/fpmurphy/UEFI-Utilitieshttp://sourceforge.net/apps/mediawiki/tianocore/index.php?title=EDK2