(LKM char设备驱动程序)简单的Linux内核模块从用户空间读取和写入内核空间

时间:2018-02-08 15:08:59

标签: c linux ubuntu linux-kernel linux-device-driver

1 sudo tail -f / var / log / syslog

2 用户空间程序输出。

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

我认为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;
}

用户空间计划

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

用户空间程序的输出

sudo ./a.out 用户空间:启动设备测试代码示例...  用户空间:写入消息到设备[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]。 用户空间:按ENTER键从设备读回...

用户空间:从设备中读取...... 用户空间:收到的消息是:[] 用户空间:程序结束 河@ mystic-computer:〜$ ^ C

sudo tail -f / var / log / syslog

的输出

Feb 8 22:11:05 mystic-computer kernel:[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 2月8日22:12:24神秘计算机内核:[21758.895678]消息的KERNEL-SPACE大小为0 KERNEL-SPACE消息[0] = KERNEL-SPACE消息[116] = KERNEL-SPACE消息[152] = KERNEL- SPACE消息[154] =&lt; 6&gt; [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:设备类正确注册 2月8日22:13:25神秘计算机内核:[21829.177943] EBBChar:设备类正确创建 2月8日22:13:40神秘计算机内核:[21844.080308] EBBChar:设备已经打开1次 2月8日22:13:40神秘计算机内核:[21844.080649] KERNEL-SPACE复制copy_to_user()0 2月8日22:13:40神秘计算机内核:[21844.080654] KERNEL-SPACE消息大小为0 2月8日22:13:40神秘计算机内核:[21844.080654]&lt; 6&gt; [21844.080660] KERNEL-SPACE消息[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 2月8日22:12:24神秘计算机内核:[21758.895678]消息的KERNEL-SPACE大小为0 KERNEL-SPACE消息[0] = KERNEL-SPACE消息[116] = KERNEL-SPACE消息[152] = KERNEL- SPACE消息[154] =&lt; 6&gt; [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:设备类正确注册 2月8日22:13:25神秘计算机内核:[21829.177943] EBBChar:设备类正确创建 2月8日22:13:40神秘计算机内核:[21844.080308] EBBChar:设备已经打开1次 2月8日22:13:40神秘计算机内核:[21844.080649] KERNEL-SPACE复制copy_to_user()0 2月8日22:13:40神秘计算机内核:[21844.080654] KERNEL-SPACE消息大小为0 2月8日22:13:40神秘计算机内核:[21844.080654]&lt; 6&gt; [21844.080660] KERNEL-SPACE消息[0] =(null) 2月8日22:13:40神秘计算机内核:[21844.081224] KERNEL-SPACE消息[247] =(null) 2月8日22:13:40神秘计算机内核:[21844.081226] KERNEL-SPACE消息[248] =(null) 2月8日22:13:40神秘计算机内核:[21844.081228] KERNEL-SPACE消息[249] =(null) 2月8日22:13:40神秘计算机内核:[21844.081230] KERNEL-SPACE消息[250] =(null) 2月8日22:13:40神秘计算机内核:[21844.081233] KERNEL-SPACE消息[251] =(null) 2月8日22:13:40神秘计算机内核:[21844.081235] KERNEL-SPACE消息[252] =(null) 2月8日22:13:40神秘计算机内核:[21844.081237] KERNEL-SPACE消息[253] =(null) 2月8日22:13:40神秘计算机内核:[21844.081239] KERNEL-SPACE消息[254] =(null) 2月8日22:13:40神秘计算机内核:[21844.081242] KERNEL-SPACE消息[255] =(null) 2月8日22:13:40神秘计算机内核:[21844.081245] EBBChar:收到消息为用户的256个字符

2 个答案:

答案 0 :(得分:0)

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

否则,

printf(“USER-SPACE:收到的消息是:[%s] \ n”,收到);

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

至少修正此问题以使打印输出正确。

答案 1 :(得分:0)

AH atlast !!搞清楚了。实际上dev_write没有工作,因为没有使用kmalloc获取内存(静态char [256] *消息)

message = kmalloc(len,GFP_KERNEL);

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