BIOS Implementation and In-Band Interaction
更新时间: 2025/11/27
在Gitcode上查看源码

BIOS Implementation and In-Band Interaction

BIOS Implementation and In-Band Interaction

The code of the BIOS module can be found at BIOS.

Introduction

The BIOS normally guides the OS boot process in the system. This document introduces the BIOS component of the BMC, which primarily interacts with the in-band BIOS. Its main functions include:

  1. Upgrading firmware for the in-band BIOS.
  2. Setting and obtaining in-band BIOS properties from the BMC.

Overall Design and Implementation

Before studying this module, please read this post: BIOS. It provides a detailed and efficient introduction to BIOS functions.

This exceptional post rewards rereading. Because the component relies on a complex implementation, you are advised to address specific problems only as they arise. Mastering the entire system demands substantial effort. This introduction provides supplementary context on the code to guide your learning.

Upgrading Firmware for In-Band BIOS

Upgrade modes include equipment upgrade, non-equipment upgrade, and silent upgrade. Equipment upgrades force a power cycle, while non-equipment upgrades do not.

The upgrade logic is relatively complex. The BIOS post already provides a detailed introduction. Based on the code process, the common BIOS upgrade process is as follows:

After the upgrade task starts, the system calls the upgrade_hpm function. This function invokes the prepare, process, and finish functions of HpmUpgrade. During the process phase, the system calls build_upgrade_mode to determine the upgrade mode (hot, cold, forced, or online forced). It then constructs the upgrade information. The resulting upgrade_info is passed to Package:process, which then calls Package:_start(). Under normal circumstances, app.log prints Start the bios upgrade prepare phase. Once the upgrade completes, it prints hpm upgrade: bios package upgrade successfully, signaling the end of the process.

The core part of the process involves executing Package:_start(), which generates the context object for the executor chain. The scenarios:execute(ctx) function determines the steps to run based on the scenario (hot or cold upgrade) and generates the execution chain. The complete execution chain includes the following steps: copying the package, caching the package, forcing power-off (only for equipment mode), power-on locking, loading the driver, parsing the package (by header), selecting the upgrade area, selecting the upgrade channel (SPI or IPMB), and starting the upgrade. Different scenarios trigger different execution chains.

During a normal upgrade, the execution chain prints upgrade chain: parse_bin (executor) start. When the chain ends, it prints upgrade chain: spi_driver (executor) end.

Upgrading the BIOS involves flashing the upgrade package content into the flash memory. Silent upgrades use the IPMB channel, while non-silent upgrades use the SPI link at the bottom layer.

See the IpmbChannel:upgrade function for the IPMB channel implementation. The IPMB bus sends commands and data without directly operating the flash. The receiving IMU handles the upgrade. For details, see write_firmware_data in ComponentUpgrade.

In other cases, SpiFlashChannel:upgrade is invoked to upgrade the BIOS. The SPI channel directly operates the hardware. It switches the SPI bus, loads the driver, and reads/writes the flash memory. It calls spi_flash.spi_flash_copy.

Modifying BIOS Properties on the BMC Page

For example, the command for setting the boot option corresponds to the https://$ip/UI/Rest/System/BootOptions Redfish interface. The interface content is as follows:

json
{"PreferredBootMedium":{"Target":"BiosSetup","EffectivePeriod":"Continuous"}}

The request reaches the interface mapping module rack_mount. It calls the SetStartOption and SetStartOptionFlag functions of the BIOS module via an RPC interface to implement specific functions. These two functions can also be called through IPMI or RPC commands. Log auto clear valid is false, set start option will be printed. After successfully setting the properties, the system waits for the BIOS to start and read them.

Exporting BIOS Firmware

export_bios_firmware creates a coroutine to perform the actual export operation. It calls process_download_action to start downloading the BIOS firmware. Specifically, it calls download_one_bios to switch the SPI channel and uses the download_bios function to read the BIOS firmware from SPI flash and write it to the export path. The core action is write_data_from_flash, which reads BIOS firmware data from SPI flash and writes it to a local file. This is the critical step in the export process. After the export finishes, export bios firmware finished is displayed. The exported file is bios.tar.gz.

BIOS and BMC Interaction Process

BIOS boot process description:

  1. First, the system performs a power-on operation. After receiving the power-on signal, the BIOS module performs a security verification on the BIOS flash. If the verification fails, the system does not allow the boot. If the verification succeeds, it allows the boot.
  2. During the BIOS boot process, the system exchanges information with the BIOS module of the BMC through IPMI commands. This mainly involves two parts, as shown below:
  • A. The BIOS reports information such as the version number, effective boot options and configurations, and BDF to the BMC. See BIOS Information Reporting.
  • B. The BIOS obtains information such as pending boot options and configurations, and silkscreens for memory and PCIe from the BMC. See BIOS Configuration Reading . In the figure, green text represents scenario A, and blue text represents scenario B.

