Mise à jour des microprogrammes d'appareils à haut débit mobile
Cet article fournit des conseils aux fabricants de modules de haut débit mobile (MB) souhaitant prendre en charge la mise à jour du firmware des appareils via Windows Update (WU). Les appareils doivent être conformes à la spécification du modèle d’interface de haut débit mobile USB NCM (MBIM) V1.0 publiée par le groupe de travail USB-IF Device.
Les informations de cet article s’appliquent à :
- Windows 8/Windows 10/Windows 11
Exigences relatives aux périphériques
Pour prendre en charge les mises à jour du firmware sur le haut débit mobile via Windows Update, les fabricants de modules ou d’appareils doivent respecter les exigences suivantes :
- Pilote basé sur UMDF (User Mode Driver Framework) développé par le fabricant du module ou de l’appareil, empaqueté avec le fichier INF et la charge utile du firmware. Un exemple de fichier INF et des détails sont fournis dans la partie suivante de ce document.
- Le firmware de l’appareil doit implémenter les fonctionnalités suivantes :
- Service de l’appareil pour l’identification du firmware (FID). Pour plus d’informations, veuillez consulter la section Service de l’appareil FID.
- Le firmware doit prendre en charge un service de mise à jour de firmware. Il s’agit d’un service d’appareil spécifique au fabricant qui permet à un pilote UMDF d’appeler et d’exécuter/télécharger la charge utile du firmware et de démarrer le processus de mise à jour du firmware.
Aperçu opérationnel
Le schéma suivant montre la conception à haut niveau et l’interaction entre les trois composants impliqués : appareil MBIM, système d’exploitation Windows 8 et pilote de mise à jour du firmware fourni par l’IHV.
- Lorsque le service WWAN détecte l’arrivée d’un nouvel appareil MB, il vérifie si l’appareil prend en charge le service d’identification du firmware (FID). S’il est présent, il récupère le FID, qui est défini comme étant un GUID. La spécification du service d’appareil pour le firmware que l’IHV doit prendre en charge sur l’appareil est décrite ci-dessous.
- Le service WWAN (système d’exploitation Windows) génère un « soft device-node » en utilisant le FID obtenu ci-dessus comme identifiant matériel de l’appareil. Ceci est appelé « soft dev node » dans le schéma ci-dessus. La création du dev-node va lancer le sous-système PnP (système d’exploitation Windows) pour trouver le pilote le mieux adapté. Dans Windows 8, le système PnP va d’abord tenter d’installer un pilote à partir du magasin local, s’il est disponible, et en parallèle, le système d’exploitation va tenter d’obtenir un pilote mieux adapté à partir de WU. Le pilote NULL inclus sera utilisé par défaut si aucun pilote mieux adapté n’est disponible pour éliminer le problème « Pilote introuvable ».
- Le package WU de l’IHV, basé sur la correspondance FID, est téléchargé sur la machine et installé. Il est attendu que le FID représente un SKU de firmware unique (l’unicité étant définie ici par la combinaison VID/PID/REV de l’appareil et MNO). Le package WU contiendrait un pilote UMDF rédigé par l’IHV ainsi qu’une charge utile de firmware.
- Une fois que l’UMDF de l’IHV est chargé sur le soft dev-node, il est responsable du contrôle du flux de mise à jour du firmware. Il convient de noter que la durée de vie du soft dev-node est liée à la présence physique de l’appareil MBIM. Le pilote UMDF doit effectuer les étapes suivantes pour réaliser les mises à jour du firmware
- Il est acceptable que l’appareil redémarre plusieurs fois au cours du processus de mise à jour du firmware, mais cela entraînerait le déchargement et le rechargement du pilote UMDF.
- L’ensemble du processus de mise à jour du firmware, y compris les redémarrages, ne doit pas durer plus de 60 secondes.
- Après la mise à jour du firmware et le retour de l’appareil en mode MBIM, Windows doit en être informé. Cela se fait en effaçant la propriété DEVPKEY_Device_PostInstallInProgress précédemment définie. L’interface IWDFUnifiedPropertyStore décrit comment définir une propriété sur le dev-node. Une propriété précédemment définie peut être effacée en utilisant DEVPROP_TYPE_EMPTY.
- Lors du rappel UMDF OnPrepareHardware, le pilote UMDF doit vérifier si le firmware sur l’appareil doit être mis à jour. Cela se fait en comparant la version du firmware sur l’appareil à celle reçue via Windows Update. Des conseils supplémentaires sont fournis plus loin dans le document concernant l’emplacement du binaire du firmware. Si une mise à jour du firmware est requise, le pilote UMDF doit :
- Planifier un élément de travail. La mise à jour effective du firmware se fait dans le contexte de l’élément de travail.
- Une fois que l’élément de travail est planifié avec succès, Windows est informé du début de la mise à jour du firmware. Cela se fait en définissant la propriété DEVPKEY_Device_PostInstallInProgress sur le soft dev-node dans le cadre du rappel OnPrepareHardware du pilote UMDF.
- Il est important de ne pas bloquer le rappel OnPrepareHardware pendant que la mise à jour du firmware est en cours. Il est attendu que le rappel OnPrepareHardware soit complété en une seconde ou deux au maximum.
Exemple de fichier INF pour le package WU
Cette section fournit un exemple de fichier INF qui fait partie du package WU. Les points clés à noter dans le fichier INF sont :
- Les binaires du firmware sont indépendants du pilote UMDF.
- Les binaires du firmware se trouvent dans le répertoire driverstore, un chemin déterminé par le système d’exploitation et référencé dans le fichier INF en utilisant DIRID 13. Les binaires ne peuvent pas être des fichiers exécutables contenant des en-têtes PE/COFF.
%13%\<UniqueBinaryName>.bin
- Le fichier INF stocke cet emplacement dans le registre et le pilote UMDF lit la valeur du registre pour découvrir l’emplacement du binaire.
- Le modèle de fichier INF suivant met en évidence les éléments à remplir par l’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"
Service d’identification du firmware (FID Device Service)
L’appareil conforme à MBIM implémentera et signalera le service d’appareil suivant lorsqu’il sera interrogé par CID_MBIM_DEVICE_SERVICES. Les services bien connus existants sont définis dans la spécification NCM MBIM à la section 10.1. Microsoft Corporation étend cela pour définir le service suivant.
Nom du service = Microsoft Firmware ID
UUID = UUID_MSFWID UUID
Valeur = e9f7dea2-feaf-4009-93ce-90a3694103b6
Plus précisément, le CID suivant est défini pour le service d’appareil UUID_MSFWID :
CID = CID_MBIM_MSFWID_FIRMWAREID
Code de commande = 1
Requête = Oui
Définir = Non
Événement = Non
Payload du Set InformationBuffer = N/A
Payload du Query InformationBuffer = N/A
Payload du Completion InformationBuffer = UUID
CID_MBIM_MSFWID_FIRMWAREID
La commande renvoie l’identification du firmware attribuée par le MNO ou l’IHV pour l’appareil. L’UUID est encodé selon les directives de la spécification MBIM.
Requête = InformationBuffer sur MBIM_COMMAND_MSG non utilisé. UUID renvoyé dans InformationBuffer MBIM_COMMAND_DONE.
Définir = Non pris en charge
Événement non sollicité = Non pris en charge
Extraits de code pour le comportement du pilote UMDF
Comme indiqué précédemment, le pilote UMDF doit indiquer à Windows lorsqu’il démarre et termine la mise à jour du firmware. Cette section fournit des extraits de code montrant comment le pilote doit notifier ces événements à Windows.
/**
* 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;
}