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:[&lt;ffffffffa00db0da&gt;]  [&lt;ffffffffa00db0da&gt;] 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]  [&lt;ffffffffa00db000&gt;] ? module_initial+0x0/0x146 [memchar]<br>[  704.203653]  [&lt;ffffffff8100204a&gt;] ? do_one_initcall+0x3a/0x180<br>[  704.203702]  [&lt;ffffffff810c5b79&gt;] ? sys_init_module+0xb9/0x200<br>
[  704.203749]  [&lt;ffffffff81040f52&gt;] ? 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 &lt;49&gt; 89 04 24 8b 1d 7c 65 fc ff c1 e3 14 0b 1d ff 62 fc ff e8 8e <br>
[  704.204218] RIP  [&lt;ffffffffa00db0da&gt;] module_initial+0xda/0x146 [memchar]<br>[  704.204275]  RSP &lt;ffff880031c85f08&gt;<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 &lt;<a href="mailto:lxsameer@gnu.org">lxsameer@gnu.org</a>&gt;<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 &lt;<a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>&gt;.<br><br>*/<br>#include &lt;linux/init.h&gt;<br>#include &lt;linux/module.h&gt;<br>#include &lt;linux/stat.h&gt;<br>
#include &lt;linux/moduleparam.h&gt;<br>#include &lt;linux/fs.h&gt;<br>#include &lt;linux/kdev_t.h&gt;<br>#include &lt;linux/errno.h&gt;<br>#include &lt;linux/slab.h&gt;<br>#include &lt;linux/kernel.h&gt;<br>#include &lt;linux/cdev.h&gt;<br>
#include &lt;linux/types.h&gt;<br>#include &lt;linux/fcntl.h&gt;<br><br>#include &lt;asm/uaccess.h&gt;<br><br><br>MODULE_LICENSE(&quot;GPL&quot;);<br>MODULE_AUTHOR(&quot;Sameer Rahmani &lt;<a href="mailto:lxsameer@gnu.org">lxsameer@gnu.org</a>&gt;&quot;);<br>
MODULE_DESCRIPTION(&quot;Memory map driver&quot;);<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 &quot;memchar module un-loaded.\n&quot;);<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-&gt;i_cdev, struct memmap, cdev);<br>  memory-&gt;device = device;<br>  filp-&gt;private_data = memory;<br><br>  /* write-only */<br>  if ( (filp-&gt;f_flags &amp; O_ACCMODE) == O_WRONLY) {<br>
    memory-&gt;position = 0;<br>    memory-&gt;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-&gt;private_data; ;<br>  int counter;<br><br>  if (memory-&gt;eof)<br>
    {<br>      return 0;<br>    }<br>  counter = count;<br>  if (count + memory-&gt;position &gt; map_size)<br>    {<br>      counter = map_size - memory-&gt;position;<br>    }<br>  if(copy_to_user(buf, memory-&gt;device, counter))<br>
    {<br>      counter = -EFAULT;<br>      return counter;<br>    }<br>  memory-&gt;position += counter;<br>  if (memory-&gt;position == map_size)<br>    memory-&gt;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-&gt;private_data; ;<br>  int counter;<br>  <br>  if (memory-&gt;eof)<br>    return 0;<br>
<br>  counter = count;<br>  if (count + memory-&gt;position &gt; map_size)<br>    {<br>      counter = map_size - memory-&gt;position;<br>    }<br>  if(copy_from_user(memory-&gt;device, buf, counter))<br>    {<br>      counter = -EFAULT;<br>
      return counter;<br>    }<br>  memory-&gt;position += counter;<br>  if (memory-&gt;position == map_size)<br>    memory-&gt;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(&amp;dev-&gt;cdev, &amp;mem_fops);<br>    dev-&gt;cdev.owner = THIS_MODULE;<br>    dev-&gt;cdev.ops = &amp;mem_fops;<br>    err = cdev_add (&amp;dev-&gt;cdev, devno, 1);<br>
    /* Fail gracefully if need be */<br>    if (err)<br>        printk(KERN_NOTICE &quot;Error %d adding memchar&quot;, 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, &quot;memchar&quot;);<br>    }<br>  else<br>    {<br>      result = alloc_chrdev_region(&amp;dev, minor, 1,<br>
                   &quot;memchar&quot;);<br>      major = MAJOR(dev);<br><br>    }<br>  if (result &lt; 0)<br>    {<br>      printk (KERN_ALERT &quot;Cannot register major number.\n&quot;);<br>      return result;<br>    }<br>
<br>  device = kmalloc(sizeof(char) * map_size, GFP_KERNEL);<br>  if (! device)<br>    {<br>      printk (KERN_ALERT &quot;Allocating device failed.\n&quot;);<br>      result = -ENOMEM;<br>      goto fail;<br>    }<br><br>
<br>  memset(device, 0, sizeof(char) * map_size);<br><br>  memory-&gt;device = device;<br>  mem_setup_cdev(memory);<br><br>  <br>  printk(KERN_ALERT &quot;Major: %d&quot;, 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>