BIOS Information Reporting

No. (Sequence Diagram No.)CommandFunction
1ReportAlarmReports alarms such as PowerLink, VRAbnormal, and MemoryLink.
2SetBiosVersionReports the BIOS version number.
5WriteSmbiosDataReports SMBIOS files containing static information such as memory and CPU manufacturers.
7WriteFileToBmcReports effective BIOS configurations (FileSelector is 0x1a) and effective certificate files (FileSelector is 0x2c).
9SetBootOptionReports effective BIOS boot options and the number of times they take effect.
10UpdatePostStatusReports the BIOS boot completion flag.

BIOS Configuration Reading

No. (Sequence Diagram No.)CommandFunction
3ReadFileFromBmcObtains silkscreens (FileSelector is 0x2a) and BIOS configuration information (FileSelector is 0x1b) from the BMC.
4UpdateBiosPasswordObtains the set BIOS password from the BMC and reports the setting result back to the BMC.
6ReadFileFromBmcObtains the BIOS configuration application flow file (FileSelector is 0x2b) from the BMC.
8GetBootOptionObtains boot options and the number of times they take effect from the BMC.

BIOS Configuration Application Details

  1. Users import BIOS configurations through Redfish or the web interface. The system writes the configurations to the setting.json file.

  2. During the boot process, the in-band BIOS reads the setting.json file from the BMC using the ReadFileFromBmc command to obtain the BIOS configurations.

  3. The in-band BIOS applies the configurations. It then reports the currentValue.json file, which contains the effective BIOS configurations, to the BMC using the WriteFileToBmc command.

ReadFile Example

The BIOS and BMC communicate primarily through IPMI commands. For example, the ReadFileFromBmc command is the function used by the BIOS to obtain files from the BMC. During each boot, the system calls bios_read_file_from_bmc, which prints logs like Disk PCIeAddrInfo:, get_mem_silk_array, and get_pcie_silk_config when obtaining information from the BMC. The bios_read_file_from_bmc code serves as the entry point. The BIOS passes different parameters to call bios_read_prepare for preparation, bios_read_data to assemble data, and bios_read_finish to calculate the checksum. Depending on the FileSelector command word, bios_read_prepare determines whether to return silkconfig.json, new_secureboot.json, psu_info.json, or other content to the BIOS.

Data transferred during interaction may exceed the IPMI command length. The specific process is as follows:

text
BIOS Side                           BMC Side
  |                                   |
  |--- BIOS_READ_PREPARE ------------>|
  |      (Request preparation)        |
  |                                   |-- Read the entire file into memory.
  |                                   |-- Return the total file size.
  |<--- Response (file length) -------|
  |                                   |
  |--- BIOS_READ_DATA --------------->|
  |      (Offset=0, length=248)       |
  |                                   |-- Intercept bytes 0-247
  |                                   |-- Calculate the checksum.
  |<--- Response (block 1 + flag) ----|
  |                                   |
  |--- BIOS_READ_DATA --------------->|
  |      (Offset=248, length=248)     |
  |                                   |-- Intercept bytes 248-495.
  |                                   |-- Calculate the checksum.
  |<--- Response (block 2 + flag) ----|
  |                                   |
  | ... (Loop until reading finishes) |
  |                                   |
  |--- BIOS_READ_DATA --------------->|
  |      (Last block)                 |
  |                                   |-- Intercept the final part.
  |                                   |-- Set the flag to NO_MORE_DATA.
  |<--- Response (last block + flag) -|
  |                                   |
  |--- BIOS_READ_FINISH ------------->|
  |      (Request end)                |
  |                                   |-- Verify the overall checksum.
  |<--- Response (Finish) ------------|
  |                                   |

This mechanism achieves reliable large file transmission within IPMI message size limits through block-based transmission, state machine control, and offset management.

WriteFile Example

BIOS sends SMBIOS data to the BMC using the WriteSmbiosData IPMI command. The write_smbios process is similar to the ReadFile process described above, involving three stages to write data to a local file. When called during boot, it prints update_smbios_file: write file len. Upon completion, it prints smbios_write_finish.

During boot, the system also calls bios_write_bdf_to_bmc, which prints write_one_frame: pcie bdf reported and bios_write_bdf_to_bmc: sht bios_write_bdf_data_to_bmc max_frame. Similar interfaces like WritePcieCardBdfToBmc write the BDF information of PCIe cards into the BMC.

Other BIOS and BMC Communication Cases

The BMC and BIOS communicate through many other interfaces. You can find details in BiosIpmiCmdsMsg and mds\ipmi.json. Their implementations are complex and are not covered here.

Reference