將Bus-Relative位址對應至虛擬位址
有些處理器會實作個別的記憶體和 I/O 位址空間,而其他處理器則不實作。 由於硬體平臺有這些差異,因此驅動程式用來存取 I/O 或記憶體駐留裝置資源的機制與平臺與平臺不同。
驅動程式會要求裝置 I/O 和記憶體資源,以回應 PnP 管理員 的 IRP_MN_QUERY_RESOURCE_REQUIREMENTS IRP。 根據硬體架構,HAL 可以在 I/O 空間或記憶體空間中指派 I/O 資源,也可以在 I/O 空間或記憶體空間中指派記憶體資源。
如果 HAL 使用匯流排相對記憶體空間來存取裝置資源, (例如裝置暫存器) ,驅動程式必須將 I/O 空間對應至虛擬記憶體,才能存取這些資源。 驅動程式可以檢查裝置啟動時由 PnP 管理員傳遞給驅動程式的翻譯資源,以判斷資源是 I/O 或記憶體駐留。 如果 HAL 使用 I/O 空間,則不需要對應。
具體而言,當驅動程式收到 IRP_MN_START_DEVICE 要求時,應該分別檢查 IrpSp-Parameters.StartDevice.AllocatedResources > 和 IrpSp-Parameters.StartDevice.AllocatedResourcesTranslated >的結構,其中分別描述原始 (匯流排相對) 和轉譯的資源,也就是 PnP 管理員指派給裝置。 驅動程式應該在裝置擴充功能中儲存每個資源清單的複本,以協助偵錯。
資源清單會配對 CM_RESOURCE_LIST 結構,其中原始清單的每個元素都會對應至已翻譯清單的相同元素。 例如,如果 AllocatedResources.List[0] 描述原始 I/O 埠範圍, AllocatedResourcesTranslated.List[0] 會在轉譯後描述相同的範圍。 每個翻譯的資源都包含實體位址和資源類型。
如果驅動程式獲指派轉譯的記憶體資源 (CmResourceTypeMemory) ,它必須呼叫 MmMapIoSpace ,將實體位址對應到虛擬位址,才能存取裝置註冊。 若要讓驅動程式以與平臺無關的方式運作,應該檢查每個傳回、翻譯的資源,並視需要加以對應。
核心模式驅動程式應該採取下列步驟,以回應IRP_MN_START_DEVICE要求,以確保存取所有裝置資源
將 IrpSp-Parameters.StartDevice.AllocatedResources > 複製到裝置延伸模組。
將 IrpSp-Parameters.StartDevice.AllocatedResourcesTranslated > 複製到裝置延伸模組。
在 迴圈中,檢查 AllocatedResourcesTranslated中的每個描述元元素。 如果描述項資源類型是 CmResourceTypeMemory,請呼叫 MmMapIoSpace,傳遞已翻譯資源的實體位址和長度。
當驅動程式從 PnP 管理員收到 IRP_MN_STOP_DEVICE 或 IRP_MN_REMOVE_DEVICE 要求時,必須在類似的迴圈中呼叫 MmUnmapIoSpace 來釋放對應。 如果驅動程式必須失敗IRP_MN_START_DEVICE要求,驅動程式也應該呼叫MmUnmapIoSpace。
原始資源類型會指出驅動程式應該呼叫哪些 HAL 存取常式, (READ_REGISTER_XXX、WRITE_REGISTER_XXX、READ_PORT_XXX WRITE_PORT_XXX) 。 大部分的驅動程式不需要檢查原始資源清單,即可判斷要使用哪些常式,因為驅動程式本身要求資源或驅動程式寫入器知道裝置硬體的本質所需的類型。
對於 I/O 空間中的資源 (CmResourceTypePort、CmResourceTypeInterrupt、CmResourceTypeDma) ,驅動程式應該使用傳回實體位址的低序 32 位來存取裝置資源,例如,透過 HAL 的讀取和寫入READ_REGISTER_XXX、WRITE_REGISTER_XXX、READ_PORT_XXX、WRITE_PORT_XXX常式。