Recently, I have been drum up the lnux character device driver. I have collected various code and comments about the linux device driver on the internet, either for 2.4 or errors, and I cannot run it successfully, I really hope that you can carefully check the correctness of the code when posting a blog. In particular, you must list the code runtime environment and dependency conditions. Otherwise, it will cause a great misunderstanding to readers.
The running environment of the following code is:
Operating System: debian 6
Kernel version: 2.6.32 (amd 64)
Gcc version: 4.4.5
The source code is as follows (the source code must be compiled and run without any bugs ):
# Include <linux/module. h> # include <linux/kernel. h> # include <linux/fs. h> # include <linux/types. h> # include <linux/cdev. h> # include <asm/uaccess. h> # include <linux/init. h> MODULE_LICENSE ("GPL"); static int yang_open (struct inode *, struct file *); static int yang_release (struct inode *, struct file *); static ssize_t yang_read (struct file *, char *, size_t, loff_t *); static ssize_t yang_write (struct file *, const char *, size_t, loff_t *); loff_t yang_llseek (struct file * filp, loff_t off, int whence); static int major; static int device_open = 0; static char * device_name = "myvar"; static dev_t devid; static struct mydev * my_cdev; struct mydev {char * data; struct cdev; unsigned long size ;}; static struct file_operations fops = {. owner = THIS_MODULE ,. read = yang_read ,. write = yang_write ,. open = yang_open ,. release = yang_release ,. llseek = yang_llseek}; int init_yang_module (void) {struct mydev * dev = (struct mydev *) kmalloc (sizeof (struct mydev), GFP_KERNEL); my_cdev = dev; // register as a global variable to enable the module to uninstall memset (dev, 0, sizeof (struct mydev); dev-> size = 10; int err; alloc_chrdev_region (& devid, 0, 1, "myvar"); major = MAJOR (devid); cdev_init (& dev-> cdev, & fops); err = cdev_add (& dev-> cdev, devid, 1); if (err) {printk (KERN_INFO "I was major number % d. \ n ", major); return-1;} printk (" major number is % d \ n ", MAJOR (devid); dev-> data = (char *) kmalloc (dev-> size * sizeof (char), GFP_KERNEL); memset (dev-> data, 0, dev-> size * sizeof (char); return 0 ;} void cleanup_yang_module (void) {cdev_del (& my_cdev-> cdev); unregister_chrdev_region (devid, 1); printk ("cleanup done \ n ");} loff_t yang_llseek (struct file * filp, loff_t off, int whence) {struct mydev * dev = filp-> private_data; loff_t newpos; switch (whence) {case SEEK_SET: newpos = off; case SEEK_CUR: newpos = filp-> f_pos + off; case SEEK_END: newpos = dev-> size + off; break; default: return-EINVAL;} if (newpos <0) return-EINVAL; filp-> f_pos = newpos; return newpos;} static int yang_open (struct inode * inode, struct file * file) {struct mydev * dev; dev = container_of (inode-> I _cdev, struct mydev, cdev); file-> private_data = dev; return 0;} static int yang_release (struct inode * inode, struct file * file) {return 0;} static ssize_t yang_read (struct file * filp, char * buffer, size_t length, loff_t * off) {struct mydev * dev = filp-> private_data; if (* off> = dev-> size) {return 0;} if (* off + length> dev-> size) length = dev-> size-* off; if (copy_to_user (buffer, dev-> data + * off, length * sizeof (char) {return-EFAULT;} * off + = length; return length ;} static ssize_t yang_write (struct file * filp, const char * buffer, size_t length, loff_t * off) {struct mydev * dev = filp-> private_data; if (length> dev-> size) {return-EFAULT;} if (copy_from_user (dev-> data, buffer, dev-> size * sizeof (char ))) {return-EFAULT;} * off + = length; return dev-> size;} module_init (init_yang_module); module_exit (cleanup_yang_module );
I will add comments later. If a brother has just learned the linux device driver, this source code is the best gift.