首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Windows NT 環境下實現 I/O 埠位址存取的完整指南

     編輯:關於C++

核心架構差異:為什麼 Windows NT 需要驅動程式?

Windows NT 採用嚴格的處理器模式保護機制:應用程式運行於用戶模式,任何嘗試直接執行 I/O 指令(如 IN、OUT)的行為都會觸發保護性失敗(General Protection Fault)。這與 Windows 95/98 允許應用程式直接存取硬體形成鮮明對比。要在 NT 系統下合法操作硬體 I/O,必須編寫運行於核心模式的設備驅動程式,由驅動程式代為執行 I/O 操作。

硬體抽象層(HAL)與總線架構

Windows NT 設計目標是跨平台可移植性(支援 x86、MIPS、Alpha、PowerPC 等架構),因此引入硬體抽象層(HAL)隔離硬體差異。驅動程式開發者必須理解:

  • 系統可能存在多種總線類型(ISA、PCI、EISA、MCA 等)
  • 不同總線之間可能需要位址轉換/傳遞
  • 必須嚴格區分I/O 空間與記憶體空間
  • 每條總線獨立支援記憶體週期與 I/O 週期

根據定義,I/O 寄存器/埠存取透過 I/O 週期 實現;但在某些系統中,外部總線的 I/O 空間可被映射到處理器記憶體空間(Memory-Mapped I/O),具體由 HAL 決定。

定位裝置資源:三要素

要存取特定 I/O 寄存器,驅動程式必須知道:

  1. 總線介面類型(Interface Type):如 Isa、PCIBus 等
  2. 總線編號(Bus Number):從 0 開始編號
  3. 該總線上的 I/O 空間位址

實戰範例:假設 ISA 裝置位於 0xE700

OffsetSize用途
01 Byte命令寄存器
11 Byte狀態寄存器
22 Bytes字資料寄存器
44 Bytes雙字資料寄存器

使用 DriverWorks (KIoRange) 存取裝置

步驟 1:建立 KIoRange 物件映射裝置寄存器

KIoRange DeviceIos;
NTSTATUS Status = DeviceIos.Initialize(
    Isa,        // 總線類型
    0,          // 總線編號
    0xE700,     // 總線位址
    8,          // 位址範圍大小 (8 bytes)
    TRUE        // 映射到系統空間 (若為記憶體映射 I/O)
);

if (NT_SUCCESS(Status)) {
    // 映射成功,可進行 I/O 操作
}

步驟 2:使用成員函數存取寄存器

// 定義寄存器偏移常數
#define COMMAND_REG   0
#define STATUS_REG    1
#define WORD_DATA_REG 2
#define DWORD_DATA_REG 3

// 讀取狀態寄存器 (1 byte)
UCHAR DeviceStatus = DeviceIos.inb(STATUS_REG);

// 寫入命令寄存器 (1 byte)
DeviceIos.outb(COMMAND_REG, CMD_RESET);

// 寫入 20 個字到資料埠 (2 bytes each)
DeviceIos.outw(WORD_DATA_REG, Buffer, 20);

替代方案:使用 KIoRegister 物件 (效能較佳)

若在同一函數中頻繁存取同一組寄存器,建立 KIoRegister 物件可減少函數呼叫開銷:

KIoRegister CommandReg = DeviceIos[COMMAND_REG];
KIoRegister StatusReg  = DeviceIos[STATUS_REG];

// 寫入命令 (隱含轉型為 UCHAR)
CommandReg = (UCHAR)RESET_CMD;

// 讀取狀態 (隱含轉型為 UCHAR)
UCHAR Status = StatusReg;

關鍵注意事項

  • 資料類型決定匯流排傳輸寬度:UCHAR (8-bit)、USHORT (16-bit)、ULONG (32-bit) 必須與硬體規格完全對應
  • KIoRegister 適合高頻存取場景;KIoRange 成員函數適合零星存取
  • 完成操作後,KIoRange 解構子會自動取消映射並釋放資源

總結

Windows NT 的安全模型強制將硬體存取封裝於核心模式驅動程式中。透過 HAL 抽象層與 DriverWorks 等工具包提供的 KIoRange/KIoRegister 類別,驅動程式開發者可跨平台、安全地實現 I/O 埠位址存取,同時保持程式碼可移植性與維護性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved