Find the answer to your Linux question:
Results 1 to 3 of 3
Hello everyone, I have an issue with a kernel module I'm trying to write. The only purpose of the module is to be a buffer between 2 userspace programs (each ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jul 2010
    Posts
    2

    Problem with reading (in userspace) from a kernel module


    Hello everyone,

    I have an issue with a kernel module I'm trying to write.
    The only purpose of the module is to be a buffer between 2 userspace programs (each reading and writing to the buffer).

    The function I currently use to read from userspace:
    Code:
    /**  This funtion is called when the /proc file is read */
    static ssize_t module_read(struct file *file,	/* see include/linux/fs.h   */
    		char *buffer,	/* buffer to fill with data */
    		size_t length,	/* length of the buffer     */
    		loff_t * offset)
    {
    ...code...
    ...code...
    ...code...
      return length;	/* Return the number of bytes "read" */
    }
    has the following problem:
    every time it runs, it always receives 1024 in the 'length' var.
    No matter how much bytes I really try to read in userspace.

    btw, the userspace code I use for reading is:
    Code:
    bytesRead = fread(buffer,sizeof(char), sizeToRead, fd)
    Where 'sizeToRead' is an integer representing the amount of bytes I want to read, 'fd' is the file descriptor of the kernel module, and 'buffer' is the string I try to write.

    Moreover, and even more strangely:
    When the kernel module receives the request to get 1024 bytes, it sends to userspace 1024 bytes of data, and returns '1024' as number of bytes read (length variable).
    But in userspace, the number I get in 'bytesRead' (how much bytes I read) is identical to 'sizeToRead' and not the real amount of data that was sent from the kernel module.

    btw, I don't have this problem when writing to the kernel module:
    Code:
    bytesSent = fprintf(fd,"%s\n", buffer)
    fflush(fd)
    Thanks to all the helpers,
    Alex

  2. #2
    Just Joined!
    Join Date
    Oct 2006
    Posts
    1

    character I/O or block I/O

    I didn't read your message carefully, but I suspect what is going on is character I/O versus block I/O. When reading from or writing to a terminal/tty/keyboard, the I/O is done character by character. When reading from or writing to disk, the I/O is done in blocks of characters.

    Is there a reason why you aren't using a socketpair()? Is this some form of Inter-Process Communication that could be better done with shared memory (mmap or SysV) SysV messages (relatively small messages), or semaphores?


    What happens if you read or write more than 1024 characters?

    John

  3. #3
    Just Joined!
    Join Date
    Jul 2010
    Posts
    2
    Quote Originally Posted by yottzumm View Post
    I didn't read your message carefully, but I suspect what is going on is character I/O versus block I/O. When reading from or writing to a terminal/tty/keyboard, the I/O is done character by character. When reading from or writing to disk, the I/O is done in blocks of characters.

    Is there a reason why you aren't using a socketpair()? Is this some form of Inter-Process Communication that could be better done with shared memory (mmap or SysV) SysV messages (relatively small messages), or semaphores?


    What happens if you read or write more than 1024 characters?

    John
    I think you're right.
    I tried to read 1500 bytes, and got the 'length' as 1024.
    I tried to read 5000 bytes, and got the 'length' as 4096.
    It seems that I'm somehow implementing a block device instead of a character device.

    The reason I cannot do it in any other way, is that it's part of an OS course HW assignment. That's how I'm supposed to implement it.

    Can you tell me the difference between implementing a character device and a block device?
    I'm currently using this guide: tldp . org/LDP/lkmpg/2.6/html/lkmpg.html as reference.
    and according to it, the way to implement reading in a char device, is almost identical to mine:
    Code:
    /* 
     * This function is called whenever a process which has already opened the
     * device file attempts to read from it.
     */
    static ssize_t device_read(struct file *file,	/* see include/linux/fs.h   */
    			   char __user * buffer,	/* buffer to be
    							 * filled with data */
    			   size_t length,	/* length of the buffer     */
    			   loff_t * offset)
    {
    	/* 
    	 * Number of bytes actually written to the buffer 
    	 */
    	int bytes_read = 0;
    
    #ifdef DEBUG
    	printk(KERN_INFO "device_read(%p,%p,%d)\n", file, buffer, length);
    #endif
    
    	/* 
    	 * If we're at the end of the message, return 0
    	 * (which signifies end of file) 
    	 */
    	if (*Message_Ptr == 0)
    		return 0;
    
    	/* 
    	 * Actually put the data into the buffer 
    	 */
    	while (length && *Message_Ptr) {
    
    		/* 
    		 * Because the buffer is in the user data segment,
    		 * not the kernel data segment, assignment wouldn't
    		 * work. Instead, we have to use put_user which
    		 * copies data from the kernel data segment to the
    		 * user data segment. 
    		 */
    		put_user(*(Message_Ptr++), buffer++);
    		length--;
    		bytes_read++;
    	}
    
    #ifdef DEBUG
    	printk(KERN_INFO "Read %d bytes, %d left\n", bytes_read, length);
    #endif
    
    	/* 
    	 * Read functions are supposed to return the number
    	 * of bytes actually inserted into the buffer 
    	 */
    	return bytes_read;
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •