LDD-Basics
Device registeration
The kernel uses structures of type struct cdev to represent char devices internally. Include <linux/cdev.h> so that you can use the following structures functions.
1 struct cdev *cdev_alloc(void); //allocate a cdev 2 void cdev_init(struct cdev *cdev, struct file_operations *fops); //initialize it 3 int cdev_add(sturct cdev *cdev, dev_t num, unsigned int count); //add it to kernel 4 void cdev_del(struct cdev *dev); //remove it
Example of setuping a cdev(scull):
1 static void scull_setup_cdev(struct scull_dev *dev, int index) 2 { 3 int err, devno = MKDEV(scull_major, scull_minor + index); 4 cdev_init(&dev->cdev, &scull_fops); 5 dev->cdev.owner = THIS_MODULE; 6 dev->cdev.ops = &scull_fops; 7 err = cdev_add (&dev->cdev, devno, 1); 8 /* Fail gracefully if need be */ 9 if (err) 10 printk(KERN_NOTICE "Error %d adding scull%d", err, index); 11 }
The older way to register and unregister a cdev is with:
1 int register_chrdev(unsigned int major, const char *name, struct file_operations *fops); 2 int unregister_chrdev(unsigned int major, const char *name);
Major and minor numbers
The major nuber is the driver associated with the device, while the minor number is used by the kernel to determine which device is being referrd to. You can use the minor number as an index into a local array of devices.
Use dev_t type to hold device number with the help of MACROS defined in <linux/kdev_t.h>. You can obtain major or minor numbers with the following codes:
1 MAJOR(dev_t dev); 2 MINOR(dev_t dev);
Instead, use the following codes to make a dev_t:
MKDEV(int major, int minor);
int register_chrdev_region(dev_t first, unsigned int count, char *name);
However, if you have no idea about which number you want, use alloc_chrdev_region to gain a device number:
int alloc_chrdev_region(dev_t *dev, unsigned in firstminor, unsigned int count, char *name);
When device numbers are no longer used, remember to free them with:
void unregister_chrdev_region(dev_t first, unsigned int count);
Module parameters
Parameter values can be assigned at load time by insmod or modprobe(this can read parameter from configuration file /etc/modeprobe.conf).
While you type the paras in command line, the paras should also be declared with the module_para marco in codes:
1 static char *whom = "world"; 2 static int howmany = 1; 3 module_param(howmany, int, S_IRUGO); 4 module_param(whom, charp, S_IRUGO);
The types of para are as following:
bool/invbool(true->false, false->true)
charp(a char pointer)
integer(int, long, short, uint, ulong, ushort)
array(values should be supplied as a comma-separated list)
The array parameter is declared in a different way:
module_param_array(name,type,nump,perm);
TO define a type of para not defined above, see modulepara.h.
The final module_param fieldis a permission value, which is defiend in <linux/stat.h>. If perm is set to 0, there is no sysfs;otherwise, it appears under /sys/module with the givern set of permissions. Usually use S_IRUGO for those that only can be read. If you are read to detect the change of the paras and react, S_IRUGO| S_IWUSR would allow root to change the paras.
作者:glob
出处:http://www.cnblogs.com/adera/
欢迎访问我的个人博客:https://blog.globs.site/
本文版权归作者和博客园共有,转载请注明出处。