编写适用于 Oracle® Solaris 11.2 的设备驱动程序

退出打印视图

更新时间: 2014 年 9 月
 
 

固件兼容性

为使设备正常运行,设备的固件必须与设备驱动程序兼容。在安装或升级设备驱动程序之前,必须检查固件兼容性。如果没有兼容的固件,设备驱动程序的实现必须确保未安装或升级设备驱动程序。


注 -  如果使用 IPS 打包驱动程序,可以在将驱动程序包下载到系统前通知用户任何固件非兼容性。有关详细信息,请参见Driver Packaging

好的设备驱动程序设计可以将固件封装在一个或多个 ELF(可执行链接格式)模块中,并可使用 attach() 函数管理固件版本。要将固件封装在一个 ELF 模块中,请使用 elfwrap(1) 命令。固件 ELF 模块通过作为 misc 模块的模块链接存根链接起来。固件模块位于 /kernel/misc 目录中。

以下流程图显示了在设备驱动程序的 attach() 函数中管理固件版本的方法。

图 1-1  attach() 函数中管理固件版本

image:在 attach() 函数中管理固件版本

有关更多信息,请参见 attach (9E) ddi_modopen (9F) ddi_modsym (9F) ddi_modclose (9F) 手册页。


注 -  某些设备(如 mwluathhwarc)不包含非易失性内存。在这些设备中,设备驱动程序装入固件时不会检查任何条件。

用于检查固件版本的 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
}