【问题标题】:Passing struct to device driver through IOCTL通过 IOCTL 将结构传递给设备驱动程序
【发布时间】:2012-08-21 06:35:22
【问题描述】:

我正在尝试将结构从用户空间传递到内核空间。我已经尝试了好几个小时,但它不起作用。这是我到目前为止所做的..

int device_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg){

int ret, SIZE;


switch(cmd){

    case PASS_STRUCT_ARRAY_SIZE:

        SIZE = (int *)arg;
        if(ret < 0){
            printk("Error in PASS_STRUCT_ARRAY_SIZE\n");
            return -1;  
        }
        printk("Struct Array Size : %d\n",SIZE);
        break;

    case PASS_STRUCT:


        struct mesg{
            int pIDs[SIZE];
            int niceVal;
        };

        struct mesg data;

        ret = copy_from_user(&data, arg, sizeof(*data));
        if(ret < 0){
            printk("PASS_STRUCT\n");
            return -1;  
        }

        printk("Message PASS_STRUCT : %d\n",data.niceVal);
        break;

    default :
        return -ENOTTY;
}

return 0;
  }

我在定义结构时遇到了麻烦。定义它的正确方法是什么?我想要 int pIDs[SIZE]。 int *pIDs 会这样做吗(在用户空间中它被定义为 pIDs[SIZE])?

编辑:

通过上述更改,我得到了这个错误?错误:“结构”之前的预期表达式有什么想法吗?

【问题讨论】:

  • 关于 PASS_STRUCT 情况,您应该将“数据”定义为 struct ,而不是指向 struct 的指针,然后将大小正确传递给 copy_from_user。你的问题更有可能是 C。恕我直言,在挖掘内核之前你应该对 C 有更多的经验。
  • 你觉得我应该如何定义这个函数,#define PASS_STRUCT _IOW(MY_MAGIC, 2, struct mesg*)?
  • 我将数据定义为结构,(struct mesg data;)。但是给出了错误错误:'data'的存储大小未知..有什么想法吗?
  • 这个错误很可能是switch语句中的问题,而不是宏中的问题。是哪一行?如果您认为宏有问题,请尝试使用 gcc -E 选项进行编译,看看预处理后会发生什么。
  • @sardok 是的,问题不在于宏..我在更改 mesg 结构后检查了它,它编译了..

标签: linux linux-kernel linux-device-driver ioctl


【解决方案1】:

您的问题中的结构有两种变体。

 struct mesg1{
  int *pIDs;
  int niceVal;
 };

 struct mesg2{
  int pIDs[SIZE];
  int niceVal;
 };

它们是不同的;在mesg1 的情况下,您有指向 int 数组的指针(位于结构之外)。在其他情况下(mesg2),结构内有 int 数组。

如果您的 SIZE 是固定的(在您的模块的 API 中;在用户空间和内核空间中使用的值相同),您可以使用第二个变体 (mesg2)。

要使用结构的第一个变体 (mesg1),您可以将字段 size 添加到结构本身,例如:

 struct mesg1{
  int pIDs_size;
  int *pIDs;
  int niceVal;
 };

并用 *pIDs 指向的整数计数填充它。

PS:请永远不要在结构中间使用具有可变大小数组的结构(又名 VLAIS)。这是 GCC 编译器对 C 语言的专有、奇怪、错误和 non-documented 扩展。根据国际 C 标准,只有结构的最后一个字段可以是 array with variable size (VLA)。这里有一些例子:12

PPS:

你可以用 VLA 声明你的结构(如果只有一个可变大小的数组):

 struct mesg2{
  int niceVal;
  int pIDs[];
 };

但是在使用 VLA 为此类结构分配内存时应该小心

【讨论】:

  • 嗯,我想使用 mesg2 类型。在传递结构之前,我计划传递 SIZE。会有用吗?
  • 不,您应该在设计步骤中修复 SIZE,然后永远不要通过它。或者你应该重写你的结构,使数组成为结构的最后一个字段。
  • Merriam-Webster 定义:“根据发明人或制造者的专有合法权利使用、生产或销售的东西;// 由拥有专有合法权利的人使用、制造或销售”。有没有支持 VLAIS 的非 GCC 编译器?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-26
  • 2021-05-03
  • 1970-01-01
  • 2012-11-29
  • 2012-01-05
  • 1970-01-01
相关资源
最近更新 更多