如何将用户空间中的缓冲区地址传递给内核

时间:2014-09-03 09:35:19

标签: c linux kernel

我想使用copy_to_user()将平台网络设备的一些信息复制到用户空间中的缓冲区。但我不知道内核如何知道" to" copy_to_user()使用的指针。 驱动程序的ioctl()需要struct ifreq作为参数。我知道我可以初始化ifreq.name以找到驱动程序的ioctl()。但是如何将"传递给&# 34;指向内核的指针恰好是驱动程序' ioctl()?

2 个答案:

答案 0 :(得分:1)

struct 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是,您是'寻找。)

即。用户空间

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);

答案 1 :(得分:0)

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

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