To err is human, and to blame it on a computer is even more so.
—Robert Orben
This chapter describes some usages of the UEFI Shell for diagnostics. Although the PC ecosystem has rich examples of robust platform software and hardware components, occasionally things go awry. In those cases, the machine state needs to be diagnosed or assessed. To that end, the act of performing diagnostics is a key action for platform deployment and lifecycle maintenance.
Today, disk operating systems such as MS-DOS or PC DOS are still used by many platform manufacturers as a diagnostics environment because of the single-tasking nature of DOS, the large library of extant DOS utilities, the fact that DOS layers directly on PC/AT BIOS as its I/O stack, and the lack of memory protection in DOS. For the purposes of a modern OS, these features of DOS are difficult to use, but for diagnosing a machine or determining the root-cause of a failure, this close mapping to the hardware and controlled environment is appreciated. But DOS has various downsides for diagnostics on contemporary platform hardware, including a limited memory map, 16-bit operating mode, and difficulties in getting modern software ported to this environment.
This description of DOS is not intended to be pejorative. In fact, the existence of DOS coupled with PC/AT BIOS has been a contributing factor to the PC ecosystem success and customer-visible value of Moore’s Law and the associated platform.
The Beyond DOS aspect of the book title, though, describes how scenarios like DOS diagnostics now have an opportunity to move to UEFI. Int21h in DOS maps the appropriate UEFI service, for example. In addition, the full machine addressability of UEFI, richness of the UEFI and shell specifications, the ability to in fact access UEFI Platform Initialization (PI) interfaces if they’re available, and open software infrastructure like the EFI Development Kits at www.tianocore.org, are key enabling elements of this migration.
In the context of a UEFI system, many actors can contribute to the diagnostics role. We mentioned above the available, generic infrastructure that the UEFI Shell and main specifications at www.uefi.org provide, but within those specifications are some purpose-designed abstractions for diagnostics. One example would be the EFI_DRIVER_DIAGNOSTICS_PROTOCOL. The intent of a protocol such as this, like other UEFI interfaces, is to bind the API to the entity that can produce the domain-specific behavior. What we mean by that is the UEFI driver that provides a capability, such as block abstraction from a disk driver, can also provide a diagnostics interface in cases of a failure of the underlying media or hardware.
So why is a device-specific abstraction valuable? This gives a platform manufacturer the opportunity to write a generic “disk diagnostics” capability into a shell application that can access the plurality of disk block instances via each driver’s EFI_DRIVER_DIAGNOSTICS_PROTOCOL. Without this per-driver API publication, such a “disk diagnostics” utility would have to contain vendor-specific information and code flows from the sundry disk controller vendors in the industry.
Regarding the usage of the EFI_DRIVER_DIAGNOSTICS protocol mentioned above, the UEFI Shell specification codifies usage via the drvdiag
command.
Another type of diagnostic can be one that accesses the platform resources, such as the PCI bus. To that end, the UEFI Shell has the mm
and pci
commands to allow peeking (reading) and poking (writing) memory-mapped I/O, direct I/O, PCI configuration access, and PCI memory-mapped device access, respectively. Like other UEFI Shell commands, these hardware accesses can be done in an interactive mode or via scripting, with console and/or log file recording being possible, too.
The final discussion of a class of diagnostics entails the use of the UEFI Shell to ascertain information from the System Management BIOS tables. This example provides working reference code and is intended to tie together some of the earlier discussions around available software frameworks, infrastructure in both the UEFI main specification and UEFI Shell specifications, and a use-case that provides customervisible value from using this technology.
The System Management BIOS (SMBIOS) tables are a set of data structures in memory that are referenced by the GUID in the UEFI system table, namely:
The location of the SMBIOS table relative to other UEFI objects is shown in Figure 8.1. The important point to note is the location of the industry standard hand-off tables in the lower left-hand side of the diagram.
This chapter describes a scenario wherein the system is not operational and different asset information is discovered using capabilities of the UEFI Shell. Before we describe the tool to ascertain the SMBIOS data, a little background information will be provided.
The purpose of this utility (named SMBIOSVIEW) is to get data from SMBIOS tables and translate the packed information into a human-readable form. As such, the SMBIOS structure table organization is the first issue to design with respect to this diagnostic UEFI Shell-based utility.
According to the SMBIOS specification, there are two access methods defined for the SMBIOS structures. The first method, defined in v2.0 of the SMBIOS specification, provides the SMBIOS structures through a plug-and-play function interface. A tablebased method, defined in v2.1 of the SMBIOS specification, provides the SMBIOS structures as a packed list of data referenced by a table entry point.
A BIOS compliant with v2.1 of the SMBIOS specification can provide one or both methods. A BIOS compliant with v2.2 and later of this specification must provide the table-based method and can optionally provide the plug-and-play function interface. EFI uses the second method.
In EFI, the SMBIOS core driver provides table-based information. SMBIOSVIEW gets the information and translates it to users. The table includes a table header, a structure table, and other data objects. See the SMBIOS specification at http://www.dmtf.org/standards/smbios/ for more information on the table entries.
The information of SMBIOS is organized as the SMBIOS structure, and the SMBIOS structure is accessed by the means of the SMBIOS structure table Entry Point Structure (EPS).
The table organization graph shown in Figure 8.2 is used to make the SMBIOS table more understandable. The SMBIOS table includes a table header and a structure table.
The table header contains the general information of the table and the necessary information to access the structure table.
The structure table contains a series of structures. The type of the last structure is 127, which indicates End-of-table.
The EPS (Entry Point Structure) has information about the structure table:
Table-Address points to the structure table starting address.
Table-Length is the length of the structure table.
Num-of-Structures is the number of structures in the structure table.
The first structure begins with the Table-Address. The second structure begins with the next byte at the end of the first one, and so on.
The type of the last structure is 127. The last structure is also indicated by the Num-of-Structures in the EPS.
The structures between the first and last are of random type. In other words, the structures are packed neither increasing type nor decreasing type, but random.
Each Structure has a common header. The header contains three fields:
Type – type of this structure, following data is organized according to this type
Length – number of bytes of format part, it does not include the text string length
Handle – uniquely identifies the structure in the structure table
The format part follows the header. Text strings follow the format part. In text string parts, two bytes of 0x00 identify the end of structure. It also identifies the end of the structure table header.
Each SMBIOS structure has a formatted section and an optional unformatted section. The formatted section of each structure begins with a 4-byte header. Remaining data in the formatted section is determined by the structure type, as is the overall length of the formatted section.
As the industry evolves, the structures defined in this specification will evolve. To ensure that the evolution occurs in a nondestructive fashion, the following guidelines must be followed:
Text strings associated with a given SMBIOS structure are returned in the dmiStrucBuffer, appended directly after the formatted portion of the structure. This method of returning string information eliminates the need for application software to deal with pointers embedded in the SMBIOS structure. Each string is terminated with a null (0x00) UINT8 and the set of strings is terminated with an additional null (0x00) UINT8. When the formatted portion of a SMBIOS structure references a string, it does so by specifying a nonzero string number within the structure’s string-set. For example, if a string field contains 0x02, it references the second string following the formatted portion of the SMBIOS structure. If a string field references no string, a null (0) is placed in that string field. If the formatted portion of the structure contains string-reference fields and all the string fields are set to 0 (no string references), the formatted section of the structure is followed by two null (0x00) BYTES. See 3.4.1 Structure Evolution and Usage Guidelines on page 90 of the SMBIOS specification for a string-containing example.
Note: Each text string is limited to 64 significant characters due to system MIF limitations.
Beginning with SMBIOS v2.3, compliant SMBIOS implementations include a base set of required structures and data within those structures. These structures include the BIOS information, system information, processor information, and several tables describing the system information.
SMBIOSVIEW allows users to display SMBIOS structure information with different detail options. Its main goal is to provide a user-friendly interface of the SMBIOS structure. SMBIOSVIEW allows users to:
Display structure table statistics information
Display structure information with different levels:
–SHOW_NONE – Don’t interpret just dump the structure
–SHOW_OUTLINE – Only display header information
–SHOW_NORMAL – Display header information and element value
–SHOW_DETAIL – Display header and element detail information (default)
Display all structures’ information of certain Type
–Display structures’ information of certain Handle
–Display structures’ information one by one or all at once
–Controls (such as change display option) in application
–Use a simple help guide (>SmbiosView -?).
This section describes the details of the user interface (UI) to the SMBIOSVIEW shell command.
1. SmbiosView [-t type] | [-h handle] | [-s] | [-a]
2. Internal commands:
Note: Internal commands provide optional controls to users and they are gotten from users’ input after a prompt ‘$’. Users can also press Enter to skip internal commands. The following command allows for describing the various portions of the SMBIOS table. The various actions that can occur with respect to the table manipulation are encoded via various input command line parameters. These options include a description of the options via ‘-?.’
>SmbiosView |
-? |
- Show help page |
>SmbiosView |
- Show structures as default | |
>SmbiosView |
-s |
- Show statistics information, as shown in Figure 8.3 |
>SmbiosView |
-t 8 |
- Show all structures of type=8, as shown in Figure 8.4 |
>SmbiosView |
-h 25 |
- Show structure of handle=0x25 |
>SmbiosView |
-a > 1. log |
- Show all structures and output to file of 1.log |
fs0:>SmbiosView -s
The SMBIOS utility components architecture is illustrated in Figure 8.5 (the arrows indicate the calling of another module), and can be described as follows:
Init Module. Gets the SMBIOS table and initializes the environment of the SMBIOS utility.
Dispatch Module. Gets and transacts the shell command parameters and user input.
User Input. The user inputs the internal commands such as changing a display option or quitting the program.
SMBIOS Info Access Module. Provides a set of APIs to access the SMBIOS table or structures.
Element Info Interpret Module. Translates packed data to understandable text according to specification.
Data Unpack Module. Translates packed data to understandable information.
Display Module. Displays information as required options.
There are four key data structures in the editor implementation, as listed in Table 8.1.
Table 8.1: Key Data Structures
Data Structure Name | Header File Name |
SMBIOS_STRUCTURE_TABLE | LibSmbios.h |
SMBIOS_HEADER | LibSmbios.h |
SMBIOS_STRUCTURE_POINTER | LibSmbios.h |
STRUCTURE_STATISTICS | SmbiosView.h |
The structure of the SMBIOS_STRUCTURE_TABLE is as follows:
This structure is defined as the EPS (Entry Point Structure) of the SMBIOS table. Access to SMBIOS table information is by this structure. For detailed information, refer to Chapter 3.
Note: Because SMBIOS table uses a byte alignment data structure, this structure is also using #pragma pack(1) to configure structure data alignment of one byte. This is necessary because a general C declaration would be naturally aligned, but the present utility needs to map the data structure to an external specification.
Table 8.2 lists the members of the SMBIOS_STRUCTURE_TABLE data structure.
These tables are going to be manipulated by the utility. The description below explains the specific entries and their meanings.
Table 8.2: Members of SMBIOS_STRUCTURE_TABLE
Member | Description |
AnchorString |
_SM_, specified as (5F 53 4D 5F) |
EntryPointStructureChecksum EntryPointLength |
Checksum of the Entry Point Structure (EPS) Length of the Entry Point Structure |
MajorVersion |
Identifies the major version of SMBIOS specification implemented in the table structures. |
MinorVersion |
Identifies the minor version of SMBIOS specification implemented in the table structures. |
MaxStructureSize |
Size of the largest SMBIOS structure, in bytes, encompasses the structure’s formatted area and text strings. |
EntryPointRevision |
Identifies the EPS revision implemented in this structure and identifies the formatting of offsets 0Bh to 0Fh. |
FormattedArea[5] |
The value present in the Entry Point Revision field defines the interpretation to be placed upon these 5 bytes. |
IntermediateAnchorString[5] |
_DMI_, specified as five ASCII characters (5F 44 4D 49 5F). |
IntermediateChecksum TableLength |
Checksum of Intermediate Entry Point Structure (IEPS) Total length of SMBIOS Structure Table, pointed to by the Structure Table Address, in bytes. |
TableAddress |
Total length of SMBIOS Structure Table, pointed to by the Structure Table Address, in bytes. |
NumberOfSmbiosStructures |
Total number of structures present in the SMBIOS Structure Table. |
SmbiosBcdRevision |
Indicates compliance with a revision of SMBIOS specification. |
The structure of SMBIOS_HEADER is as follows:
Table 8.3 lists the members of SMBIOS_HEADER.
Table 8.3: Members of SMBIOS_HEADER
Member | Description |
Type |
Structure type |
Length |
Format part length of structure |
Handle |
Unique identifier of structure in structure table |
The structure of SMBIOS_STRUCTURE_POINTER is as follows:
This structure is defined as a union. Each field in the union is a method of organizing the data of the structure, such as structure header, a structure type, or simply a byte raw array.
Table 8.4 lists the members of SMBIOS_STRUCTURE_POINTER.
Table 8.4: Members of SMBIOS_STRUCTURE_POINTER
Members | Description |
Hdr |
Points to Structure header, common part of all structure types |
Type(n) |
Interprets the structure as certain structure type format |
Raw |
Interprets the Structure as simple bytes packet |
The structure of STRUCTURE_STATISTICS is as follows:
Table 8.5 lists the members of STRUCTURE_STATISTICS.
Table 8.5: Members of STRUCTURE_STATISTICS
Member | Description |
Index |
Index in the SMBIOS structure table |
Type |
Structure type identified in the structure header |
Handle |
Structure handle unique to identified structure in the table |
Addr |
Structure offset from structure table start address |
Len |
Structure whole length including format part and text format |
To bring the SMBIOS overview and design discussions together, the SMBIOS view command is described next. Various portions of this UEFI Shell utility are presented and decomposed in order to show how the theory of SMBIOS can be married to a particular UEFI practice.
These lines contain the include files for the application.
These lines contain the module globals for the application.
These lines contain an initialization routine for the application, including logic to discover the SMBIOS data in memory.
These lines contain code to discover the entry point structure.
These lines contain code to discover the head structure.
These lines contain code to set various fields of the SMBIOS information.
These lines contain code to discover specific SMBIOS structures.
This chapter has described how the UEFI Shell can be used for an important action in the platform development and deployment space, namely diagnostics. The discussion has included a discussion of using the UEFI Shell for SMBIOS. Specifically, an extant industry standard, such as SMBIOS, can be comprehended by UEFI and then assessed/managed via a UEFI Shell application. Again, this is just one instance where the UEFI Shell, with its rich application library, can assist in real-world platform deployment and management activities.
3.145.188.172