LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel
User Name
Password
Linux - Kernel This forum is for all discussion relating to the Linux kernel.

Notices


Reply
  Search this Thread
Old 07-07-2010, 09:48 AM   #1
AlexM25
LQ Newbie
 
Registered: Jul 2010
Posts: 4

Rep: Reputation: 0
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 a 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
 
Old 07-07-2010, 09:58 AM   #2
zirias
Member
 
Registered: Jun 2010
Posts: 361

Rep: Reputation: 59
Quote:
Originally Posted by AlexM25 View Post
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" */
}
Shouldn't this return your "bytesRead" variable?

Quote:
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.
Did you verify this with a debugger or du you just assume so because of the results of your program?

BTW, if this is not just for the sake of practicing kernel module programming, don't write a module for this. There are several IPC mechanisms readily available (pipes, named pipes, shared memory areas) and one of them will probably suit your problem well.
 
Old 07-07-2010, 10:06 AM   #3
AlexM25
LQ Newbie
 
Registered: Jul 2010
Posts: 4

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by zirias View Post
Shouldn't this return your "bytesRead" variable?
I actually manipulate the 'Length' variable I get from the userspace, and in the end of the module_read function it holds the amount of bytes actually read (it may be smaller than the amount requested).

Quote:
Did you verify this with a debugger or du you just assume so because of the results of your program?
I verified with a debugger.


Quote:
BTW, if this is not just for the sake of practicing kernel module programming, don't write a module for this. There are several IPC mechanisms readily available (pipes, named pipes, shared memory areas) and one of them will probably suit your problem well.
Unfortunately it is
It's for a HW assignment in an OS course I'm taking.
 
Old 07-07-2010, 10:26 AM   #4
zirias
Member
 
Registered: Jun 2010
Posts: 361

Rep: Reputation: 59
Ok, maybe your implementation of the proc interface does not return the correct values... it seems to be a quite strange interface. The following is a working proc-read implementation i had to do for a university course:

Code:
static int proc_idedisk_read_breakeven
	(char *page, char **start, off_t off, int count, int *eof, void *data)
{
	ide_drive_t	*drive = (ide_drive_t *) data;
	int len = sprintf(page, "%u\n",
			jiffies_to_msecs(drive->break_even_period));
	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
I just did some copy&paste development back then, so didn't bother much about the macro used:
Code:
#define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) \
{                                       \
        len -= off;                     \
        if (len < count) {              \
                *eof = 1;               \
                if (len <= 0)           \
                        return 0;       \
        } else                          \
                len = count;            \
        *start = page + off;            \
        return len;                     \
}
but it looks quite a little complicated. maybe you got something wrong in your code
 
Old 07-07-2010, 11:54 AM   #5
Odulo
LQ Newbie
 
Registered: Jul 2010
Distribution: Ubuntu / Fedora
Posts: 4

Rep: Reputation: 0
Quote:
Originally Posted by AlexM25 View Post
every time it runs, it always receives 1024 in the 'length' var.
No matter how much bytes I really try to read in userspace.
If you want to read more than 1024 what happens ? The read function is call several time ? I have seen that when I wanted to write a large amount of data. I have not tried with less than 1024.
 
Old 07-07-2010, 02:20 PM   #6
AlexM25
LQ Newbie
 
Registered: Jul 2010
Posts: 4

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by zirias View Post
Ok, maybe your implementation of the proc interface does not return the correct values... it seems to be a quite strange interface. The following is a working proc-read implementation i had to do for a university course:

Code:
static int proc_idedisk_read_breakeven
	(char *page, char **start, off_t off, int count, int *eof, void *data)
{
	ide_drive_t	*drive = (ide_drive_t *) data;
	int len = sprintf(page, "%u\n",
			jiffies_to_msecs(drive->break_even_period));
	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
I just did some copy&paste development back then, so didn't bother much about the macro used:
Code:
#define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) \
{                                       \
        len -= off;                     \
        if (len < count) {              \
                *eof = 1;               \
                if (len <= 0)           \
                        return 0;       \
        } else                          \
                len = count;            \
        *start = page + off;            \
        return len;                     \
}
but it looks quite a little complicated. maybe you got something wrong in your code
I'm not sure I understand your code.
How do you send data to the userspace? using spritnf to page?
The way I do it is:
Code:
copy_to_user(buffer, procfs_buffer, length)
In either case, when I get length parameter in the function it's already 1024, so it doesn't change anything for me...


Quote:
Originally Posted by Odulo View Post
If you want to read more than 1024 what happens ? The read function is call several time ? I have seen that when I wanted to write a large amount of data. I have not tried with less than 1024.
I haven't tried it yet, because I'm having a problem with smaller ones.
If I try to read 5 bytes out of a 10-byte buffer, the read_module function receives a command to read 1024 bytes, reads 10 bytes (the entire buffer content) and returns it to userspace (that only receives 5 first bytes of it).
So that's my problem...


Edit:
I did try to read more than 1024 bytes, and it seems the reads I get are in 1024 bytes blocks.
i.e. If I try to read 1500 bytes, I get 1024 in 'length'.
If I try to read 5000 bytes, I get 4096 in 'length'.

Last edited by AlexM25; 07-08-2010 at 12:46 AM.
 
Old 07-08-2010, 02:56 AM   #7
AlexM25
LQ Newbie
 
Registered: Jul 2010
Posts: 4

Original Poster
Rep: Reputation: 0
It's possible I implemented a block device instead of a char device.
Is it possible I need to create a char device using the mknod command, and then read/write from/to it?
(instead of directly from /proc/devicename)
 
Old 07-08-2010, 11:17 AM   #8
Odulo
LQ Newbie
 
Registered: Jul 2010
Distribution: Ubuntu / Fedora
Posts: 4

Rep: Reputation: 0
I don't know block devices but yes it can be a reason.

Yes you can use char devices and directly write/read from or to them.

You can use sysfs/udev (class_create, device_create, etc.) instead of having to create the nodes by yourself.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Userspace Executable are kernel independent? Harini1111 Linux - Kernel 2 12-05-2008 10:26 AM
Efficient kernel<->userspace data transfering maverik Programming 2 05-31-2008 02:24 AM
Using kernel functions and macros in userspace karimasif Linux - General 1 01-16-2008 11:34 PM
2in1 problem thread. (nvidia kernel module vs X module, and strange workbug phenom) htedrom Linux - Software 15 10-04-2007 10:55 PM
reading /proc information from kernel module someshwar Linux - Kernel 1 10-31-2006 11:35 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software > Linux - Kernel

All times are GMT -5. The time now is 04:56 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration