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

标签 c linux kernel

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

最佳答案

结构 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 命令,则必须弄清楚您应该使用 union 体中的哪些成员,包括用户空间和内核。

如果您要实现自己的 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);

这里的缓冲区只是一个固定大小的数组,如果您需要更大的灵 active ,您当然可以使用结构,只要用户空间和您的内核 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);

关于c - 如何将用户空间中缓冲区的地址传递给内核,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25640944/

相关文章:

c - 带有左对齐标志的 printf() 位置参数

python - 将我的 PyGtk 3 应用程序移植到 Win32

php - 如何在 Laravel PHP 中使用控制台内核?

c - 如何测量 Linux 中的实际 CPU 使用率?

Linux ioport.h 和 memblock.h 头文件丢失

c - gtk_init 改变了 sprintf 的功能

java - 可访问、跨平台、相关的 UI 框架?

c - 在 C 中解析 Twitter 提要

linux - Spring aop作用域代理在Linux安装上不起作用

python - Crontab在docker上运行但未调度