Mapping degli indirizzi Bus-Relative agli indirizzi virtuali
Alcuni processori implementano spazi di indirizzi di memoria e I/O separati, mentre altri processori non lo fanno. A causa di queste differenze nelle piattaforme hardware, i driver di meccanismo usano per accedere alle risorse dei dispositivi residenti in memoria o I/O differiscono dalla piattaforma alla piattaforma.
Un driver richiede risorse di I/O e memoria del dispositivo in risposta alle IRP_MN_QUERY_RESOURCE_REQUIREMENTS IRP del manager PnP. A seconda dell'architettura hardware, l'HAL può assegnare risorse di I/O nello spazio di I/O o nello spazio di memoria e può assegnare risorse di memoria nello spazio di I/O o nello spazio di memoria.
Se l'HAL usa lo spazio di memoria relativo al bus per accedere alle risorse del dispositivo ,ad esempio i registri dei dispositivi, un driver deve eseguire il mapping dello spazio di I/O in memoria virtuale in modo che possa accedere a queste risorse. Il driver può determinare se le risorse sono I/O o residenti in memoria controllando le risorse tradotte passate al driver dal gestore PnP all'avvio del dispositivo. Se hal usa lo spazio di I/O, non è necessario alcun mapping.
In particolare, quando un driver riceve una richiesta di IRP_MN_START_DEVICE, deve esaminare le strutture in IrpSp-Parameters.StartDevice.AllocateResources> e IrpSp-Parameters.StartDevice.AllocateResourcesTranslated>, che descrivono rispettivamente le risorse non elaborate (relative al bus) e tradotte assegnate dal manager PnP al dispositivo. I driver devono salvare una copia di ogni elenco di risorse nell'estensione del dispositivo come aiuto per il debug.
Gli elenchi di risorse sono associati CM_RESOURCE_LIST strutture, in cui ogni elemento dell'elenco non elaborato corrisponde allo stesso elemento dell'elenco tradotto. Ad esempio, se AllocateResources.List[0] descrive un intervallo di porte I/O non elaborato, AllocateResourcesTranslated.List[0] descrive lo stesso intervallo dopo la conversione. Ogni risorsa tradotta include un indirizzo fisico e il tipo della risorsa.
Se a un driver viene assegnata una risorsa di memoria tradotta (CmResourceTypeMemory), deve chiamare MmMapIoSpace per eseguire il mapping dell'indirizzo fisico in un indirizzo virtuale tramite il quale può accedere ai registri del dispositivo. Affinché un driver funzioni in modo indipendente dalla piattaforma, deve controllare ogni risorsa restituita, tradotta ed eseguirne il mapping, se necessario.
Un driver in modalità kernel deve eseguire i passaggi seguenti, in risposta a una richiesta di IRP_MN_START_DEVICE, per garantire l'accesso a tutte le risorse del dispositivo
Copiare IrpSp-Parameters.StartDevice.AllocateResources> nell'estensione del dispositivo.
Copiare IrpSp-Parameters.StartDevice.AllocateResourcesTranslated> nell'estensione del dispositivo.
In un ciclo esaminare ogni elemento descrittore in AllocateResourcesTranslated. Se il tipo di risorsa descrittore è CmResourceTypeMemory, chiamare MmMapIoSpace, passando l'indirizzo fisico e la lunghezza della risorsa tradotta.
Quando il driver riceve una richiesta di IRP_MN_STOP_DEVICE o IRP_MN_REMOVE_DEVICE dal gestore PnP, deve rilasciare i mapping chiamando MmUnmapIoSpace in un ciclo simile. Il driver deve anche chiamare MmUnmapIoSpace se deve non riuscire la richiesta di IRP_MN_START_DEVICE .
Il tipo di risorsa non elaborato indica quale routine di accesso HAL deve chiamare un driver (READ_REGISTER_XXX, WRITE_REGISTER_XXX, READ_PORT_XXX, WRITE_PORT_XXX). La maggior parte dei driver non deve controllare l'elenco di risorse non elaborate per determinare quale di queste routine usare, perché il driver stesso ha richiesto la risorsa o il writer di driver conosce il tipo richiesto in base alla natura dell'hardware del dispositivo.
Per una risorsa nello spazio di I/O (CmResourceTypePort, CmResourceTypeInterrupt, CmResourceTypeDma), il driver deve usare i 32 bit dell'indirizzo fisico restituito per accedere alla risorsa del dispositivo, ad esempio tramite le routine di lettura e scrittura di HAL READ_REGISTER_XXX, WRITE_REGISTER_XXX, READ_PORT_XXX, WRITE_PORT_XXX .