Condividi tramite


Aggiornamento del firmware del dispositivo Mobile Broadband

Questo articolo fornisce indicazioni ai produttori di moduli Mobile Broadband (MB) che intendono supportare i dispositivi di aggiornamento del firmware tramite Windows Update (WU). I dispositivi devono essere conformi alla specifica USB NCM Mobile Broadband Interface Model (MBIM) V1.0 rilasciata dal gruppo di lavoro del dispositivo USB-IF.

Le informazioni contenute in questo articolo si applicano a:

  • Windows 8/Windows 10/Windows 11

Requisiti dei dispositivi

Per supportare gli aggiornamenti del firmware in Mobile Broadband con Windows Update, i produttori di moduli o dispositivi devono rispettare i requisiti seguenti:

  • Driver basato su UMDF (User Mode Driver Framework) sviluppato dal modulo o dal produttore del dispositivo, incluso nel pacchetto con il payload del file e del firmware INF. I dettagli e il file INF di esempio vengono forniti nella parte successiva di questo documento
  • Firmware del dispositivo per implementare le funzionalità seguenti:
    • Firmware ID Device Service (FID). Per altre informazioni, vedere Servizio dispositivi FID.
    • Firmware per supportare un servizio del dispositivo di aggiornamento del firmware. Si tratta di un servizio dispositivo specifico del produttore del dispositivo che consente a un driver UMDF di chiamare ed eseguire/scaricare il payload del firmware e avviare il processo di aggiornamento del firmware.

Panoramica operativa

Il diagramma seguente illustra la progettazione e l'interazione di alto livello tra i tre componenti coinvolti: dispositivo MBIM, sistema operativo Windows 8 e driver di aggiornamento del firmware forniti da IHV.

