为使设备正常运行,设备的固件必须与设备驱动程序兼容。在安装或升级设备驱动程序之前,必须检查固件兼容性。如果没有兼容的固件,设备驱动程序的实现必须确保未安装或升级设备驱动程序。
好的设备驱动程序设计可以将固件封装在一个或多个 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 }