(LKM char device drivers ) Simple Linux Kernel Module 从用户空间读写到内核空间

(LKM char device drivers ) Simple Linux Kernel Module Read and write from userspace to kernelspace

1 sudo tail -f /var/log/syslog

2用户space程序输出。

无法使用用户space程序写入和读取内核space模块。

我认为 copy_to_user 函数返回 0,这意味着但实际上没有任何内容被复制。

我正在使用 derekmolloy 示例,但根本不起作用 (Ubuntu LTS 16.04.1)

其次想到我想问问我如何打印这个。 char* buffer dev_read 函数,因为当我想使用 printk 打印这个时,模块被杀死了。

dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset)

ebbchar.c (LKM)

static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset)
{
      int error_count = 0;

      error_count = copy_to_user(buffer, message, size_of_message);

     if (error_count==0)
     {            // if true then have success
        printk(KERN_INFO "EBBChar: Sent %d characters to the user\n", 
               size_of_message);
         return (size_of_message=0);  // clear the position to the 
                                      //start and 
       return 0;
     }
    else
   {
      printk(KERN_INFO "EBBChar: Failed to send %d characters to the 
             user\n", error_count);
      return -EFAULT;  // Failed -- return a bad address message (i.e. 
                       //-14)
   }
}


static ssize_t dev_write(struct file *filep, const char *buffer, size_t 
                       len, loff_t *offset)
{

      int error; 
      // sprintf(message, "%c", buffer, len);   // appending received 
                                            //string with its length
     error = copy_to_user(message, buffer , size_of_message);
   //ssize_t simple_read_from_buffer(void *to, size_t count, loff_t 
   //*ppos, const void *from, size_t available)
  //  error = simple_read_from_buffer(&message, 256, offset , buffer , 
                                     // len);

     int i = 0; 

     printk (KERN_INFO "KERNEL-SPACE copying copy_to_user() %d",error 

    size_of_message = strlen(message);                              
    printk ( KERN_INFO "KERNEL-SPACE size of message recivied is %d \n 
            ", size_of_message);

    for (i = 0 ; i < len ; i ++)
    {
        printk(KERN_INFO "KERNEL-SPACE message[%d]=%s \n" , i , 
        message[i] );
    }

        printk(KERN_INFO "EBBChar: Received %zu characters from the 
        user the message is %s\n", len, message);


    return len;
}

用户-space 程序

int main()
{
   int ret, 
   int fd;
   char stringToSend[BUFFER_LENGTH];


   fd = open("/dev/ebbchar", O_RDWR);// Open the device with 

    if (fd < 0)
    {
       perror("USER-SPACE : Failed to open the device...");
       return errno;
    }

   for (int i = 0 ; i < BUFFER_LENGTH ; i++)
   {
       stringToSend[i] = 'a';
   }    

   printf(" USER-SPACE : Writing message to the device [%s].\n", 
           stringToSend);

   ret = write(fd, stringToSend, BUFFER_LENGTH); // Send the string to 
                                                 //the LKM
   if (ret < 0)
   {
      perror(" USER-SPACE : Failed to write the message to the 
               device.");
      return errno;
   }

   printf("USER-SPACE : Press ENTER to read back from the 
                   device...\n");
   getchar();

   printf("USER-SPACE : Reading from the device...\n");
   ret = read(fd, receive, BUFFER_LENGTH); // Read the response from 
                                           // the LKM
   if (ret < 0)
   {
      perror("USER-SPACE : Failed to read the message from the 
            device.");
      return errno;
   }
    printf("USER-SPACE : The received message is: [%s]\n", receive);
    printf("USER-SPACE : End of the program\n");
    return 0;
}

用户-space程序的输出

须藤./a.out USER-SPACE:启动设备测试代码示例... USER-SPACE : Writing message to the device [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa��� �]. USER-SPACE : 按 ENTER 从设备读回...

USER-SPACE:从设备读取... USER-SPACE : 收到的消息是:[] USER-SPACE : 程序结束 river@mystic-computer:~$ ^C

sudo tail -f /var/log/syslog

的输出

2 月 8 日 22:11:05 神秘计算机内核:[21689.104780] EBBChar:设备已成功关闭 2 月 8 日 22:12:15 神秘计算机内核:[21758.895624] EBBChar:设备已打开 2 次 2 月 8 日 22:12:15 神秘计算机内核:[21758.895674] KERNEL-SPACE 复制 copy_to_user() 0 Feb 8 22:12:24 神秘计算机内核:[21758.895678] KERNEL-SPACE 接收到的消息大小为 0 KERNEL-SPACE message[0]=KERNEL-SPACE message[116 ]=KERNEL-SPACE message[152]=KERNEL-SPACE message[154]=<6>[21767.721994] EBBChar:向用户发送了 0 个字符 2 月 8 日 22:12:24 神秘计算机内核:[21767.722145] EBBChar:设备已成功关闭 2 月 8 日 22:13:08 神秘计算机内核:[21812.346367] EBBChar:LKM 再见! 2 月 8 日 22:13:25 神秘计算机内核:[21829.177728] EBBChar:初始化 EBBChar LKM 2 月 8 日 22:13:25 神秘计算机内核:[21829.177743] EBBChar:使用主编号 243 正确注册 2 月 8 日 22:13:25 神秘计算机内核:[21829.177773] EBBChar:设备 class 已正确注册 2 月 8 日 22:13:25 神秘计算机内核:[21829.177943] EBBChar:正确创建设备 class 2 月 8 日 22:13:40 神秘计算机内核:[21844.080308] EBBChar:设备已打开 1 次 2 月 8 日 22:13:40 神秘计算机内核:[21844.080649] KERNEL-SPACE 复制 copy_to_user() 0 Feb 8 22:13:40 神秘计算机内核:[21844.080654] KERNEL-SPACE 接收到的消息大小为 0 Feb 8 22:13:40 神秘计算机内核:[21844.080654] <6>[21844.080660] KERNEL-SPACE message[0]=(null) 2 月 8 日 22:11:05 神秘计算机内核:[21689.104780] EBBChar:设备已成功关闭 2 月 8 日 22:12:15 神秘计算机内核:[21758.895624] EBBChar:设备已打开 2 次 2 月 8 日 22:12:15 神秘计算机内核:[21758.895674] KERNEL-SPACE 复制 copy_to_user() 0 Feb 8 22:12:24 神秘计算机内核:[21758.895678] KERNEL-SPACE 接收到的消息大小为 0 KERNEL-SPACE message[0]=KERNEL-SPACE message[116 ]=KERNEL-SPACE message[152]=KERNEL-SPACE message[154]=<6>[21767.721994] EBBChar:向用户发送了 0 个字符 2 月 8 日 22:12:24 神秘计算机内核:[21767.722145] EBBChar:设备已成功关闭 2 月 8 日 22:13:08 神秘计算机内核:[21812.346367] EBBChar:LKM 再见! 2 月 8 日 22:13:25 神秘计算机内核:[21829.177728] EBBChar:初始化 EBBChar LKM 2 月 8 日 22:13:25 神秘计算机内核:[21829.177743] EBBChar:使用主编号 243 正确注册 2 月 8 日 22:13:25 神秘计算机内核:[21829.177773] EBBChar:设备 class 已正确注册 2 月 8 日 22:13:25 神秘计算机内核:[21829.177943] EBBChar:正确创建设备 class 2 月 8 日 22:13:40 神秘计算机内核:[21844.080308] EBBChar:设备已打开 1 次 2 月 8 日 22:13:40 神秘计算机内核:[21844.080649] KERNEL-SPACE 复制 copy_to_user() 0 Feb 8 22:13:40 神秘计算机内核:[21844.080654] KERNEL-SPACE 接收到的消息大小为 0 Feb 8 22:13:40 神秘计算机内核:[21844.080654] <6>[21844.080660] KERNEL-SPACE message[0]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081224] KERNEL-SPACE message[247]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081226] KERNEL-SPACE message[248]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081228] KERNEL-SPACE message[249]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081230] KERNEL-SPACE message[250]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081233] KERNEL-SPACE message[251]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081235] KERNEL-SPACE message[252]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081237] KERNEL-SPACE message[253]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081239] KERNEL-SPACE message[254]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081242] KERNEL-SPACE message[255]=(null) 2 月 8 日 22:13:40 神秘计算机内核:[21844.081245] EBBChar:从用户那里收到 256 个字符消息是

不确定这是否能解决您的问题,但您需要使用 NULL 字符终止 stringToSend 数组,即 stringToSend[BUFFER_LENGTH - 1] = '\0'

否则,

printf("USER-SPACE : The received message is: [%s]\n", 接收);

无法正常工作,因为 printf() 不知道没有 NULL 字符的字符串在哪里终止。

至少要解决这个问题才能正确打印出来。

终于啊!!想通了。实际上 dev_write 没有工作,因为内存 (static char[256] *message) 不是使用 kmalloc

获取的

消息=kmalloc(len,GFP_KERNEL);

遇到此问题的任何人都可以使用 kmalloc。在内核 space 中获取内存。您可以在 __init 或 dev_write 函数中使用 kmalloc