簡體   English   中英

在Linux內核模塊的ioctl上獲得ENOTTY

[英]Getting ENOTTY on ioctl for a Linux Kernel Module

我定義了以下chardev:

。H

#define MAJOR_NUM 245
#define MINOR_NUM 0
#define IOCTL_MY_DEV1 _IOW(MAJOR_NUM, 0, unsigned long)
#define IOCTL_MY_DEV2 _IOW(MAJOR_NUM, 1, unsigned long)
#define IOCTL_MY_DEV3 _IOW(MAJOR_NUM, 2, unsigned long)

.c模塊

static long device_ioctl(
                  struct file*   file,
                  unsigned int   ioctl_num,
                  unsigned long  ioctl_param)
{
    ...
}

static int device_open(struct inode* inode, struct file* file)
{
    ...
}

static int device_release(struct inode* inode, struct file* file)
{
    ...
}

struct file_operations Fops = {
    .open=device_open,
    .unlocked_ioctl= device_ioctl,
    .release=device_release
};

static int __init my_dev_init(void)
{
    register_chrdev(MAJOR_NUM, "MY_DEV", &Fops);
    ...
}
module_init(my_dev_init);

我的用戶代碼

ioctl(fd, IOCTL_MY_DEV1, 1);

總是失敗,並出現相同的錯誤: ENOTTY

設備不正確的ioctl

我見過類似的問題:

Linux內核模塊-IOCTL使用率返回ENOTTY

Linux內核模塊/ IOCTL:不適合設備的ioctl

但是他們的解決方案對我不起作用

當您的設備驅動程序尚未注冊要調用的ioctl函數時,內核會發出ENOTTY 恐怕您的函數未正確注冊,可能是因為您已在struct file_operations結構的.unlocked_ioctl字段中注冊了它。

如果在功能的鎖定版本中注冊它,可能會得到不同的結果。 最可能的原因是索引節點被鎖定以進行ioctl調用(應該這樣做是為了避免競爭條件,同時對同一設備進行readwrite操作)

抱歉,我無法使用要使用的字段的正確名稱訪問linux源代碼樹,但是可以肯定的是,您可以自己找到它。

注意

我觀察到您使用了宏_IOW ,並將主數字用作唯一標識符。 這可能不是您想要的。 _IOW第一個參數試圖確保ioctl調用獲得唯一標識符。 沒有通用的方法來獲取此類標識符,因為這是您在應用程序代碼和內核代碼之間創建的接口協定。 因此,使用主號碼是不好的做法,原因有兩個:

  • 多個設備(至少在Linux中)可以共享相同的主編號(Linux內核中的次要分配允許這樣做),從而可能在設備的ioctl之間發生沖突。
  • 萬一您更改了主號碼(在已分配了該號碼的情況下配置了內核),則必須重新編譯所有用戶級別的軟件,以應對新的設備ioctl id(如果這樣做,它們都將更改)

_IOW是很久以前(從Linux內核誕生之日起)構建的宏,它試圖解決此問題,方法是允許您為每個驅動程序選擇一個不同的字符(但不依賴於其他內核參數,原因已指出)對於具有ioctl調用且未與其他設備驅動程序沖突的設備。 發生這種沖突的可能性很小,但是發生這種情況時,可能會導致機器狀態不正確(您已向錯誤的設備發出了有效的,有效的ioctl調用)

古代的unix(和早期的linux)內核使用不同的字符來構建這些調用,因此,例如, tty驅動程序將'T'用作_IO*宏的參數,scsi磁盤使用了'S'等。

我建議您選擇一個隨機數(不在Linux內核列表中的其他位置出現),然后在所有設備中使用它(可能編寫的驅動程序比內核中的驅動程序少),並為每個ioctl選擇一個不同的ioctl id呼叫。 用這種方式用已注冊的ioctl維護本地ioctl文件比嘗試猜測始終有效的值要好得多。

另外,看看_IO*宏的定義應該是非常說明性的:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM