【问题标题】:Linux kernel module compile error: implicit declaration of function ‘open’Linux内核模块编译错误:函数“open”的隐式声明
【发布时间】:2017-04-12 17:55:55
【问题描述】:

我正在尝试为 linux 编写一个简单的嗅探器驱动程序,它将所有请求重定向到真正的串行端口(并且还将所有消息打印到系统日志中)。我在网上找了一些例子,实现的功能很少。例如打开ouw fake设备时调用的函数:

static int dev_open(struct inode *inodep, struct file *filep) {
   numberOpens++;
   printk(KERN_INFO "sniffer: Device has been opened %d time(s)\n", numberOpens);

   /// Connecting to real device   
   fd = open (real_device, O_RDWR | O_NOCTTY | O_SYNC);
   if (fd < 0) {
      printk(KERN_INFO "sniffer: cannot open device %s\n", real_device);
     return 1;
   }

   set_interface_attribs (fd, B115200, 0);  // set speed to 115,200 bps, 8n1 (no parity)
   set_blocking (fd, 0);                     // set no blocking
   return 0;
}

如您所见,此函数只是使用标准 linux open 系统调用打开真实设备。或设置真实设备设置(速度和奇偶校验)的功能:

int set_interface_attribs (int fd, int speed, int parity) {
    struct termios tty;
    memset (&tty, 0, sizeof tty);
    if (tcgetattr (fd, &tty) != 0) {
        // error_message ("error %d from tcgetattr", errno);
        printk(KERN_INFO "sniffer: cannot get device attributes\n");
        return -1;
    }

    cfsetospeed (&tty, speed);
    cfsetispeed (&tty, speed);

    tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;     // 8-bit chars
    // disable IGNBRK for mismatched speed tests; otherwise receive break
    // as \000 chars
    tty.c_iflag &= ~IGNBRK;         // disable break processing
    tty.c_lflag = 0;                // no signaling chars, no echo,
                                // no canonical processing
    tty.c_oflag = 0;                // no remapping, no delays
    tty.c_cc[VMIN]  = 0;            // read doesn't block
    tty.c_cc[VTIME] = 5;            // 0.5 seconds read timeout

    tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl

    tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,
                                    // enable reading
    tty.c_cflag &= ~(PARENB | PARODD);      // shut off parity
    tty.c_cflag |= parity;
    tty.c_cflag &= ~CSTOPB;
    tty.c_cflag &= ~CRTSCTS;

    if (tcsetattr (fd, TCSANOW, &tty) != 0) {
        printk(KERN_INFO "sniffer: cannot set device attributes\n");
        return -1;
    }
    return -1;
}

它使用tcgetattrtcsetattr 系统调用。

我包含了所有必需的头文件:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/fcntl.h> 
#include <linux/unistd.h>
#include <linux/string.h>
#include <linux/termios.h>
#include <linux/fs.h>
#include <asm/uaccess.h>

但是当我尝试编译这个模块时,我得到这个系统调用的“函数隐式声明”错误。

我的 Makefile:

obj-m += sniffer.o

all:
    $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

编译错误:

sniffer.c: In function ‘set_interface_attribs’:
sniffer.c:51:9: error: implicit declaration of function ‘tcgetattr’ [-Werror=implicit-function-declaration]
     if (tcgetattr (fd, &tty) != 0) {
         ^
sniffer.c:57:5: error: implicit declaration of function ‘cfsetospeed’ [-Werror=implicit-function-declaration]
     cfsetospeed (&tty, speed);
     ^
sniffer.c:58:5: error: implicit declaration of function ‘cfsetispeed’ [-Werror=implicit-function-declaration]
     cfsetispeed (&tty, speed);
     ^
sniffer.c:79:9: error: implicit declaration of function ‘tcsetattr’ [-Werror=implicit-function-declaration]
     if (tcsetattr (fd, TCSANOW, &tty) != 0) {
         ^
sniffer.c: In function ‘dev_open’:
sniffer.c:151:9: error: implicit declaration of function ‘open’ [-Werror=implicit-function-declaration]
    fd = open (real_device, O_RDWR | O_NOCTTY | O_SYNC);
         ^
sniffer.c: In function ‘dev_read’:
sniffer.c:164:18: error: implicit declaration of function ‘read’ [-Werror=implicit-function-declaration]
    error_count = read(fd, buffer, len);
                  ^
sniffer.c: In function ‘dev_write’:
sniffer.c:177:4: error: implicit declaration of function ‘write’ [-Werror=implicit-function-declaration]
    write (fd, buffer, len);
    ^
sniffer.c: In function ‘dev_release’:
sniffer.c:184:4: error: implicit declaration of function ‘close’ [-Werror=implicit-function-declaration]
    close(fd);
    ^

可能是什么?我发现的所有示例都只是说我应该包括&lt;linux/unistd.h&gt;&lt;linux/termios.h&gt;

【问题讨论】:

  • 您不能只是将用户空间代码翻译到内核中并让它工作。您将需要找出每个缺失函数的内核内部等效项是什么。准备做大量更多的工作。
  • (我不知道等价物是什么,但我知道从设备内部调用“标准 [d] linux open 系统调用”实际上没有意义驱动程序,并且您尝试调用的各种 termios 函数是围绕 ioctl 操作的用户空间 C 库包装器,这在设备驱动程序中可能甚至没有意义。)
  • @zwol 是的,我现在开始意识到这一点,谢谢。我找到了文件操作的内核等价物。但是还不知道如何使用 termios 函数
  • 函数tcgetattrtcsetattr 实际上是ioctl 请求的包装器。在内核中,您可以使用 file-&gt;f_ops-&gt;unlocked_ioctl() 作为 ioctl 系统调用的模拟。为了确定termios使用的确切ioctl代码,在用户空间编写一些代码,然后在trace工具下运行。
  • 为什么成功和失败都返回-1

标签: c linux linux-kernel kernel-module


【解决方案1】:

我有类似的问题,我发现是添加

#include <linux/uaccess.h> 

包含的列表解决了我在 Ubuntu 18.04(Linux 内核版本:4.15.0)上的问题。

注意:也离开#include &lt;asm/uaccess.h&gt;

在某些情况下,重新排序包含语句会有所帮助。查看此问题的答案:

warning: implicit declaration of function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    相关资源
    最近更新 更多