Devlink Flash¶
devlink-flash
API 允许更新设备固件。它取代了旧的 ethtool-flash
机制,并且不需要在内核中获取任何网络锁来执行固件更新。使用示例
$ devlink dev flash pci/0000:05:00.0 file flash-boot.bin
请注意,文件名是相对于固件加载路径(通常是 /lib/firmware/
)的路径。驱动程序可能会发送状态更新,以告知用户空间有关更新操作的进度。
覆盖掩码¶
devlink-flash
命令允许可选地指定一个掩码,指示设备在更新时应如何处理闪存组件的子部分。此掩码指示允许覆盖的节集合。
名称 |
描述 |
|
指示设备应使用提供的镜像中找到的设置覆盖正在更新的组件中的设置。 |
|
指示设备应使用提供的镜像中找到的标识符覆盖正在更新的组件中的标识符。这包括 MAC 地址、序列号和类似的设备标识符。 |
可以组合并一起请求多个覆盖位。如果未提供任何位,则预期设备仅更新正在更新的组件中的固件二进制文件。设置和标识符应在更新过程中保留。设备可能不支持每种组合,并且此类设备的驱动程序必须拒绝任何无法忠实实现的组合。
固件加载¶
需要固件才能运行的设备通常将其存储在板上的非易失性存储器中,例如闪存。一些设备仅在板上存储基本固件,并且驱动程序在探测期间从磁盘加载其余部分。devlink-info
允许用户查询固件信息(已加载的组件和版本)。
在其他情况下,设备既可以将镜像存储在板上,也可以从磁盘加载,还可以自动从磁盘刷新新镜像。fw_load_policy
devlink 参数可用于控制此行为 (Documentation/networking/devlink/devlink-params.rst)。
磁盘上的固件文件通常存储在 /lib/firmware/
中。
固件版本管理¶
驱动程序应实现 devlink-flash
和 devlink-info
功能,它们共同允许实现与供应商无关的自动化固件更新工具。
devlink-info
公开 driver
名称和三个版本组(fixed
、running
、stored
)。
driver
属性和 fixed
组标识特定的设备设计,例如,用于查找适用的固件更新。这就是为什么 serial_number
不是 fixed
版本的一部分(即使它是固定的) - fixed
版本应标识设计,而不是单个设备。
running
和 stored
固件版本标识设备上运行的固件以及重启或设备复位后将激活的固件。
固件更新代理应该能够遵循此简单算法来更新固件内容,而与设备供应商无关
# Get unique HW design identifier
$hw_id = devlink-dev-info['fixed']
# Find out which FW flash we want to use for this NIC
$want_flash_vers = some-db-backed.lookup($hw_id, 'flash')
# Update flash if necessary
if $want_flash_vers != devlink-dev-info['stored']:
$file = some-db-backed.download($hw_id, 'flash')
devlink-dev-flash($file)
# Find out the expected overall firmware versions
$want_fw_vers = some-db-backed.lookup($hw_id, 'all')
# Update on-disk file if necessary
if $want_fw_vers != devlink-dev-info['running']:
$file = some-db-backed.download($hw_id, 'disk')
write($file, '/lib/firmware/')
# Try device reset, if available
if $want_fw_vers != devlink-dev-info['running']:
devlink-reset()
# Reboot, if reset wasn't enough
if $want_fw_vers != devlink-dev-info['running']:
reboot()
请注意,此伪代码中对 devlink-dev-info
的每次引用都应从内核获取最新的信息。
为了方便识别固件文件,一些供应商将 bundle_id
信息添加到固件版本中。此元版本涵盖多个每个组件的版本,例如,可以在固件文件名中使用(所有组件版本可能会很长。)