【问题标题】:How can i pass the address of a buffer in user space to kernel如何将用户空间中缓冲区的地址传递给内核
【发布时间】:2014-09-03 09:35:18
【问题描述】:

我想使用 copy_to_user() 将平台网络设备的一些信息复制到用户空间的缓冲区。但我不知道内核如何知道 copy_to_user() 使用的“to”指针。 驱动程序的 ioctl() 需要 struct ifreq 作为参数。而且我知道我可以初始化 ifreq.name 以找到驱动程序的 ioctl()。但是我怎样才能将“to”指针准确地传递给内核 driver'ioctl()?

【问题讨论】:

    标签: c linux kernel


    【解决方案1】:

    结构 ifreq 看起来像这样:

    struct ifreq {
        char    ifr_name[IFNAMSIZ];/* Interface name */
        union {
                struct sockaddrifr_addr;
                struct sockaddrifr_dstaddr;
                struct sockaddrifr_broadaddr;
                struct sockaddrifr_netmask;
                struct sockaddrifr_hwaddr;
                short   ifr_flags;
                int     ifr_ifindex;
                int     ifr_metric;
                int     ifr_mtu;
                struct ifmapifr_map;
                char    ifr_slave[IFNAMSIZ];
                char    ifr_newname[IFNAMSIZ];
                char *  ifr_data;
        };
    };
    

    如果您要实现现有的 ioctl 命令,则必须弄清楚您应该使用联合中的哪些成员,无论是在用户空间还是内核中。

    如果您要实现自己的 ioctl 命令,则可以使用 ifr_data。调用者(在用户空间中)将成员设置为指向本地缓冲区,您将在内核中使用 copy_to_user() 填充该缓冲区(即 ifr_data 是您正在寻找的 to 。 )

    即用户空间可以

    char buf[128];
    struct ifreq req;
    strcpy(req.ifr_name,"eth0");
    req.ifr_data = buf;
    ioctl(fd, SIOCMYIOCTL, &ifr);
    

    这里的缓冲区只是一个固定大小的数组,如果您需要更大的灵活性,您当然可以使用结构,只要用户空间和您的内核 ioctl() 同意 ifr_data 是什么。

    struct my_ioctl_data {
         int a, b, c;
    };
    struct my_ioctl_data data;
    struct ifreq req;
    strcpy(req.ifr_name,"eth0");
    req.ifr_data = (char*)&data;
    ioctl(fd, SIOCMYIOCTL, &ifr);
    

    【讨论】:

      【解决方案2】:

      在平台网络设备驱动中更改读取方法:

      static ssize_t net_device_read(arg1,char __user *user_buffer,size_t count,loff_t *position)
      
      {
      
      
         copy_to_user(user_buffer, position,count) != 0 
      
      }
      

      使用 cat 命令从用户空间访问这个缓冲区

       cat /dev/net-device 
      >> string to pass
      

      在此处阅读更多信息:http://www.codeproject.com/Articles/112474/A-Simple-Driver-for-Linux-OS

      【讨论】:

      • 也谢谢你。但是在我的目标板上,结构 net_device_ops 没有读取函数指针(所以我真的不知道在哪里改变)。我不明白func(&position1,position) 的含义。为什么你的 copy_to_user() 看起来与只有 3 个参数的原型不同?
      • 已更正!但是您打算只使用 Ioctl 吗?如果是,我认为您应该考虑查看上面的 @nos 示例,或者请发布简洁的要求。
      • 我正在学习内核和用户之间的通信。你所说的另一种方式也有用但不适用于这种情况。在结构 net_device_ops 中,它没有读取功能指针。我在 struct file_operations 中找到它,所以下次我会知道如何在你的帮助下做。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-07
      • 1970-01-01
      • 2019-07-03
      相关资源
      最近更新 更多