On Fri, Sep 10, 2010 at 6:51 PM, fabio de francesco <[email protected]> wrote:
> Hi all,
>
> I have modified a simple character device driver as an exercise from the
> Cooperstein's Linux Device Drivers book.
>
> It seems to work fine except that when I "cat /dev/mycdrv" it provides
> garbage.
>
> This is a trimmed down version of the code:
>
> #include <linux/module.h> /* for modules */
> #include <linux/fs.h> /* file_operations */
> #include <linux/uaccess.h> /* copy_(to,from)_user */
> #include <linux/init.h> /* module_init, module_exit */
> #include <linux/slab.h> /* kmalloc */
> #include <linux/cdev.h> /* cdev utilities */
>
> #define MYDEV_NAME "mycdrv"
> #define KBUF_SIZE (size_t)( PAGE_SIZE )
>
> static char *kbuf;
> static dev_t first;
> static unsigned int count = 1;
> static int my_major = 700, my_minor = 0;
> static struct cdev *my_cdev;
> static int counter = 0;
>
> static int mycdrv_open (struct inode *inode, struct file *file)
> {
> printk( KERN_INFO " open #%d\n", ++counter );
> kbuf = kmalloc (KBUF_SIZE, GFP_KERNEL);
> memset( kbuf, '\0', KBUF_SIZE );
> return 0;
> }
>
> static int mycdrv_release (struct inode *inode, struct file *file)
> {
> printk (KERN_INFO " CLOSING device: %s:\n\n", MYDEV_NAME);
> kfree( kbuf );
> --counter;
> return 0;
> }
>
> static ssize_t
> mycdrv_read (struct file *file, char __user * buf, size_t lbuf, loff_t * ppos)
> {
> int nbytes, maxbytes, bytes_to_do;
> maxbytes = KBUF_SIZE - *ppos;
> bytes_to_do = lbuf <= maxbytes ? lbuf : maxbytes;
> nbytes = lbuf - copy_to_user (buf, kbuf + *ppos, bytes_to_do);
> *ppos += nbytes;
> printk (KERN_INFO "\n READING function, nbytes=%d, pos=%d\n", nbytes,
> (int)*ppos);
Can you post the output of this line?
> return nbytes;
> }
>
> static const struct file_operations mycdrv_fops = {
> .owner = THIS_MODULE,
> .read = mycdrv_read,
> .write = mycdrv_write,
> .open = mycdrv_open,
> .release = mycdrv_release,
> .llseek = mycdrv_llseek
> };
>
> static int __init my_init (void)
> {
> first = MKDEV (my_major, my_minor);
> alloc_chrdev_region( &first, 0, count, MYDEV_NAME );
> printk ( KERN_INFO "Device %s: MAJOR %d, MINOR %d\n", MYDEV_NAME, MAJOR(
> first ), MINOR( first ) );
> my_cdev = cdev_alloc ();
> cdev_init (my_cdev, &mycdrv_fops);
> cdev_add (my_cdev, first, count);
> printk (KERN_INFO "\nSucceeded in registering character device %s\n",
> MYDEV_NAME);
> return 0;
> }
>
> static void __exit my_exit (void)
> {
> cdev_del (my_cdev);
> unregister_chrdev_region (first, count);
> printk (KERN_INFO "\ndevice unregistered\n");
> }
>
> module_init (my_init);
> module_exit (my_exit);
>
> Please, could someone explain why the readings of the device return garbage
> data instead of NULL characters as I have set with memset()?
--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to [email protected]
Please read the FAQ at http://kernelnewbies.org/FAQ