Diagramma che mostra l'interazione tra il dispositivo MBIM, il sistema operativo Windows 8 e il driver di aggiornamento del firmware forniti da IHV.

  • Quando il servizio WWAN rileva l'arrivo del nuovo dispositivo MB, verifica se il servizio dispositivo supporta l'ID firmware (FID). Se è presente, recupera il FID, definito come GUID. Di seguito è descritta la specifica del servizio di dispositivo firmware necessaria per il supporto del dispositivo.
  • Il servizio WWAN (sistema operativo Windows) genera "soft device-node" usando il FID ottenuto in precedenza come ID hardware del dispositivo. Questa operazione è denominata "Soft Dev Node" nel diagramma precedente. La creazione del nodo di sviluppo avvierà il sottosistema PnP (sistema operativo Windows) per trovare il driver più adatto. In Windows 8, il sistema PnP tenterà prima di tutto di installare un driver dall'archivio locale, se disponibile, e in parallelo il sistema operativo tenterà di recuperare un driver corrispondente migliore da WU. Il driver NULL della posta in arrivo verrà usato come predefinito se il driver di corrispondenza migliore non è disponibile per eliminare il problema "Driver Not Found".
  • Il pacchetto WU IHV, in base alla corrispondenza FID, viene estratto nel computer e installato. È previsto che il FID rappresenti uno SKU univoco del firmware (l'univocità di seguito è definita dalla combinazione di DISPOSITIVO VID/PID/REV e MNO). Il pacchetto WU conterrà un driver UMDF creato da IHV e un payload del firmware.
  • Una volta che la funzione IHV UMDF viene caricata nel nodo di sviluppo software, è responsabile del controllo del flusso di aggiornamento del firmware. Si noti che il tempo di vita del nodo di sviluppo flessibile è legato alla presenza fisica del dispositivo MBIM. Il driver UMDF eseguirà i passaggi seguenti per eseguire gli aggiornamenti del firmware
    • È accettabile che il dispositivo si riavvii più volte durante il processo di aggiornamento del firmware, ma causerebbe il caricamento/ricarica del driver UMDF
    • L'intero processo di aggiornamento del firmware, inclusi i riavvii, non dovrebbe essere eseguito più di 60 secondi.
    • Dopo aver completato l'aggiornamento del firmware e aver ripristinato la modalità MBIM del dispositivo, Windows deve ricevere una notifica. Questa operazione viene eseguita cancellando la proprietà DEVPKEY_Device_PostInstallInProgress impostata in precedenza. L'interfaccia IWDFUnifiedPropertyStore descrive come impostare una proprietà in dev-node. È possibile cancellare una proprietà impostata in precedenza usando DEVPROP_TYPE_EMPTY.
    • Durante il callback UMDF onPrepareHardware, il driver UMDF verifica se il firmware nel dispositivo deve essere aggiornato. Questa operazione viene eseguita confrontando la versione del firmware nel dispositivo con quella che è stata inserita tramite Windows Update. Altre indicazioni sono disponibili più avanti nel documento relativo alla posizione di posizionamento del file binario del firmware. Se è necessario aggiornare il firmware, il driver UMDF deve:
      • Pianificare un elemento di lavoro. L'aggiornamento effettivo del firmware avviene nel contesto dell'elemento di lavoro.
      • Dopo che l'elemento di lavoro è stato pianificato correttamente, notificare a Windows l'avvio dell'aggiornamento del firmware. Questa operazione viene eseguita impostando la proprietà DEVPKEY_Device_PostInstallInProgress nel nodo di sviluppo software nel contesto del callback di OnPrepareHardware UMDF.
      • È importante non bloccare il callback OnPrepareHardware mentre è in corso l'aggiornamento del firmware. È previsto che il callback OnPrepareHardware venga completato entro un secondo o due al massimo.

File INF di esempio per il pacchetto WU

Questa sezione fornisce un esempio di INF che fa parte del pacchetto WU. I punti chiave da notare nel file INF sono:

  • I file binari del firmware sono indipendenti dal driver UMDF.
  • I file binari del firmware si trovano nella directory driverstore, un percorso determinato dal sistema operativo e a cui viene fatto riferimento in INF usando DIRID 13. I file binari non possono essere file eseguibili contenenti intestazioni PE/COFF.
  • %13%\<UniqueBinaryName>.bin
  • Il file INF archivia questo percorso nel Registro di sistema e il driver UMDF legge il valore del Registro di sistema per individuare il percorso binario.
  • Il modello INF di esempio seguente evidenzia gli elementi che devono essere compilati dall'IHV.
[Version]
Signature       = "$WINDOWS NT$"
Class           = Firmware
ClassGuid       = {f2e7dd72-6468-4e36-b6f1-6488f42c1b52}
Provider        = %Provider%
DriverVer       = 06/21/2006,6.2.8303.0
CatalogFile     = MBFWDriver.cat
PnpLockdown     = 1

[Manufacturer]
%Mfg%           = Firmware,NTx86

[Firmware.NTx86]
%DeviceDesc%    = Firmware_Install,MBFW\{FirmwareID}    ; From Device Service
;%DeviceDesc%    = Firmware_Install,MBFW\{2B13DD42-649C-3442-9E08-D85B26D7825C}

[Firmware_Install.NT]
CopyFiles       = FirmwareDriver_CopyFiles,FirmwareImage_CopyFiles

[Firmware_Install.NT.HW]
AddReg          = Device_AddReg

[Device_AddReg]
HKR,,FirmwareBinary,,"%13%\MBIHVFirmware-XYZ-1.0.bin"

[Firmware_Install.NT.Services]
AddService      = WUDFRd,0x000001fa,WUDFRD_ServiceInstall

[WUDFRD_ServiceInstall]
DisplayName     = %WudfRdDisplayName%
ServiceType     = 1
StartType       = 3
ErrorControl    = 1
ServiceBinary   = %12%\WUDFRd.sys
LoadOrderGroup  = Base

[Firmware_Install.NT.CoInstallers]
CopyFiles       = WudfCoInstaller_CopyFiles

[WudfCoInstaller_AddReg]
HKR,,CoInstallers32,0x00010000,"WUDFCoinstaller.dll"

[Firmware_Install.NT.Wdf]
UmdfService      = MBIHVFirmwareDriver,MBIHVFirmwareDriver_Install
UmdfServiceOrder = MBIHVFirmwareDriver

[MBIHVFirmwareDriver_Install]
UmdfLibraryVersion  = 1.11
ServiceBinary       = %12%\UMDF\MBFWDriver.dll
DriverCLSID         = {<DriverClassGuid>} ; From UMDF driver

[FirmwareImage_CopyFiles]
MBIHVFirmware-XYZ-1.0.bin   ; Firmware Image

[FirmwareDriver_CopyFiles]
MBFWDriver.dll          ; UMDF driver for SoftDevNode

[DestinationDirs]
FirmwareImage_CopyFiles  = 13      ; Driver Store
FirmwareDriver_CopyFiles = 12,UMDF ;%SystemRoot%\System32\drivers\UMDF

[SourceDisksFiles]
MBIHVFirmware-XYZ-1.0.bin = 1

[SourceDisksNames]
1 = %DiskName%

; ================== Generic ==================================

[Strings]
Provider        = "MBIHV"
Mfg             = "MBIHV"
DeviceDesc      = "MBIHV Mobile Broadband Firmware Device"
DiskName        = "Firmware Driver Installation Media"

Servizio dispositivo di identificazione del firmware (servizio dispositivi FID)

Il dispositivo conforme a MBIM implementerà e indicherà il servizio dispositivo seguente quando viene eseguita una query da CID_MBIM_DEVICE_SERVICES. I servizi noti esistenti sono definiti nella specifica MBIM NCM nella sezione 10.1. Microsoft Corporation estende questa funzionalità per definire il servizio seguente.

Nome servizio = ID firmware Microsoft

UUID = UUID_MSFWID UUID

Value = e9f7dea2-feaf-4009-93ce-90a3694103b6

In particolare, il CID seguente viene definito per UUID_MSFWID servizio del dispositivo:

CID = CID_MBIM_MSFWID_FIRMWAREID

Codice comando = 1

Query =

Set = No

Evento = No

Impostare il payload InformationBuffer = N/A

Payload Query InformationBuffer = N/A

Payload InformationBuffer di completamento = UUID

CID_MBIM_MSFWID_FIRMWAREID

Il comando restituisce l'ID firmware assegnato da MNO o IHV per il dispositivo. L'UUID viene codificato in base alle linee guida nella specifica MBIM.

Query = InformationBuffer in MBIM_COMMAND_MSG non usato. UUID restituito in InformationBuffer MBIM_COMMAND_DONE.

Set = Non supportato

Evento non richiesto = Non supportato

Frammenti di codice per il comportamento del driver UMDF

Come indicato in precedenza, il driver UMDF deve indicare a Windows all'avvio e completa l'aggiornamento del firmware. In questa sezione vengono forniti frammenti di codice che mostrano come il driver deve notificare a Windows questi eventi.

/**
 * This is the IPnpCallbackHardware*:OnPrepareHardware handler 
 * in the UMDF driver. This is called every time the firmware 
 * update is device is started. Since this handler should be 
 * blocked from returning actual the firmware update process 
 * should be done in a workitem 
 */
HRESULT
CMyDevice::OnPrepareHardware(IWDFDevice* pDevice)
{
    HRESULT hr = S_OK;
    BOOL bFirmwareUpdateInProgress = FALSE;
    BOOL bFirmwareUpdateNeeded = FALSE;
    BOOL bFirmwareUpdateIsDone = FALSE;

    //
    // The snippets below demonstrates the steps for firmware 
    // update against a MB device that loads the updated firmware 
    // on device boot. So the firmware update driver needs to
    // send the new firmware down to the device and then tell 
    // the device to initiate a stop/start. Once the device has
    // reappeared, it would have automatically loaded the 
    // new firmware
    // 


    //
    // First, determine if firmware update is in progress. This 
    // can be based on some registry key that is saved when
    // firmware update is started
    //

    // Assuming this status is returned in bFirmwareUpdateInProgress
    if (bFirmwareUpdateInProgress)
    {
        //
        // If firmware update is in progress, check if its done. For
        // this it may be necessary to access the MB device. Note that 
        // if the MB device (& hence the Firmware update device) needs
        // multiple stop/starts to do the firmware update. In that case
        // it will be marked as done at the end of the process
        //

        // Assuming this status is returned in bFirmwareUpdateIsDone
        if (bFirmwareUpdateIsDone)
        {
            //
            // Signal the completion of the firmware update
            // process.
            //
            SignalFirmwareUpdateComplete(pDevice);
        }
        else
        {
            //
            // Take appropriate steps to get notified when
            // firmware update is done. Call SignalFirmwareUpdateComplete
            // when that notification is received
            //
        }
    }
    else
    {
        //
        // Determine if firmware update is needed. This can be 
        // based on checking state in the registry of the last
        // firmware version set on the device to the firmware
        // version associated with this driver
        //
        
        // Assuming this status is returned in bFirmwareUpdateNeeded
        if (bFirmwareUpdateNeeded)
        {
            // 
            // Create and queue a workitem to perform the firmware
            // update process. IWDFWorkItem can be used for this
            //
            
            // Assuming the creation/enquing status
            // is returned in hr
            
            if (SUCCEEDED(hr))
            {
                //
                // Work item queued. It will do the firmware update
                // Tell the OS that firmware update is in progress
                //
                SignalFirmwareUpdateInProgress(pDevice);
            }
        }
    }

    //
    // If we have a failure, we clear the firmware update
    // in progress state
    //
    if (FAILED(hr))
    {
        SignalFirmwareUpdateComplete(pDevice);
    }
    return S_OK;
}

/**
 * This function tells the OS that firmware update is in progress.
 * It should be called from the firmware update UMDF driver's 
 * IPnpCallbackHardware*:OnPrepareHardware handler after it has
 * successfully queued a workitem to perform the firmware update
 */
HRESULT
CMyDevice::SignalFirmwareUpdateInProgress(
    __in IWDFDevice* pDevice
    )
{
    HRESULT hr = S_OK;    
    IWDFUnifiedPropertyStoreFactory* spPropertyStoreFactory = NULL;
    IWDFUnifiedPropertyStore* spPropStore = NULL;
    WDF_PROPERTY_STORE_ROOT wdfPropRoot = { sizeof(WDF_PROPERTY_STORE_ROOT), WdfPropertyStoreRootClassHardwareKey };
    DEVPROP_BOOLEAN boolValue = DEVPROP_TRUE;
    
    do
    {
       
        hr = pDevice->QueryInterface(IID_PPV_ARGS(&spPropertyStoreFactory));
        if (FAILED(hr))
        {
            Trace(TRACE_LEVEL_ERROR, "Failed to query for property store factory. Error = 0x%x", hr);
            break;

        }
        
        hr = spPropertyStoreFactory->RetrieveUnifiedDevicePropertyStore(
            &wdfPropRoot,
            &spPropStore
            );
        if (FAILED(hr))
        {
            Trace(TRACE_LEVEL_ERROR, "Failed to query for device property store. Error = 0x%x", hr);
            break;
        }

        // Set the OS flag
        hr = spPropStore->SetPropertyData(
            reinterpret_cast<const DEVPROPKEY*>(&DEVPKEY_Device_PostInstallInProgress),
            0, // this property is language neutral
            0,
            DEVPROP_TYPE_BOOLEAN,
            sizeof(DEVPROP_BOOLEAN),
            &boolValue
            );
        if (FAILED(hr))
        {
            Trace(TRACE_LEVEL_ERROR, "Failed to set device property for PostInstallInProgress. Error = 0x%x", hr);
            break;
        }

        //
        // Save some state so that we know we are in the process
        // of firmware update
        //
    } while (FALSE);        

    if (spPropStore)
    {
        spPropStore->Release();
    }

    if (spPropertyStoreFactory)
    {
        spPropertyStoreFactory->Release();
    }

    return hr;
}


/**
 * This function tells the OS that firmware update is done
 * It should be called only after the full firmware update process
 * (including any MB device stop/start) has finished
 */
HRESULT
CMyDevice::SignalFirmwareUpdateComplete(
    __in IWDFDevice* pDevice
    )
{
    HRESULT hr = S_OK;    
    IWDFUnifiedPropertyStoreFactory* spPropertyStoreFactory = NULL;
    IWDFUnifiedPropertyStore* spPropStore = NULL;
    WDF_PROPERTY_STORE_ROOT wdfPropRoot = { sizeof(WDF_PROPERTY_STORE_ROOT), WdfPropertyStoreRootClassHardwareKey };
    
    do
    {
        hr = pDevice->QueryInterface(IID_PPV_ARGS(&spPropertyStoreFactory));
        if (FAILED(hr))
        {
            Trace(TRACE_LEVEL_ERROR, "Failed to query for property store factory. Error = 0x%x", hr);
            break;

        }

        hr = spPropertyStoreFactory->RetrieveUnifiedDevicePropertyStore(
            &wdfPropRoot,
            &spPropStore
            );
        if (FAILED(hr))
        {
            Trace(TRACE_LEVEL_ERROR, "Failed to query for device property store. Error = 0x%x", hr);
            break;
        }

        hr = spPropStore->SetPropertyData(
            reinterpret_cast<const DEVPROPKEY*>(&DEVPKEY_Device_PostInstallInProgress),
            0, // this property is language neutral
            0,
            DEVPROP_TYPE_BOOLEAN,
            0,
            NULL
            );
        if (FAILED(hr))
        {
            Trace(TRACE_LEVEL_ERROR, "Failed to clear device property for PostInstallInProgress. Error = 0x%x", hr);
            break;
        }

        //
        // Save some state so that we can do quick check on 
        // whether firmware update is needed or not
        //

    } while (FALSE);        

    if (spPropStore)
    {
        spPropStore->Release();
    }

    if (spPropertyStoreFactory)
    {
        spPropertyStoreFactory->Release();
    }

    return hr;
}