为使设备正常运行,设备的固件必须与设备驱动程序兼容。在安装或升级设备驱动程序之前,必须检查固件兼容性。如果没有兼容的固件,设备驱动程序的实现必须确保未安装或升级设备驱动程序。
好的设备驱动程序设计可以将固件封装在一个或多个 ELF(可执行链接格式)模块中,并可使用 attach() 函数管理固件版本。要将固件封装在一个 ELF 模块中,请使用 elfwrap(1) 命令。固件 ELF 模块通过作为 misc 模块的模块链接存根链接起来。固件模块位于 /kernel/misc 目录中。
以下流程图显示了在设备驱动程序的 attach() 函数中管理固件版本的方法。
图 1-1 在 attach() 函数中管理固件版本
有关更多信息,请参见 attach (9E) 、 ddi_modopen (9F) 、 ddi_modsym (9F) 和 ddi_modclose (9F) 手册页。
用于检查固件版本的 attach() 函数的通用伪代码如下所示:
static int xxxx_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
.....
ddi_modhandle_t modfn;
int errno;
uint32_t *fwvp;
.....
long fw_version;
.....
/* Check if firmware update is disabled.
* If firmware update is disabled, return.
* The setting is stored in a config file.
*/
if(dip->firmware_disable_update){
return (0);
}
/* Get the current firmware version. */
fw_version = xxxx_get_firmware_version(dip,...);
/* Check if the firmware version is correct and if force update is disabled. */
if(fw_version == REQUIRED_FIRMWARE_VERSION){
if(dip->firmware_force_update == 0){
return (0);
}
/* Even though the firmware version matches, update is forced. */
}
/* Open the firmware file by using ddi_modopen. */
modfn = ddi_modopen(FIRMWARE_FILENAME, KRTLD_MODE_FIRST, &errno);
if (errno){
/* handle error */
}
/* locate the firmware */
fwvp = ddi_modsym(modfn, FIRMWARE_VERSION_NAME, &errno);
if (errno){
/* handle error */
(void) ddi_modclose(modfn);
}
/* Check if the firmware version in the module is correct. */
if (*fwvp != REQUIRED_FIRMWARE_VERSION){
if(dip->firmware_force_update == 0){
/* close the firmware module file */
(void) ddi_modclose(modfn);
return (0);
}
/* Even tough the firmware version in the module does not match,
* update is forced.
*/
}
/* Update the firmware. */
xxx_update_firmware(dip,....);
/* Close the FIRMWARE file */
(void) ddi_modclose(modfn);
.....
// resume attach
}