Kernel panics : trying to write / read on tiny tty driver -


i'm beginner linux programming , trying hands on device driver examples while practising. below code (a trimmed down version of tiny_tty.c) loads using insmod , i'm able see in /proc/tty/drivers , /proc/modules , device nodes getting created under /dev. when try write device file echo "abcd" > /dev/ttyms0 (i hope fine) or read cat /dev/ttyms0, kernel panics call trace on screen. i'm on kernel 3.5.0 under ubuntu. unfortunately i'm not able capture trace , when panics i'm left no option reboot using power button. believe issue timer here, trace shows line on top saying : "*kernel bug @ /build/buildd/linux-3.5.0/kernel/timer.c:901*", call trace , followed "*eip @ add_timer+0x18/0x20*" below full code. guidance appreciated in anticipation.

10may2013 : tried initializing timer in open function , time below call trace "kernel panic - not syncing : fatal exception in interrupt panic occurred, switching text console":

update_sd_lb_stats+0xcd/0x4b0 find_busiest_group+0x2e/0x420 enqueue_entity+0xcb/0x510 load_balance+0x7e/0x5e0 rebalance_domains+0xed/0x150 __do_softirq+0xdb/0x180 local_bh_enable_ip+0x90/0x90 <irq> copy_to_user0x41/0x60 sys_gettimeofday+0x2a/0x70 sysenter_do_call0x12/0x20      #include <linux/init.h>     #include <linux/kernel.h>     #include <linux/module.h>     #include <linux/fs.h>     #include <linux/kdev_t.h>     #include <linux/wait.h>     #include <linux/errno.h>     #include <linux/slab.h>     /* kmalloc() */     #include <linux/tty_driver.h>     #include <linux/tty.h>     #include <linux/tty_flip.h>     #include <linux/mutex.h>     #include <linux/serial.h>     #include <linux/sched.h>     #include <asm/uaccess.h>     #include <asm/termios.h>       module_license("gpl");      #define ms_tty_major 250    //test value     #define ms_tty_num_dev 2     #define delay_time      hz * 2      /* 2 seconds per character */     #define tiny_data_character 't'      static int major_num;     //static int minor_num=0;     //static int num_tty_dev=2;      /* below structure wrapper device specific fields */     struct ms_tty_serial {         struct tty_struct   *tty;       /* pointer tty device */         int         open_count; /* number of times port has been opened */         struct semaphore    sem;        /* locks structure */         struct timer_list   *timer;      };      static struct ms_tty_serial *ms_tty_table[ms_tty_num_dev];  /* null */      static void ms_tty_timer(unsigned long timer_data)     {         struct ms_tty_serial *ms_ptr = (struct ms_tty_serial *)timer_data;         struct tty_struct *tty;         char data[1] = {tiny_data_character};       int data_size = 1;          if (!ms_ptr)             return;          tty = ms_ptr->tty;         tty->low_latency=1;         /* send data tty layer users read.  doesn't          * push data through unless tty->low_latency set */         tty_buffer_request_room (tty, data_size);             tty_insert_flip_string(tty, data, data_size);             tty_flip_buffer_push(tty);          /* resubmit timer again */         ms_ptr->timer->expires = jiffies + delay_time;         add_timer(ms_ptr->timer);     }        //// define open function ////     static int tty_ms_open(struct tty_struct *tty_this, struct file *file_this) {      printk(kern_alert "tty_ms driver: opened ...\n");     struct ms_tty_serial *ms_ptr;     struct timer_list *timer;     int index;      /* initialize pointer in case fails */     tty_this->driver_data = null;      /* serial object associated tty pointer */     index = tty_this->index;     ms_ptr = ms_tty_table[index];     if (ms_ptr == null) {         /* first time accessing device, create */         ms_ptr = kmalloc(sizeof(*ms_ptr), gfp_kernel);         if (!ms_ptr)             return -enomem;  //      init_mutex(&ms_ptr->sem);       /* didn't work kernel version 3.5.0 */          #ifndef init_mutex      /* sema_init used kernel 2.6.37 , above */         sema_init(&ms_ptr->sem,1);         #else         init_mutex(&ms_ptr->sem);         #endif          ms_ptr->open_count = 0;         ms_ptr->timer = null;          ms_tty_table[index] = ms_ptr;     }      down(&ms_ptr->sem);      /* save our structure within tty structure */     tty_this->driver_data = ms_ptr;     ms_ptr->tty = tty_this;     ms_ptr->filp = file_this;       // tried     ++ms_ptr->open_count;     if (ms_ptr->open_count == 1) {         /* first time port opened */         /* hardware initialization needed here */          /* create timer , submit */         if (!ms_ptr->timer) {             timer = kmalloc(sizeof(*timer), gfp_kernel);             if (!timer) {                 up(&ms_ptr->sem);                 return -enomem;             }             ms_ptr->timer = timer;         }          init_timer (ms_ptr->timer);     // tried         ms_ptr->timer->data = (unsigned long )ms_ptr;         ms_ptr->timer->expires = jiffies + delay_time;         ms_ptr->timer->function = ms_tty_timer;         add_timer(ms_ptr->timer);     }      up(&ms_ptr->sem);     return 0; }      //// define close function ////      static void do_close(struct ms_tty_serial *ms_ptr)     {         down(&ms_ptr->sem);          if (!ms_ptr->open_count) {             /* port never opened */             goto exit;         }          --ms_ptr->open_count;         if (ms_ptr->open_count <= 0) {             /* port being closed last user. */             /* hardware specific stuff here */              /* shut down our timer */             del_timer(ms_ptr->timer);         }     exit:         up(&ms_ptr->sem);     }      static void tty_ms_close(struct tty_struct *tty_this, struct file *file_this)     {          printk(kern_alert "tty_ms driver: closing ...\n");         struct ms_tty_serial *ms_ptr = tty_this->driver_data;          if (ms_ptr)             do_close(ms_ptr);     }       //// define write function ////      static int tty_ms_write(struct tty_struct *tty_this, const unsigned char *tty_buff, int count)     {          printk(kern_alert "tty_ms driver: writing ...\n");     struct ms_tty_serial *ms_ptr = tty_this->driver_data;         int i;         int retval = -einval;          if (!ms_ptr)             return -enodev;          down(&ms_ptr->sem);          if (!ms_ptr->open_count)             /* port not opened */             {             up(&ms_ptr->sem);             return retval;             }         /* fake sending data out hardware port          * writing kernel debug log.          */         printk(kern_debug "%s - ", __function__);         (i = 0; < count; ++i)             printk("%02x ", tty_buff[i]);         printk("\n");         return 0;      }      // define operations tty driver in tty_operations struct //      static struct tty_operations tty_ms_ops = {     .open = tty_ms_open,     .close = tty_ms_close,     .write = tty_ms_write,     //.set_termios = tty_ms_set_termios,     };      ///////////////////////////////////////// module initialization starts ////////////////////////////////////      static struct tty_driver *tty_ms_driver;      static int tty_ms_init(void)     {     //  static int result;         static int retval,iter;      // allocate tty_driver struct driver //          tty_ms_driver = alloc_tty_driver(ms_tty_num_dev);         if (!tty_ms_driver)         return -enomem;         // error no memory , allocation failed         else         printk(kern_info "tty_driver structure allocated..!!");     //debug line      // initialize allocated tty_driver structure //         tty_ms_driver->magic=tty_driver_magic;         tty_ms_driver->owner = this_module;         tty_ms_driver->driver_name = "tty_ms";         tty_ms_driver->name = "ttyms";         tty_ms_driver->major = ms_tty_major,         tty_ms_driver->type = tty_driver_type_serial,         tty_ms_driver->subtype = serial_type_normal,         tty_ms_driver->flags = tty_driver_real_raw | tty_driver_dynamic_dev,         tty_ms_driver->init_termios = tty_std_termios;         tty_ms_driver->init_termios.c_cflag = b9600 | cs8 | cread | hupcl | clocal;         tty_set_operations(tty_ms_driver, &tty_ms_ops);         printk(kern_info "allocated tty_driver structure -initialized.");   //debug line     //// register driver tty core ////          retval = tty_register_driver(tty_ms_driver);         if (retval) {         printk(kern_err "failed register tty_ms driver\n tty registration returned %d", retval);         put_tty_driver(tty_ms_driver);         return retval;         }      //// register tty devices(nodes) tty core ////          (iter = 0; iter < ms_tty_num_dev ; ++iter)         tty_register_device(tty_ms_driver, iter, null);         return 0;       // initializations done      }           // init func ends      ///////////////////////////////////////// module initialization ends ////////////////////////////////////      ///////////////////////////////////////// module cleanup starts ////////////////////////////////////      static void tty_ms_terminate(void)     {         static int iter;         struct ms_tty_serial *tty_ser;         printk(kern_alert "tty_ms driver: unloading...\n");          for(iter=1;iter<=ms_tty_num_dev;iter++)          tty_unregister_device(tty_ms_driver,iter);   //unregister devices, tty layer          tty_unregister_driver(tty_ms_driver);       // unregister driver tty layer          /* shut down of timers , free memory */         (iter = 0; iter < ms_tty_num_dev; ++iter) {             tty_ser = ms_tty_table[iter];             if (tty_ser) {                 /* close port */                 while (tty_ser->open_count)                     do_close(tty_ser);                  /* shut down our timer , free memory */                 del_timer(tty_ser->timer);                 kfree(tty_ser->timer);                 kfree(tty_ser);                 ms_tty_table[iter] = null;             }         }              dev_t devno=mkdev(major_num,0);  // wrap major/minor numbers in dev_t structure , pass deassigning.          unregister_chrdev_region(devno,ms_tty_num_dev);       }      ///////////////////////////////////////// module cleanup ends ////////////////////////////////////      module_init(tty_ms_init);     module_exit(tty_ms_terminate); 


Comments

Popular posts from this blog

java - Jmockit String final length method mocking Issue -

asp.net - Razor Page Hosted on IIS 6 Fails Every Morning -

c++ - wxwidget compiling on windows command prompt -