ioctl(I/O Control)是 Linux 設備驅動開發中核心的控制介面,實現用戶空間與核心空間的資料交換與設備配置。本文從原理、必要性、實作機制到命令碼編碼,全方位剖析 ioctl 的運作機制。
ioctl 專門處理無法用標準 read/write 描述的設備控制操作,例如:
函數原型:
int ioctl(int fd, unsigned long cmd, ...);
fd:open() 回傳的檔案描述符cmd:編碼後的控制命令碼...:選擇性參數(通常為指向資料結構的指標)若無 ioctl,開發者只能濫用 write 傳遞特殊控制碼,導致:
ioctl 提供標準化、可擴充的控制通道,實現「用戶空間發命令、驅動程式做解析」的清晰分工。
驅動程式中的 ioctl 實際是一個巨大的 switch-case 結構:
long my_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {
switch (cmd) {
case MY_IOCTL_SET_BAUDRATE:
// 設定鮑率邏輯
break;
case MY_IOCTL_GET_STATUS:
// 取得狀態邏輯
break;
default:
return -ENOTTY; // 無效命令
}
return 0;
}
Linux 核心定義 32 位元命令碼結構:
| 欄位 | 位寬 | 說明 |
|---|---|---|
| 型別 | 8 bits | 幻數,通常用單一字母區分設備類別 |
| 序號 | 8 bits | 同一型別下的命令流水號 |
| 方向 | 2 bits | _IOC_NONE/_IOC_READ/_IOC_WRITE/_IOC_READ|_IOC_WRITE |
| 資料大小 | 13~14 bits | 參數資料結構大小(byte) |
核心提供四大宏自動生成命令碼:
_IO(type, nr):無參數_IOR(type, nr, datatype):讀取資料(驅動→用戶)_IOW(type, nr, datatype):寫入資料(用戶→驅動)_IOWR(type, nr, datatype):雙向傳輸ioctl(fd, MY_CMD, &arg)unlocked_ioctlswitch-case 分派至具體處理函式copy_to_user/copy_from_user 交換資料_IOC_DIR 檢查傳輸方向,防止記憶體越界Documentation/ioctl/ioctl-number.txt 避免幻數衝突scull 範例掌握 ioctl 精髓在於理解命令碼編碼/解碼機制與 switch-case 分派邏輯,這是驅動開發進階的必修課。