hi<br>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,<br>i want to know problem, mistakes, hints and .... <br>
thank you so much <br><br>here is a tracback<br><br>=========================<br>[ 704.202596] Pid: 6912, comm: insmod Not tainted 2.6.37-2 #2 33238RG/33238RG<br>[ 704.202648] RIP: 0010:[<ffffffffa00db0da>] [<ffffffffa00db0da>] module_initial+0xda/0x146 [memchar]<br>
[ 704.202722] RSP: 0018:ffff880031c85f08 EFLAGS: 00010246<br>[ 704.202763] RAX: ffff8801317bf5c0 RBX: 0000000000000000 RCX: 0000000000000000<br>[ 704.202816] RDX: ffff8801317bf5c0 RSI: ffffffffa00a1320 RDI: 0000000000000008<br>
[ 704.202868] RBP: 0000000000000008 R08: ffff8800bb016350 R09: ffff8800ab0b49c0<br>[ 704.202921] R10: 0000000000000000 R11: 00000000000136c0 R12: 0000000000000000<br>[ 704.202974] R13: 0000000000026085 R14: 0000000000040000 R15: 0000000000000003<br>
[ 704.203027] FS: 00007fe95def9700(0000) GS:ffff8800bb000000(0000) knlGS:0000000000000000<br>[ 704.203087] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033<br>[ 704.203130] CR2: 0000000000000000 CR3: 00000000ab169000 CR4: 00000000000006f0<br>
[ 704.203182] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000<br>[ 704.203240] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400<br>[ 704.203293] Process insmod (pid: 6912, threadinfo ffff880031c84000, task ffff880131741a00)<br>
[ 704.203353] Stack:<br>[ 704.203371] 00000000ffffffff 0fc00001810b0439 0000000000000000 0000000000000000<br>[ 704.203439] ffffffffa00db000 ffffffff8100204a 0000000000026085 ffffffffa00a1400<br>[ 704.203507] 0000000000026085 0000000000a9c010 0000000000026085 ffffffff810c5b79<br>
[ 704.203574] Call Trace:<br>[ 704.203600] [<ffffffffa00db000>] ? module_initial+0x0/0x146 [memchar]<br>[ 704.203653] [<ffffffff8100204a>] ? do_one_initcall+0x3a/0x180<br>[ 704.203702] [<ffffffff810c5b79>] ? sys_init_module+0xb9/0x200<br>
[ 704.203749] [<ffffffff81040f52>] ? system_call_fastpath+0x16/0x1b<br>[ 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 <br>
[ 704.204218] RIP [<ffffffffa00db0da>] module_initial+0xda/0x146 [memchar]<br>[ 704.204275] RSP <ffff880031c85f08><br>[ 704.204303] CR2: 0000000000000000<br>[ 704.213239] ---[ end trace 84796bda6e0d2134 ]---<br>
<br><br>========================================<br><br>/*<br> memchar - Memory map driver<br> Copyright (C) 2011 Sameer Rahmani <<a href="mailto:lxsameer@gnu.org">lxsameer@gnu.org</a>><br><br> This program is free software: you can redistribute it and/or modify<br>
it under the terms of the GNU General Public License as published by<br> the Free Software Foundation, either version 3 of the License, or<br> any later version.<br><br> This program is distributed in the hope that it will be useful,<br>
but WITHOUT ANY WARRANTY; without even the implied warranty of<br> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br> GNU General Public License for more details.<br><br> You should have received a copy of the GNU General Public License<br>
along with this program. If not, see <<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>>.<br><br>*/<br>#include <linux/init.h><br>#include <linux/module.h><br>#include <linux/stat.h><br>
#include <linux/moduleparam.h><br>#include <linux/fs.h><br>#include <linux/kdev_t.h><br>#include <linux/errno.h><br>#include <linux/slab.h><br>#include <linux/kernel.h><br>#include <linux/cdev.h><br>
#include <linux/types.h><br>#include <linux/fcntl.h><br><br>#include <asm/uaccess.h><br><br><br>MODULE_LICENSE("GPL");<br>MODULE_AUTHOR("Sameer Rahmani <<a href="mailto:lxsameer@gnu.org">lxsameer@gnu.org</a>>");<br>
MODULE_DESCRIPTION("Memory map driver");<br><br><br>struct memmap {<br> char *device;<br> struct cdev cdev;<br> int position;<br> bool eof;<br>};<br><br><br>static int major = 0;<br>static int minor = 1;<br>
static int map_size = 100;<br>char *device;<br><br>module_param(major, int, S_IRUGO);<br>module_param(minor, int, S_IRUGO);<br>module_param(map_size, int, S_IRUGO);<br><br>static void module_cleanup(void)<br>{<br> dev_t dev;<br>
kfree(device);<br> dev = MKDEV(major, minor);<br> unregister_chrdev_region(dev, 1);<br> printk(KERN_ALERT "memchar module un-loaded.\n");<br>}<br><br>/*<br> * open function.<br> */<br>int mem_open(struct inode *inode, struct file *filp)<br>
{<br> struct memmap *memory;<br> memory = container_of(inode->i_cdev, struct memmap, cdev);<br> memory->device = device;<br> filp->private_data = memory;<br><br> /* write-only */<br> if ( (filp->f_flags & O_ACCMODE) == O_WRONLY) {<br>
memory->position = 0;<br> memory->eof = false;<br> }<br> return 0; /* success */<br><br>}<br><br>/* close function */<br>int mem_release(struct inode *inode, struct file *filp)<br>{<br> return 0;<br>
}<br><br>/* read function */<br>ssize_t mem_read(struct file *filp, char __user *buf, size_t count,<br> loff_t *f_pos)<br>{<br> struct memmap *memory = filp->private_data; ;<br> int counter;<br><br> if (memory->eof)<br>
{<br> return 0;<br> }<br> counter = count;<br> if (count + memory->position > map_size)<br> {<br> counter = map_size - memory->position;<br> }<br> if(copy_to_user(buf, memory->device, counter))<br>
{<br> counter = -EFAULT;<br> return counter;<br> }<br> memory->position += counter;<br> if (memory->position == map_size)<br> memory->eof = true;<br> return counter;<br>}<br><br>/* write function */<br>
ssize_t mem_write(struct file *filp, const char __user *buf, size_t count,<br> loff_t *f_pos)<br>{<br> struct memmap *memory = filp->private_data; ;<br> int counter;<br> <br> if (memory->eof)<br> return 0;<br>
<br> counter = count;<br> if (count + memory->position > map_size)<br> {<br> counter = map_size - memory->position;<br> }<br> if(copy_from_user(memory->device, buf, counter))<br> {<br> counter = -EFAULT;<br>
return counter;<br> }<br> memory->position += counter;<br> if (memory->position == map_size)<br> memory->eof = true;<br> return counter;<br>}<br><br>struct file_operations mem_fops = {<br> .owner = THIS_MODULE,<br>
.read = mem_read,<br> .write = mem_write,<br> .open = mem_open,<br> .release = mem_release,<br>};<br><br><br>/*<br> * Set up the char_dev structure for this device.<br> */<br>static void mem_setup_cdev(struct memmap *dev)<br>
{<br> int err, devno = MKDEV(major, minor);<br><br> cdev_init(&dev->cdev, &mem_fops);<br> dev->cdev.owner = THIS_MODULE;<br> dev->cdev.ops = &mem_fops;<br> err = cdev_add (&dev->cdev, devno, 1);<br>
/* Fail gracefully if need be */<br> if (err)<br> printk(KERN_NOTICE "Error %d adding memchar", err);<br>}<br><br><br>static int __init module_initial(void)<br>{<br> dev_t dev;<br> int result;<br>
struct memmap *memory;<br><br> if (major)<br> {<br> dev = MKDEV(major, minor);<br> result = register_chrdev_region(dev, 1, "memchar");<br> }<br> else<br> {<br> result = alloc_chrdev_region(&dev, minor, 1,<br>
"memchar");<br> major = MAJOR(dev);<br><br> }<br> if (result < 0)<br> {<br> printk (KERN_ALERT "Cannot register major number.\n");<br> return result;<br> }<br>
<br> device = kmalloc(sizeof(char) * map_size, GFP_KERNEL);<br> if (! device)<br> {<br> printk (KERN_ALERT "Allocating device failed.\n");<br> result = -ENOMEM;<br> goto fail;<br> }<br><br>
<br> memset(device, 0, sizeof(char) * map_size);<br><br> memory->device = device;<br> mem_setup_cdev(memory);<br><br> <br> printk(KERN_ALERT "Major: %d", major);<br> return 0;<br><br> fail:<br> module_cleanup();<br>
return result;<br>}<br><br>module_init(module_initial);<br>module_exit(module_cleanup);<br><br><br>=================================<br><br><br>