System Management BIOS: Difference between revisions
[unchecked revision] | [unchecked revision] |
No edit summary |
changed inane type names to fixed width integer types |
||
Line 40: | Line 40: | ||
<source lang="C"> |
<source lang="C"> |
||
struct SMBIOSEntryPoint { |
struct SMBIOSEntryPoint { |
||
int8_t EntryPointString[4]; //This is _SM_ |
|||
uint8_t Checksum; //This value summed with all the values of the table, should be 0 (overflow) |
|||
uint8_t Length; //Length of the Entry Point Table. Since version 2.1 of SMBIOS, this is 0x1F |
|||
uint8_t MajorVersion; //Major Version of SMBIOS |
|||
uint8_t MinorVersion; //Minor Version of SMBIOS |
|||
uint16_t MaxStructureSize; //Maximum size of a SMBIOS Structure (we will se later) |
|||
uint8_t EntryPointRevision; //... |
|||
int8_t FormattedArea[5]; //... |
|||
int8_t EntryPointString2[5]; //This is _DMI_ |
|||
uint8_t Checksum2; //Checksum for values from EntryPointString2 to the end of table |
|||
uint16_t TableLength; //Length of the Table containing all the structures |
|||
uint8_t TableAddress; //Address of the Table |
|||
uint16_t NumberOfStructures; //Number of structures in the table |
|||
uint8_t BCDRevision; //Unused |
|||
}; |
}; |
||
</source> |
</source> |
||
Line 65: | Line 65: | ||
<source lang="C"> |
<source lang="C"> |
||
struct SMBIOSHeader { |
struct SMBIOSHeader { |
||
uint8_t Type; |
|||
uint8_t Length; |
|||
uint16_t Handle; |
|||
}; |
}; |
||
</source> |
</source> |
Revision as of 01:39, 21 January 2024
System Management BIOS (SMBIOS) is a standard developed by DMTF. The purpose of this standard is to allow the operating system to retrieve information about the PC.
On booting the SMBIOS will put a table somewhere in memory. By parsing this table it is possible to access information about the computer and its capabilities.
Locating the SMBIOS Entry Point Table
The SMBIOS Entry Point Table is located somewhere between the addresses 0xF0000 and 0xFFFFF, and must be on a 16-byte boundary. To find the specific location of the start of the table it is necessary to search that region of memory for the string "_SM_", and then check the structure's checksum (add all bytes and see if the lowest 8 bits of the result are zero).
One example of how this can be done is demonstrated in the below code.
char *mem = (unsigned char *) 0xF0000;
int length, i;
unsigned char checksum;
while ((unsigned int) mem < 0x100000) {
if (mem[0] == '_' && mem[1] == 'S' && mem[2] == 'M' && mem[3] == '_') {
length = mem[5];
checksum = 0;
for(i = 0; i < length; i++) {
checksum += mem[i];
}
if(checksum == 0) break;
}
mem += 16;
}
Now mem contains the address of the Entry Point Table. Some old systems may not have the SMBIOS. So...
if ((unsigned int) mem == 0x100000) {
panic("No SMBIOS found!");
}
Parsing the Entry Point Table
The entry point table has the following structure for SMBIOS 2 and below (the structure is different for SMBIOS 3):
struct SMBIOSEntryPoint {
int8_t EntryPointString[4]; //This is _SM_
uint8_t Checksum; //This value summed with all the values of the table, should be 0 (overflow)
uint8_t Length; //Length of the Entry Point Table. Since version 2.1 of SMBIOS, this is 0x1F
uint8_t MajorVersion; //Major Version of SMBIOS
uint8_t MinorVersion; //Minor Version of SMBIOS
uint16_t MaxStructureSize; //Maximum size of a SMBIOS Structure (we will se later)
uint8_t EntryPointRevision; //...
int8_t FormattedArea[5]; //...
int8_t EntryPointString2[5]; //This is _DMI_
uint8_t Checksum2; //Checksum for values from EntryPointString2 to the end of table
uint16_t TableLength; //Length of the Table containing all the structures
uint8_t TableAddress; //Address of the Table
uint16_t NumberOfStructures; //Number of structures in the table
uint8_t BCDRevision; //Unused
};
TableAddress contains the address of the table that contains all the structures with information about the PC. All of the structures are located from [TableAddress] to [TableAddress + TableLength]. The structures are located directly adjacent to each other in memory, with a new structure beginning as soon as another one ends. Each structure is composed of a header, a structure specific table, and a string table.
The format of the header is as follows.
struct SMBIOSHeader {
uint8_t Type;
uint8_t Length;
uint16_t Handle;
};
Located at TableAddress is a SMBIOS header. The value of Type indicates what element the structure contains information about. (see Header Types section) Length indicates the size of header + data table. The strings are not included in the length.
Immediately after the end of the header is the data. At the end of the data table (Address + Length), the strings section starts. Each string is NULL terminated and is limited to 64 characters. Strings are referenced within tables by using an index into the string table (index 0 means that the string is effectively a NULL pointer and should be ignored). The first string begins immediately after the data, and the second string begins immediately after that, etc. The string section itself is terminated by two consecutive zero bytes. So, your code to find the total length of a table might look like:
size_t smbios_table_len(struct SMBIOSHeader *hd)
{
size_t i;
const char *strtab = (char *)hd + hd->len;
// Scan until we find a double zero byte
for (i = 1; strtab[i - 1] != '\0' || strtab[i] != '\0'; i++)
;
return hd->len + i + 1;
}
The next table begins immediately after the end of the string section. The final table is denoted by a 'type' field of value 127.
As an example, the BIOS Struct (Type 0) might look like this:
db 0 ; Indicates BIOS Structure Type |
db 13h ; Length of information in bytes | HEADER
dw ? ; Reserved for handle |
db 01h ; String 1 is the Vendor Name |
db 02h ; String 2 is the BIOS version |
dw 0E800h ; BIOS Starting Address |
db 03h ; String 3 is the BIOS Build Date | DATA
db 1 ; Size of BIOS ROM is 128K (64K * (1 + 1)) |
dq BIOS_Char ; BIOS Characteristics |
db 0 ; BIOS Characteristics Extension Byte 1 |
db ‘System BIOS Vendor Name’,0 ; |
db ‘4.04’,0 ; | STRINGS
db ‘00/00/0000’,0 ; |
db 0 ; End of structure
Header Types
Code | Description |
---|---|
0 | BIOS Information |
1 | System Information |
2 | Mainboard Information |
3 | Enclosure/Chasis Information |
4 | Processor Information |
7 | Cache Information |
9 | System Slots Information |
16 | Physical Memory Array |
17 | Memory Device Information |
19 | Memory Array Mapped Address |
20 | Memory Device Mapped Address (optional as of SMBIOS 2.5) |
32 | System Boot Information |
More details can be found in the Specification (see External Links)
See Also
Articles
Forum Threads
- http://www.osdev.org/phpBB2/viewtopic.php?t=16687 Info (saved here through lack of info)