Practical character driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



hi
i write a a character device driver practically, when i load it in kernel, kernel kill the driver because of a crash. i also put the C file in this mail so please review my code please,
i want to know problem, mistakes, hints and ....
thank you so much

here is a tracback

=========================
[Â 704.202596] Pid: 6912, comm: insmod Not tainted 2.6.37-2 #2 33238RG/33238RG
[Â 704.202648] RIP: 0010:[<ffffffffa00db0da>]Â [<ffffffffa00db0da>] module_initial+0xda/0x146 [memchar]
[Â 704.202722] RSP: 0018:ffff880031c85f08Â EFLAGS: 00010246
[Â 704.202763] RAX: ffff8801317bf5c0 RBX: 0000000000000000 RCX: 0000000000000000
[Â 704.202816] RDX: ffff8801317bf5c0 RSI: ffffffffa00a1320 RDI: 0000000000000008
[Â 704.202868] RBP: 0000000000000008 R08: ffff8800bb016350 R09: ffff8800ab0b49c0
[Â 704.202921] R10: 0000000000000000 R11: 00000000000136c0 R12: 0000000000000000
[Â 704.202974] R13: 0000000000026085 R14: 0000000000040000 R15: 0000000000000003
[Â 704.203027] FS:Â 00007fe95def9700(0000) GS:ffff8800bb000000(0000) knlGS:0000000000000000
[Â 704.203087] CS:Â 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[Â 704.203130] CR2: 0000000000000000 CR3: 00000000ab169000 CR4: 00000000000006f0
[Â 704.203182] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[Â 704.203240] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[Â 704.203293] Process insmod (pid: 6912, threadinfo ffff880031c84000, task ffff880131741a00)
[Â 704.203353] Stack:
[Â 704.203371]Â 00000000ffffffff 0fc00001810b0439 0000000000000000 0000000000000000
[Â 704.203439]Â ffffffffa00db000 ffffffff8100204a 0000000000026085 ffffffffa00a1400
[Â 704.203507]Â 0000000000026085 0000000000a9c010 0000000000026085 ffffffff810c5b79
[Â 704.203574] Call Trace:
[Â 704.203600]Â [<ffffffffa00db000>] ? module_initial+0x0/0x146 [memchar]
[Â 704.203653]Â [<ffffffff8100204a>] ? do_one_initcall+0x3a/0x180
[Â 704.203702]Â [<ffffffff810c5b79>] ? sys_init_module+0xb9/0x200
[Â 704.203749]Â [<ffffffff81040f52>] ? system_call_fastpath+0x16/0x1b
[Â 704.203796] Code: 8a 00 00 00 45 31 e4 48 63 0d 2b 63 fc ff 31 c0 48 89 d7 49 8d 6c 24 08 f3 aa 48 c7 c6 20 13 0a a0 48 8b 05 81 65 fc ff 48 89 ef <49> 89 04 24 8b 1d 7c 65 fc ff c1 e3 14 0b 1d ff 62 fc ff e8 8e
[Â 704.204218] RIPÂ [<ffffffffa00db0da>] module_initial+0xda/0x146 [memchar]
[Â 704.204275]Â RSP <ffff880031c85f08>
[Â 704.204303] CR2: 0000000000000000
[Â 704.213239] ---[ end trace 84796bda6e0d2134 ]---


========================================

/*
ÂÂ memchar - Memory map driver
ÂÂÂ Copyright (C) 2011Â Sameer Rahmani <lxsameer@xxxxxxx>

ÂÂÂ This program is free software: you can redistribute it and/or modify
ÂÂÂ it under the terms of the GNU General Public License as published by
ÂÂÂ the Free Software Foundation, either version 3 of the License, or
ÂÂÂ any later version.

ÂÂÂ This program is distributed in the hope that it will be useful,
ÂÂÂ but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ÂÂÂ GNU General Public License for more details.

ÂÂÂ You should have received a copy of the GNU General Public License
 along with this program. If not, see <http://www.gnu.org/licenses/>.

*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/stat.h>
#include <linux/moduleparam.h>
#include <linux/fs.h>
#include <linux/kdev_t.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <linux/fcntl.h>

#include <asm/uaccess.h>


MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sameer Rahmani <lxsameer@xxxxxxx>");
MODULE_DESCRIPTION("Memory map driver");


struct memmap {
 char *device;
 struct cdev cdev;
 int position;
 bool eof;
};


static int major = 0;
static int minor = 1;
static int map_size = 100;
char *device;

module_param(major, int, S_IRUGO);
module_param(minor, int, S_IRUGO);
module_param(map_size, int, S_IRUGO);

static void module_cleanup(void)
{
 dev_t dev;
 kfree(device);
 dev = MKDEV(major, minor);
 unregister_chrdev_region(dev, 1);
 printk(KERN_ALERT "memchar module un-loaded.\n");
}

/*
Â* open function.
Â*/
int mem_open(struct inode *inode, struct file *filp)
{
 struct memmap *memory;
 memory = container_of(inode->i_cdev, struct memmap, cdev);
 memory->device = device;
 filp->private_data = memory;

 /* write-only */
 if ( (filp->f_flags & O_ACCMODE) == O_WRONLY) {
ÂÂÂ memory->position = 0;
ÂÂÂ memory->eof = false;
 }
 return 0; /* success */

}

/* close function */
int mem_release(struct inode *inode, struct file *filp)
{
ÂÂÂ return 0;
}

/* read function */
ssize_t mem_read(struct file *filp, char __user *buf, size_t count,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ loff_t *f_pos)
{
 struct memmap *memory = filp->private_data; ;
 int counter;

 if (memory->eof)
ÂÂÂ {
ÂÂÂÂÂ return 0;
ÂÂÂ }
 counter = count;
 if (count + memory->position > map_size)
ÂÂÂ {
ÂÂÂÂÂ counter = map_size - memory->position;
ÂÂÂ }
 if(copy_to_user(buf, memory->device, counter))
ÂÂÂ {
ÂÂÂÂÂ counter = -EFAULT;
ÂÂÂÂÂ return counter;
ÂÂÂ }
 memory->position += counter;
 if (memory->position == map_size)
ÂÂÂ memory->eof = true;
 return counter;
}

/* write function */
ssize_t mem_write(struct file *filp, const char __user *buf, size_t count,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ loff_t *f_pos)
{
 struct memmap *memory = filp->private_data; ;
 int counter;
Â
 if (memory->eof)
ÂÂÂ return 0;

 counter = count;
 if (count + memory->position > map_size)
ÂÂÂ {
ÂÂÂÂÂ counter = map_size - memory->position;
ÂÂÂ }
 if(copy_from_user(memory->device, buf, counter))
ÂÂÂ {
ÂÂÂÂÂ counter = -EFAULT;
ÂÂÂÂÂ return counter;
ÂÂÂ }
 memory->position += counter;
 if (memory->position == map_size)
ÂÂÂ memory->eof = true;
 return counter;
}

struct file_operations mem_fops = {
ÂÂÂ .owner =ÂÂÂ THIS_MODULE,
ÂÂÂ .read =ÂÂÂÂ mem_read,
ÂÂÂ .write =ÂÂÂ mem_write,
ÂÂÂ .open =ÂÂÂÂ mem_open,
ÂÂÂ .release =Â mem_release,
};


/*
Â* Set up the char_dev structure for this device.
Â*/
static void mem_setup_cdev(struct memmap *dev)
{
ÂÂÂ int err, devno = MKDEV(major, minor);

ÂÂÂ cdev_init(&dev->cdev, &mem_fops);
ÂÂÂ dev->cdev.owner = THIS_MODULE;
ÂÂÂ dev->cdev.ops = &mem_fops;
ÂÂÂ err = cdev_add (&dev->cdev, devno, 1);
ÂÂÂ /* Fail gracefully if need be */
ÂÂÂ if (err)
ÂÂÂ ÂÂÂ printk(KERN_NOTICE "Error %d adding memchar", err);
}


static int __init module_initial(void)
{
 dev_t dev;
 int result;
 struct memmap *memory;

 if (major)
ÂÂÂ {
ÂÂÂÂÂ dev = MKDEV(major, minor);
ÂÂÂÂÂ result = register_chrdev_region(dev, 1, "memchar");
ÂÂÂ }
 else
ÂÂÂ {
ÂÂÂÂÂ result = alloc_chrdev_region(&dev, minor, 1,
ÂÂÂ ÂÂÂ ÂÂÂ ÂÂÂ ÂÂ "memchar");
ÂÂÂÂÂ major = MAJOR(dev);

ÂÂÂ }
 if (result < 0)
ÂÂÂ {
ÂÂÂÂÂ printk (KERN_ALERT "Cannot register major number.\n");
ÂÂÂÂÂ return result;
ÂÂÂ }

 device = kmalloc(sizeof(char) * map_size, GFP_KERNEL);
 if (! device)
ÂÂÂ {
ÂÂÂÂÂ printk (KERN_ALERT "Allocating device failed.\n");
ÂÂÂÂÂ result = -ENOMEM;
ÂÂÂÂÂ goto fail;
ÂÂÂ }


 memset(device, 0, sizeof(char) * map_size);

 memory->device = device;
 mem_setup_cdev(memory);

Â
 printk(KERN_ALERT "Major: %d", major);
 return 0;

Âfail:
 module_cleanup();
 return result;
}

module_init(module_initial);
module_exit(module_cleanup);


=================================


_______________________________________________
Kernelnewbies mailing list
Kernelnewbies@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux